From e4f009f5297766be9fe2a294ee76ba92d2e90435 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Wed, 4 Jun 2025 11:08:47 +0000 Subject: [PATCH] virtio: conditionally set checksum offload based on TCP/UDP offload flags Type: fix Previously, the Virtio device node unconditionally set the checksum offload flag and the checksum start offset, regardless of whether TCP/UDP checksum offload flags were set. This patch updates the logic to apply these settings only when the TCP/UDP offload flags are explicitly set. Signed-off-by: Mohsin Kazmi Change-Id: I9af37d03b388ff7d1e22ec125fae97fad50e64d2 --- src/vnet/devices/virtio/device.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index 112f77e7065..0dd93976c22 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -313,9 +313,6 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, if (b->flags & VNET_BUFFER_F_IS_IP4) { ip4_header_t *ip4; - hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - hdr->csum_start = l4_hdr_offset; // 0x22; - /* * virtio devices do not support IP4 checksum offload. So driver takes * care of it while doing tx. @@ -333,6 +330,9 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, tcp_header_t *tcp = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); tcp->checksum = ip4_pseudo_header_cksum (ip4); + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->hdr_len = l4_hdr_offset + tcp_header_bytes (tcp); + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum); } else if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM) @@ -340,14 +340,15 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, udp_header_t *udp = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); udp->checksum = ip4_pseudo_header_cksum (ip4); + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->hdr_len = l4_hdr_offset + sizeof (udp_header_t); + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum); } } else if (b->flags & VNET_BUFFER_F_IS_IP6) { ip6_header_t *ip6; - hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - hdr->csum_start = l4_hdr_offset; // 0x36; ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset); /* @@ -359,6 +360,9 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, tcp_header_t *tcp = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); tcp->checksum = ip6_pseudo_header_cksum (ip6); + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->hdr_len = l4_hdr_offset + tcp_header_bytes (tcp); + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum); } else if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM) @@ -366,6 +370,9 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, udp_header_t *udp = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); udp->checksum = ip6_pseudo_header_cksum (ip6); + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->hdr_len = l4_hdr_offset + sizeof (udp_header_t); + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum); } } @@ -381,11 +388,11 @@ set_gso_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, if (b->flags & VNET_BUFFER_F_IS_IP4) { ip4_header_t *ip4; + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; - hdr->gso_size = vnet_buffer2 (b)->gso_size; hdr->hdr_len = l4_hdr_offset + vnet_buffer2 (b)->gso_l4_hdr_sz; - hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - hdr->csum_start = l4_hdr_offset; // 0x22; + hdr->gso_size = vnet_buffer2 (b)->gso_size; + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum); ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset); /* @@ -397,11 +404,11 @@ set_gso_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr, } else if (b->flags & VNET_BUFFER_F_IS_IP6) { + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - hdr->gso_size = vnet_buffer2 (b)->gso_size; hdr->hdr_len = l4_hdr_offset + vnet_buffer2 (b)->gso_l4_hdr_sz; - hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; - hdr->csum_start = l4_hdr_offset; // 0x36; + hdr->gso_size = vnet_buffer2 (b)->gso_size; + hdr->csum_start = l4_hdr_offset; hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum); } } -- 2.16.6