diff options
author | Mohsin Kazmi <sykazmi@cisco.com> | 2021-02-23 15:55:04 +0100 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2021-10-01 10:04:24 +0000 |
commit | f5462369f3ad22c9d19f54832faa2b6e61449f66 (patch) | |
tree | af4c5d3a0218f482b92501b81bdae36cfcfc4d20 /src/vnet/devices/virtio/vhost_user_output.c | |
parent | de3caf37c64431c199fe649256b268010ce6a4f3 (diff) |
devices: add support for pseudo header checksum
Type: improvement
Linux uses pseudo header checksum when checksum of l4 is offloaded.
This patch adds similar support in virtual interfaces.
Change-Id: I6a94d1104e59356f95057e7c122e3be9cd8659a3
Signed-off-by: Aloys Augustin <aloaugus@cisco.com>
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/vnet/devices/virtio/vhost_user_output.c')
-rw-r--r-- | src/vnet/devices/virtio/vhost_user_output.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index 4efafa85333..15e39a11692 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -37,6 +37,7 @@ #include <vnet/ethernet/ethernet.h> #include <vnet/devices/devices.h> #include <vnet/feature/feature.h> +#include <vnet/ip/ip_psh_cksum.h> #include <vnet/devices/virtio/vhost_user.h> #include <vnet/devices/virtio/vhost_user_inline.h> @@ -208,27 +209,40 @@ vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4; int is_ip6 = b->flags & VNET_BUFFER_F_IS_IP6; vnet_buffer_oflags_t oflags = vnet_buffer (b)->oflags; + u16 psh_cksum = 0; + ip4_header_t *ip4 = 0; + ip6_header_t *ip6 = 0; ASSERT (!(is_ip4 && is_ip6)); vnet_generic_header_offset_parser (b, &gho, 1 /* l2 */ , is_ip4, is_ip6); if (oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM) { - ip4_header_t *ip4; - ip4 = (ip4_header_t *) (vlib_buffer_get_current (b) + gho.l3_hdr_offset); ip4->checksum = ip4_header_checksum (ip4); + psh_cksum = ip4_pseudo_header_cksum (ip4); + } + else + { + ip6 = (ip6_header_t *) (vlib_buffer_get_current (b) + gho.l3_hdr_offset); + psh_cksum = ip6_pseudo_header_cksum (ip6); } /* checksum offload */ if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM) { + udp_header_t *udp = + (udp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset); + udp->checksum = psh_cksum; hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->csum_start = gho.l4_hdr_offset; hdr->csum_offset = offsetof (udp_header_t, checksum); } else if (oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM) { + tcp_header_t *tcp = + (tcp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset); + tcp->checksum = psh_cksum; hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->csum_start = gho.l4_hdr_offset; hdr->csum_offset = offsetof (tcp_header_t, checksum); |