aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/buffer.h
diff options
context:
space:
mode:
authorAndrew Yourtchenko <ayourtch@gmail.com>2018-10-12 16:09:22 +0200
committerDamjan Marion <dmarion@me.com>2019-02-19 12:47:40 +0000
commit6a7cff7ec234af8529ff72a530076e191cc8d759 (patch)
treeea7a9bf447385172d0d3fda382aebf2d0203ecc8 /src/vnet/buffer.h
parentbe30fea370ed7cfe6a4a1b154a944411ec3eabd0 (diff)
tap gso: experimental support
This commit adds a "gso" parameter to existing "create tap..." CLI, and a "no-gso" parameter for the compatibility with the future, when/if defaults change. It makes use of the lowest bit of the "tap_flags" field in the API call in order to allow creation of GSO interfaces via API as well. It does the necessary syscalls to enable the GSO and checksum offload support on the kernel side and sets two flags on the interface: virtio-specific virtio_if_t.gso_enabled, and vnet_hw_interface_t.flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO. The first one, if enabled, triggers the marking of the GSO-encapsulated packets on ingress with VNET_BUFFER_F_GSO flag, and setting vnet_buffer2(b)->gso_size to the desired L4 payload size. VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO determines the egress packet processing in interface-output for such packets: When the flag is set, they are sent out almost as usual (just taking care to set the vnet header for virtio). When the flag is not enabled (the case for most interfaces), the egress path performs the re-segmentation such that the L4 payload of the transmitted packets equals gso_size. The operations in the datapath are enabled only when there is at least one GSO-compatible interface in the system - this is done by tracking the count in interface_main.gso_interface_count. This way the impact of conditional checks for the setups that do not use GSO is minimized. "show tap" CLI shows the state of the GSO flag on the interface, and the total count of GSO-enabled interfaces (which is used to enable the GSO-related processing in the packet path). This commit lacks IPv6 extension header traversal support of any kind - the L4 payload is assumed to follow the IPv6 header. Also it performs the offloads only for TCP (TSO - TCP segmentation offload). The UDP fragmentation offload (UFO) is not part of it. For debug purposes it also adds the debug CLI: "set tap gso {<interface> | sw_if_index <sw_idx>} <enable|disable>" Change-Id: Ifd562db89adcc2208094b3d1032cee8c307aaef9 Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Diffstat (limited to 'src/vnet/buffer.h')
-rw-r--r--src/vnet/buffer.h35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h
index 06696515ecd..ee04627fde3 100644
--- a/src/vnet/buffer.h
+++ b/src/vnet/buffer.h
@@ -66,14 +66,14 @@
_(17, FLOW_REPORT, "flow-report", 1) \
_(18, IS_DVR, "dvr", 1) \
_(19, QOS_DATA_VALID, "qos-data-valid", 0) \
- _(20, AVAIL1, "avail1", 1) \
- _(21, AVAIL2, "avail2", 1) \
- _(22, AVAIL3, "avail3", 1) \
- _(23, AVAIL4, "avail4", 1) \
- _(24, AVAIL5, "avail5", 1) \
- _(25, AVAIL6, "avail6", 1) \
- _(26, AVAIL7, "avail7", 1) \
- _(27, AVAIL8, "avail8", 1)
+ _(20, GSO, "gso", 0) \
+ _(21, AVAIL1, "avail1", 1) \
+ _(22, AVAIL2, "avail2", 1) \
+ _(23, AVAIL3, "avail3", 1) \
+ _(24, AVAIL4, "avail4", 1) \
+ _(25, AVAIL5, "avail5", 1) \
+ _(26, AVAIL6, "avail6", 1) \
+ _(27, AVAIL7, "avail7", 1)
/*
* Please allocate the FIRST available bit, redefine
@@ -396,6 +396,20 @@ typedef struct
};
} gbp;
+ /**
+ * The L4 payload size set on input on GSO enabled interfaces
+ * when we receive a GSO packet (a chain of buffers with the first one
+ * having GSO bit set), and needs to persist all the way to the interface-output,
+ * in case the egress interface is not GSO-enabled - then we need to perform
+ * the segmentation, and use this value to cut the payload appropriately.
+ */
+ u16 gso_size;
+ /* size of L4 prototol header */
+ u16 gso_l4_hdr_sz;
+
+ /* The union below has a u64 alignment, so this space is unused */
+ u32 __unused2[1];
+
union
{
struct
@@ -410,7 +424,7 @@ typedef struct
u64 pad[1];
u64 pg_replay_timestamp;
};
- u32 unused[10];
+ u32 unused[8];
};
} vnet_buffer_opaque2_t;
@@ -424,6 +438,9 @@ STATIC_ASSERT (sizeof (vnet_buffer_opaque2_t) <=
STRUCT_SIZE_OF (vlib_buffer_t, opaque2),
"VNET buffer opaque2 meta-data too large for vlib_buffer");
+#define gso_mtu_sz(b) (vnet_buffer2(b)->gso_size + vnet_buffer2(b)->gso_l4_hdr_sz + vnet_buffer(b)->l4_hdr_offset)
+
+
format_function_t format_vnet_buffer;
#endif /* included_vnet_buffer_h */