diff options
author | Steven Luong <sluong@cisco.com> | 2019-05-06 08:51:56 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2019-07-31 16:33:15 +0000 |
commit | 4208a4ce8d72d3fb6428527cde1fba7b397bd6f7 (patch) | |
tree | 3a04e358925ab7215c7d358fbf62b6c1eb33b25f /src/vnet/devices/virtio/vhost_user_output.c | |
parent | 83832e7ced8be8b7de394415feaba70c32e3c38d (diff) |
devices interface tests: vhosst GSO support
Add gso option in create vhost interface to support gso and checksum
offload.
Tested with the following startup options in qemu:
csum=on,gso=on,guest_csum=on,guest_tso4=on,guest_tso6=on,guest_ufo=on,
host_tso4=on,host_tso6=on,host_ufo=on
Type: feature
Change-Id: I9ba1ee33677a694c4a0dfe66e745b098995902b8
Signed-off-by: Steven Luong <sluong@cisco.com>
Diffstat (limited to 'src/vnet/devices/virtio/vhost_user_output.c')
-rw-r--r-- | src/vnet/devices/virtio/vhost_user_output.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index c0c54d1b13a..797c1c5ff92 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -17,6 +17,7 @@ *------------------------------------------------------------------ */ +#include <stddef.h> #include <fcntl.h> /* for open */ #include <sys/ioctl.h> #include <sys/socket.h> @@ -39,6 +40,7 @@ #include <vnet/devices/devices.h> #include <vnet/feature/feature.h> +#include <vnet/devices/virtio/virtio.h> #include <vnet/devices/virtio/vhost_user.h> #include <vnet/devices/virtio/vhost_user_inline.h> @@ -226,6 +228,51 @@ vhost_user_tx_copy (vhost_user_intf_t * vui, vhost_copy_t * cpy, return 0; } +static_always_inline void +vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, + virtio_net_hdr_t * hdr) +{ + /* checksum offload */ + if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) + { + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; + hdr->csum_offset = offsetof (udp_header_t, checksum); + } + else if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + { + hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; + hdr->csum_offset = offsetof (tcp_header_t, checksum); + } + + /* GSO offload */ + if (b->flags & VNET_BUFFER_F_GSO) + { + if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + { + if ((b->flags & VNET_BUFFER_F_IS_IP4) && + (vui->features & (1ULL << FEAT_VIRTIO_NET_F_GUEST_TSO4))) + { + hdr->gso_size = vnet_buffer2 (b)->gso_size; + hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + } + else if ((b->flags & VNET_BUFFER_F_IS_IP6) && + (vui->features & (1ULL << FEAT_VIRTIO_NET_F_GUEST_TSO6))) + { + hdr->gso_size = vnet_buffer2 (b)->gso_size; + hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + } + } + else if ((vui->features & (1ULL << FEAT_VIRTIO_NET_F_GUEST_UFO)) && + (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)) + { + hdr->gso_size = vnet_buffer2 (b)->gso_size; + hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; + } + } +} + VNET_DEVICE_CLASS_TX_FN (vhost_user_device_class) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) @@ -335,9 +382,13 @@ retry: virtio_net_hdr_mrg_rxbuf_t *hdr = &cpu->tx_headers[tx_headers_len]; tx_headers_len++; hdr->hdr.flags = 0; - hdr->hdr.gso_type = 0; + 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)) + vhost_user_handle_tx_offload (vui, b0, &hdr->hdr); + // Prepare a copy order executed later for the header vhost_copy_t *cpy = &cpu->copy[copy_len]; copy_len++; |