Thread (37 messages) 37 messages, 3 authors, 2025-06-17

Re: [PATCH RFC v3 5/8] net: implement virtio helpers to handle UDP GSO tunneling.

From: Paolo Abeni <pabeni@redhat.com>
Date: 2025-06-12 10:10:06

On 6/12/25 5:53 AM, Jason Wang wrote:
On Fri, Jun 6, 2025 at 7:46 PM Paolo Abeni [off-list ref] wrote:
quoted
+static inline int virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
+                                             struct virtio_net_hdr *hdr,
+                                             unsigned int tnl_offset,
+                                             bool little_endian,
+                                             int vlan_hlen)
+{
+       struct virtio_net_hdr_tunnel *tnl;
+       unsigned int inner_nh, outer_th;
+       int tnl_gso_type;
+       int ret;
+
+       tnl_gso_type = skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL |
+
SKB_GSO_UDP_TUNNEL_CSUM);
quoted
+       if (!tnl_gso_type)
+               return virtio_net_hdr_from_skb(skb, hdr,
little_endian, false,
quoted
+                                              vlan_hlen);
So tun_vnet_hdr_from_skb() has

        int vlan_hlen = skb_vlan_tag_present(skb) ? VLAN_HLEN : 0;
        int tnl_offset = tun_vnet_tnl_offset(flags);

        if (virtio_net_hdr_tnl_from_skb(skb, hdr, tnl_offset,
                                        tun_vnet_is_little_endian(flags),
                                        vlan_hlen)) {


It looks like the outer vlan_hlen is used for the inner here?
vlan_hlen always refers to the outer vlan tag (if present), as it moves
the (inner) transport csum offset accordingly.

I can a comment to clarify the parsing.

Note that in the above call there is a single set of headers (no
encapsulation) so the vlan_hlen should be unambigous.
quoted
+
+       /* Tunnel support not negotiated but skb ask for it. */
+       if (!tnl_offset)
+               return -EINVAL;
+
+       /* Let the basic parsing deal with plain GSO features. */
+       skb_shinfo(skb)->gso_type &= ~tnl_gso_type;
+       ret = virtio_net_hdr_from_skb(skb, hdr, true, false, vlan_hlen);
Here I'll add:

	Here vlan_hlen refers to the outer headers set, but still affect
	the inner transport header offset.
quoted
@@ -181,6 +208,22 @@ struct virtio_net_hdr_v1_hash {
        __le16 padding;
 };

+/* This header after hashing information */
+struct virtio_net_hdr_tunnel {
+       __le16 outer_th_offset;
+       __le16 inner_nh_offset;
+};
+
+struct virtio_net_hdr_v1_tunnel {
+       struct virtio_net_hdr_v1 hdr;
+       struct virtio_net_hdr_tunnel tnl;
+};
+
+struct virtio_net_hdr_v1_hash_tunnel {
+       struct virtio_net_hdr_v1_hash hdr;
+       struct virtio_net_hdr_tunnel tnl;
+};
Not a native speaker but I realize there's probably an issue:

        le32 hash_value;        (Only if VIRTIO_NET_F_HASH_REPORT
negotiated)
        le16 hash_report;       (Only if VIRTIO_NET_F_HASH_REPORT
negotiated)
        le16 padding_reserved;  (Only if VIRTIO_NET_F_HASH_REPORT
negotiated)
        le16 outer_th_offset    (Only if
VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO or VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO
negotiated)
        le16 inner_nh_offset;   (Only if
VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO or VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO
negotiated)
        le16 outer_nh_offset;   /* Only if VIRTIO_NET_F_OUT_NET_HEADER
negotiated */
        /* Only if VIRTIO_NET_F_OUT_NET_HEADER or VIRTIO_NET_F_IPSEC
negotiated */
        union {
                u8 padding_reserved_2[6];
                struct ipsec_resource_hdr {
                        le32 resource_id;
                        le16 resource_type;
                } ipsec_resource_hdr;
        };

I thought e.g outer_th_offset should have a fixed offset then
everything is simplified but it looks not the case here. If we decide
to do things like this, we will end up with a very huge uAPI
definition for different features combinations. This doesn't follow
the existing headers for example num_buffers exist no matter if
MRG_RXBUF is negotiated.>> At least, if we decide to go with the
dynamic offset, it seems less
valuable to define those headers with different combinations if both
device and driver process the vnet header piece wisely
I'm a little confused here. AFAICT the dynamic offset is
requested/mandated by the specifications: if the hash related fields are
not present, they are actually non existing and everything below moves
upward.  I think we spent together quite some time to agree on this.

If you want/intend the tunnel header to be at fixed offset inside the
virtio_hdr regardless of the negotiated features? That would yield to
slightly simpler but also slightly less efficient implementation.

Also I guess (fear mostly) some specification clarification would be needed.

/P
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help