From 14bea1bb6505c0134dd5d2a18bcc436ce72cd149 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Mon, 29 Jul 2019 11:39:26 +0200 Subject: gso: fix l3 and l4 header offset in case of tagged interface previously, PG and virtio interfaces calculate wrong l3 and l4 header offset. This patch fixes this issue. Type: fix Ticket: VPP-1739 Change-Id: I5ba978e464babeb65e0711e1027320d46b3b9932 Signed-off-by: Mohsin Kazmi --- src/vnet/devices/virtio/node.c | 14 ++++++++++++++ src/vnet/pg/input.c | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 9cb6cca5672..3b218abdbb7 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -153,6 +153,20 @@ fill_gso_buffer_flags (vlib_buffer_t * b0, struct virtio_net_hdr_v1 *hdr) u16 ethertype = clib_net_to_host_u16 (eh->type); u16 l2hdr_sz = sizeof (ethernet_header_t); + if (ethernet_frame_is_tagged (ethertype)) + { + ethernet_vlan_header_t *vlan = (ethernet_vlan_header_t *) (eh + 1); + + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + if (ethertype == ETHERNET_TYPE_VLAN) + { + vlan++; + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + } + } + vnet_buffer (b0)->l2_hdr_offset = 0; vnet_buffer (b0)->l3_hdr_offset = l2hdr_sz; if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP4)) diff --git a/src/vnet/pg/input.c b/src/vnet/pg/input.c index 757a2916640..bb760b09b26 100644 --- a/src/vnet/pg/input.c +++ b/src/vnet/pg/input.c @@ -1541,6 +1541,20 @@ fill_gso_buffer_flags (vlib_main_t * vm, u32 * buffers, u32 n_buffers, u16 ethertype = clib_net_to_host_u16 (eh->type); u16 l2hdr_sz = sizeof (ethernet_header_t); + if (ethernet_frame_is_tagged (ethertype)) + { + ethernet_vlan_header_t *vlan = (ethernet_vlan_header_t *) (eh + 1); + + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + if (ethertype == ETHERNET_TYPE_VLAN) + { + vlan++; + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + } + } + vnet_buffer (b0)->l2_hdr_offset = 0; vnet_buffer (b0)->l3_hdr_offset = l2hdr_sz; if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP4)) -- cgit 1.2.3-korg