From 6d18505efaa6d3d7dade969d42ee520738e713cb Mon Sep 17 00:00:00 2001 From: Jiayu Hu Date: Tue, 21 Nov 2017 14:56:52 +0800 Subject: [PATCH] vhost: support UDP Fragmentation Offload In virtio, UDP Fragmentation Offload (UFO) includes two parts: host UFO and guest UFO. Guest UFO means the frontend can receive large UDP packets, and host UFO means the backend can receive large UDP packets. This patch supports host UFO and guest UFO for vhost-user. Signed-off-by: Jiayu Hu Reviewed-by: Maxime Coquelin Tested-by: Lei Yao Acked-by: Neil Horman Acked-by: Yuanhan Liu --- lib/librte_mbuf/rte_mbuf.h | 7 +++++++ lib/librte_vhost/vhost.h | 2 ++ lib/librte_vhost/virtio_net.c | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index e4e3917f64..6cba632b97 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -208,6 +208,13 @@ extern "C" { /* add new TX flags here */ +/** + * UDP Fragmentation Offload flag. This flag is used for enabling UDP + * fragmentation in SW or in HW. When use UFO, mbuf->tso_segsz is used + * to store the MSS of UDP fragments. + */ +#define PKT_TX_UDP_SEG (1ULL << 42) + /** * Request security offload processing on the TX packet. */ diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 1943d069a1..8afb4265de 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -178,10 +178,12 @@ struct vhost_msg { (1ULL << VIRTIO_NET_F_GSO) | \ (1ULL << VIRTIO_NET_F_HOST_TSO4) | \ (1ULL << VIRTIO_NET_F_HOST_TSO6) | \ + (1ULL << VIRTIO_NET_F_HOST_UFO) | \ (1ULL << VIRTIO_NET_F_CSUM) | \ (1ULL << VIRTIO_NET_F_GUEST_CSUM) | \ (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ + (1ULL << VIRTIO_NET_F_GUEST_UFO) | \ (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | \ (1ULL << VIRTIO_NET_F_MTU) | \ (1ULL << VIRTIO_F_IOMMU_PLATFORM)) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 4f7217f898..cd304f61b7 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -159,6 +159,11 @@ virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr) net_hdr->gso_size = m_buf->tso_segsz; net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len + m_buf->l4_len; + } else if (m_buf->ol_flags & PKT_TX_UDP_SEG) { + net_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; + net_hdr->gso_size = m_buf->tso_segsz; + net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len + + m_buf->l4_len; } else { ASSIGN_UNLESS_EQUAL(net_hdr->gso_type, 0); ASSIGN_UNLESS_EQUAL(net_hdr->gso_size, 0); @@ -792,6 +797,11 @@ vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m) m->tso_segsz = hdr->gso_size; m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; break; + case VIRTIO_NET_HDR_GSO_UDP: + m->ol_flags |= PKT_TX_UDP_SEG; + m->tso_segsz = hdr->gso_size; + m->l4_len = sizeof(struct udp_hdr); + break; default: RTE_LOG(WARNING, VHOST_DATA, "unsupported gso type %u.\n", hdr->gso_type); -- 2.20.1