vxlan: Fixed checksum caclculation offset

VXLAN uses csum_offload for IPv6 packets.

But without gso node we have csum calculated only for inner
packet.
This patch adds support for outer header csum calculation.
Checksum for inner packet should be calculated before
interface-output node (for example in vxlan node).

Type: fix

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Signed-off-by: Vladimir Isaev <visaev@netgate.com>
Change-Id: Ica68429ede4426293769207cd83c791ebe72fe56
This commit is contained in:
Vladimir Isaev
2020-05-21 16:34:17 +03:00
committed by John Lo
parent e362151804
commit 698eb87a8e
11 changed files with 86 additions and 79 deletions

View File

@ -82,59 +82,29 @@ vnet_calc_ip6_checksums (vlib_main_t * vm, vlib_buffer_t * b,
static_always_inline void
vnet_calc_checksums_inline (vlib_main_t * vm, vlib_buffer_t * b,
int is_ip4, int is_ip6, int with_gso)
int is_ip4, int is_ip6)
{
ip4_header_t *ip4;
ip6_header_t *ip6;
tcp_header_t *th;
udp_header_t *uh;
if (with_gso)
ASSERT (!(is_ip4 && is_ip6));
ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
if (is_ip4)
{
generic_header_offset_t gho = { 0 };
vnet_generic_header_offset_parser (b, &gho, 1 /* l2 */ , is_ip4,
is_ip6);
ASSERT (gho.gho_flags ^ (GHO_F_IP4 | GHO_F_IP6));
vnet_get_inner_header (b, &gho);
ip4 = (ip4_header_t *)
(vlib_buffer_get_current (b) + gho.l3_hdr_offset);
ip6 = (ip6_header_t *)
(vlib_buffer_get_current (b) + gho.l3_hdr_offset);
th = (tcp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
uh = (udp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
if (gho.gho_flags & GHO_F_IP4)
{
vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
}
else if (gho.gho_flags & GHO_F_IP6)
{
vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
}
vnet_get_outer_header (b, &gho);
vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
}
else
else if (is_ip6)
{
ASSERT (!(is_ip4 && is_ip6));
ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
if (is_ip4)
{
vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
}
if (is_ip6)
{
vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
}
vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
}
b->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
b->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
b->flags &= ~VNET_BUFFER_F_OFFLOAD_IP_CKSUM;