[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CACGkMEtP5PoxS+=veyQimHB+Mui2+71tpJUYg5UcQCw9BR8yrg@mail.gmail.com>
Date: Thu, 12 Jun 2025 12:05:46 +0800
From: Jason Wang <jasowang@...hat.com>
To: Paolo Abeni <pabeni@...hat.com>
Cc: netdev@...r.kernel.org, Willem de Bruijn <willemdebruijn.kernel@...il.com>,
Andrew Lunn <andrew+netdev@...n.ch>, "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
"Michael S. Tsirkin" <mst@...hat.com>, Xuan Zhuo <xuanzhuo@...ux.alibaba.com>,
Eugenio Pérez <eperezma@...hat.com>,
Yuri Benditovich <yuri.benditovich@...nix.com>, Akihiko Odaki <akihiko.odaki@...nix.com>
Subject: Re: [PATCH RFC v3 6/8] virtio_net: enable gso over UDP tunnel support.
On Fri, Jun 6, 2025 at 7:46 PM Paolo Abeni <pabeni@...hat.com> wrote:
>
> If the related virtio feature is set, enable transmission and reception
> of gso over UDP tunnel packets.
>
> Most of the work is done by the previously introduced helper, just need
> to determine the UDP tunnel features inside the virtio_net_hdr and
> update accordingly the virtio net hdr size.
>
> Signed-off-by: Paolo Abeni <pabeni@...hat.com>
> ---
> v2 -> v3:
> - drop the VIRTIO_HAS_EXTENDED_FEATURES conditionals
>
> v1 -> v2:
> - test for UDP_TUNNEL_GSO* only on builds with extended features support
> - comment indentation cleanup
> - rebased on top of virtio helpers changes
> - dump more information in case of bad offloads
> ---
> drivers/net/virtio_net.c | 70 +++++++++++++++++++++++++++++++---------
> 1 file changed, 54 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 18ad50de4928..0b234f318e39 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -78,15 +78,19 @@ static const unsigned long guest_offloads[] = {
> VIRTIO_NET_F_GUEST_CSUM,
> VIRTIO_NET_F_GUEST_USO4,
> VIRTIO_NET_F_GUEST_USO6,
> - VIRTIO_NET_F_GUEST_HDRLEN
> + VIRTIO_NET_F_GUEST_HDRLEN,
> + VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_MAPPED,
> + VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM_MAPPED,
> };
>
> #define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
> - (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
> - (1ULL << VIRTIO_NET_F_GUEST_ECN) | \
> - (1ULL << VIRTIO_NET_F_GUEST_UFO) | \
> - (1ULL << VIRTIO_NET_F_GUEST_USO4) | \
> - (1ULL << VIRTIO_NET_F_GUEST_USO6))
> + (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
> + (1ULL << VIRTIO_NET_F_GUEST_ECN) | \
> + (1ULL << VIRTIO_NET_F_GUEST_UFO) | \
> + (1ULL << VIRTIO_NET_F_GUEST_USO4) | \
> + (1ULL << VIRTIO_NET_F_GUEST_USO6) | \
> + (1ULL << VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_MAPPED) | \
> + (1ULL << VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM_MAPPED))
>
> struct virtnet_stat_desc {
> char desc[ETH_GSTRING_LEN];
> @@ -436,9 +440,14 @@ struct virtnet_info {
> /* Packet virtio header size */
> u8 hdr_len;
>
> + /* UDP tunnel support */
> + u8 tnl_offset;
> +
> /* Work struct for delayed refilling if we run low on memory. */
> struct delayed_work refill;
>
> + bool rx_tnl_csum;
> +
> /* Is delayed refill enabled? */
> bool refill_enabled;
>
> @@ -2531,14 +2540,22 @@ static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *
> if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> virtio_skb_set_hash(&hdr->hash_v1_hdr, skb);
>
> - if (flags & VIRTIO_NET_HDR_F_DATA_VALID)
> - skb->ip_summed = CHECKSUM_UNNECESSARY;
> + /* restore the received value */
Nit: this comment seems to be redundant
> + hdr->hdr.flags = flags;
> + if (virtio_net_chk_data_valid(skb, &hdr->hdr, vi->rx_tnl_csum)) {
Nit: this function did more than just check DATA_VALID, we probably
need a better name.
> + net_warn_ratelimited("%s: bad csum: flags: %x, gso_type: %x rx_tnl_csum %d\n",
> + dev->name, hdr->hdr.flags,
> + hdr->hdr.gso_type, vi->rx_tnl_csum);
> + goto frame_err;
> + }
>
> - if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> - virtio_is_little_endian(vi->vdev))) {
> - net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> + if (virtio_net_hdr_tnl_to_skb(skb, &hdr->hdr, vi->tnl_offset,
I wonder why virtio_net_chk_data_valid() is not part of the
virtio_net_hdr_tnl_to_skb().
> + vi->rx_tnl_csum,
> + virtio_is_little_endian(vi->vdev))) {
> + net_warn_ratelimited("%s: bad gso: type: %x, size: %u, flags %x tunnel %d tnl csum %d\n",
> dev->name, hdr->hdr.gso_type,
> - hdr->hdr.gso_size);
> + hdr->hdr.gso_size, hdr->hdr.flags,
> + vi->tnl_offset, vi->rx_tnl_csum);
> goto frame_err;
> }
>
> @@ -3269,9 +3286,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb, bool orphan)
> else
> hdr = &skb_vnet_common_hdr(skb)->mrg_hdr;
>
> - if (virtio_net_hdr_from_skb(skb, &hdr->hdr,
> - virtio_is_little_endian(vi->vdev), false,
> - 0))
> + if (virtio_net_hdr_tnl_from_skb(skb, &hdr->hdr, vi->tnl_offset,
> + virtio_is_little_endian(vi->vdev), 0))
> return -EPROTO;
>
> if (vi->mergeable_rx_bufs)
> @@ -6775,10 +6791,20 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_USO))
> dev->hw_features |= NETIF_F_GSO_UDP_L4;
>
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO)) {
> + dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
> + dev->hw_enc_features = dev->hw_features;
> + }
> + if (dev->hw_features & NETIF_F_GSO_UDP_TUNNEL &&
> + virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO_CSUM)) {
> + dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
> + dev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
> + }
> +
> dev->features |= NETIF_F_GSO_ROBUST;
>
> if (gso)
> - dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
> + dev->features |= dev->hw_features;
> /* (!csum && gso) case will be fixed by register_netdev() */
> }
>
> @@ -6879,6 +6905,14 @@ static int virtnet_probe(struct virtio_device *vdev)
> else
> vi->hdr_len = sizeof(struct virtio_net_hdr);
>
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO) ||
> + virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO))
> + vi->tnl_offset = vi->hdr_len;
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM))
> + vi->rx_tnl_csum = true;
> + if (vi->tnl_offset)
> + vi->hdr_len += sizeof(struct virtio_net_hdr_tunnel);
> +
> if (virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT) ||
> virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
> vi->any_header_sg = true;
> @@ -7189,6 +7223,10 @@ static struct virtio_device_id id_table[] = {
>
> static unsigned int features[] = {
> VIRTNET_FEATURES,
> + VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO,
> + VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM,
> + VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO,
> + VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO_CSUM,
> };
>
> static unsigned int features_legacy[] = {
> --
> 2.49.0
>
Thanks
Powered by blists - more mailing lists