From dbd5fb3db5d1edd33354cada459162407e30c023 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Tue, 2 Jun 2020 15:21:03 +0200 Subject: [PATCH] vxlan: fix the inner packet checksum calculation Type: fix Change-Id: I1da4ace9f3e548af4b5b3373d695e4214c5df2ff Signed-off-by: Mohsin Kazmi --- src/vnet/vxlan-gbp/encap.c | 52 +++++++++++++++++++++++++++++++++++++++++++-- src/vnet/vxlan/encap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/vnet/vxlan-gbp/encap.c b/src/vnet/vxlan-gbp/encap.c index a606b891189..4514fdae7a7 100644 --- a/src/vnet/vxlan-gbp/encap.c +++ b/src/vnet/vxlan-gbp/encap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -102,8 +103,17 @@ vxlan_gbp_encap_inline (vlib_main_t * vm, sizeof (ip4_vxlan_gbp_header_t) : sizeof (ip6_vxlan_gbp_header_t); u16 const l3_len = is_ip4 ? sizeof (ip4_header_t) : sizeof (ip6_header_t); u32 const csum_flags = is_ip4 ? VNET_BUFFER_F_OFFLOAD_IP_CKSUM | - VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM : - VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM; + VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | VNET_BUFFER_F_L4_HDR_OFFSET_VALID : + VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | VNET_BUFFER_F_L4_HDR_OFFSET_VALID; + u32 const inner_packet_csum_offload_flags = + VNET_BUFFER_F_OFFLOAD_IP_CKSUM | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; + u32 const inner_packet_removed_flags = + VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_IS_IP6 | + VNET_BUFFER_F_L2_HDR_OFFSET_VALID | VNET_BUFFER_F_L3_HDR_OFFSET_VALID | + VNET_BUFFER_F_L4_HDR_OFFSET_VALID; while (n_left_from > 0) { @@ -136,6 +146,30 @@ vxlan_gbp_encap_inline (vlib_main_t * vm, n_left_to_next -= 2; n_left_from -= 2; + u32 or_flags = b[0]->flags | b[1]->flags; + if (csum_offload && (or_flags & inner_packet_csum_offload_flags)) + { + /* Only calculate the non-GSO packet csum offload */ + if ((b[0]->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b[0], + b[0]->flags & + VNET_BUFFER_F_IS_IP4, + b[0]->flags & + VNET_BUFFER_F_IS_IP6); + b[0]->flags &= ~inner_packet_removed_flags; + } + if ((b[1]->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b[1], + b[1]->flags & + VNET_BUFFER_F_IS_IP4, + b[1]->flags & + VNET_BUFFER_F_IS_IP6); + b[1]->flags &= ~inner_packet_removed_flags; + } + } + u32 flow_hash0 = vnet_l2_compute_flow_hash (b[0]); u32 flow_hash1 = vnet_l2_compute_flow_hash (b[1]); @@ -353,6 +387,20 @@ vxlan_gbp_encap_inline (vlib_main_t * vm, n_left_from -= 1; n_left_to_next -= 1; + if (csum_offload && (b[0]->flags & inner_packet_csum_offload_flags)) + { + /* Only calculate the non-GSO packet csum offload */ + if ((b[0]->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b[0], + b[0]->flags & + VNET_BUFFER_F_IS_IP4, + b[0]->flags & + VNET_BUFFER_F_IS_IP6); + b[0]->flags &= ~inner_packet_removed_flags; + } + } + u32 flow_hash0 = vnet_l2_compute_flow_hash (b[0]); /* Get next node index and adj index from tunnel next_dpo */ diff --git a/src/vnet/vxlan/encap.c b/src/vnet/vxlan/encap.c index 2bc221adaff..787758a94f8 100644 --- a/src/vnet/vxlan/encap.c +++ b/src/vnet/vxlan/encap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -98,8 +99,18 @@ vxlan_encap_inline (vlib_main_t * vm, sizeof (ip4_vxlan_header_t) : sizeof (ip6_vxlan_header_t); u16 const l3_len = is_ip4 ? sizeof (ip4_header_t) : sizeof (ip6_header_t); u32 const csum_flags = is_ip4 ? VNET_BUFFER_F_OFFLOAD_IP_CKSUM | - VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM : - VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM; + VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | VNET_BUFFER_F_L4_HDR_OFFSET_VALID : + VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | VNET_BUFFER_F_L4_HDR_OFFSET_VALID; + u32 const inner_packet_csum_offload_flags = + VNET_BUFFER_F_OFFLOAD_IP_CKSUM | VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; + u32 const inner_packet_removed_flags = + VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_IS_IP6 | + VNET_BUFFER_F_L2_HDR_OFFSET_VALID | VNET_BUFFER_F_L3_HDR_OFFSET_VALID | + VNET_BUFFER_F_L4_HDR_OFFSET_VALID; + vlib_get_buffers (vm, from, bufs, n_left_from); while (n_left_from > 0) @@ -132,6 +143,30 @@ vxlan_encap_inline (vlib_main_t * vm, vlib_buffer_t *b1 = b[1]; b += 2; + u32 or_flags = b0->flags | b1->flags; + if (csum_offload && (or_flags & inner_packet_csum_offload_flags)) + { + /* Only calculate the non-GSO packet csum offload */ + if ((b0->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b0, + b0->flags & + VNET_BUFFER_F_IS_IP4, + b0->flags & + VNET_BUFFER_F_IS_IP6); + b0->flags &= ~inner_packet_removed_flags; + } + if ((b1->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b1, + b1->flags & + VNET_BUFFER_F_IS_IP4, + b1->flags & + VNET_BUFFER_F_IS_IP6); + b1->flags &= ~inner_packet_removed_flags; + } + } + u32 flow_hash0 = vnet_l2_compute_flow_hash (b0); u32 flow_hash1 = vnet_l2_compute_flow_hash (b1); @@ -342,6 +377,20 @@ vxlan_encap_inline (vlib_main_t * vm, vlib_buffer_t *b0 = b[0]; b += 1; + if (csum_offload && (b0->flags & inner_packet_csum_offload_flags)) + { + /* Only calculate the non-GSO packet csum offload */ + if ((b0->flags & VNET_BUFFER_F_GSO) == 0) + { + vnet_calc_checksums_inline (vm, b0, + b0->flags & + VNET_BUFFER_F_IS_IP4, + b0->flags & + VNET_BUFFER_F_IS_IP6); + b0->flags &= ~inner_packet_removed_flags; + } + } + u32 flow_hash0 = vnet_l2_compute_flow_hash (b0); /* Get next node index and adj index from tunnel next_dpo */ -- 2.16.6