virtio: vhost gso is broken in some topology 92/24692/2
authorSteven Luong <sluong@cisco.com>
Thu, 30 Jan 2020 23:18:45 +0000 (15:18 -0800)
committerDave Barach <openvpp@barachs.net>
Mon, 3 Feb 2020 12:33:28 +0000 (12:33 +0000)
Recent modification added a call to vnet_gso_header_offset_parser in the
beginning of vhost_user_handle_tx_offload. The former routine may set tcp or
udp->checksum to 0. While it is appropriate to set it to 0 for the GSO packet,
it is broken and causes checksum error if the aformentiooned routine is called
by a non-GSO packet. The fix is to not call vhost_user_handle_tx_offload
if the buffer does not indicate checksum offload is needed.

Type: fix

Signed-off-by: Steven Luong <sluong@cisco.com>
Change-Id: I6e699d7a40b7887ff149cd8f77e8f0fa9374ef19

src/vnet/devices/virtio/vhost_user_output.c

index a47583d..c1b8fe1 100644 (file)
@@ -307,6 +307,7 @@ VNET_DEVICE_CLASS_TX_FN (vhost_user_device_class) (vlib_main_t * vm,
   u8 retry = 8;
   u16 copy_len;
   u16 tx_headers_len;
+  u32 or_flags;
 
   if (PREDICT_FALSE (!vui->admin_up))
     {
@@ -400,8 +401,13 @@ retry:
        hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE;
        hdr->num_buffers = 1;   //This is local, no need to check
 
-       /* Guest supports csum offload? */
-       if (vui->features & (1ULL << FEAT_VIRTIO_NET_F_GUEST_CSUM))
+       or_flags = (b0->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM) ||
+         (b0->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) ||
+         (b0->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM);
+
+       /* Guest supports csum offload and buffer requires checksum offload? */
+       if (or_flags
+           && (vui->features & (1ULL << FEAT_VIRTIO_NET_F_GUEST_CSUM)))
          vhost_user_handle_tx_offload (vui, b0, &hdr->hdr);
 
        // Prepare a copy order executed later for the header