Le ven. 6 nov. 2026 à 09:16, <[email protected]> a écrit :
>
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue to consider:
> - [Medium] selftests: net: tun: off-by-ETH_HLEN lengths in
>   build_udptnl6_frame()
> --
>
> commit 5c13d992f1a4a8ebd5983197ac9a5424f5b3dd20
> Author: Eric Dumazet <[email protected]>
>
> selftests: net: tun: test more outer header mismatches of UDP tunnel GSO
>
> This commit adds tap selftests in tools/testing/selftests/net/tun.c to test
> outer header validation for UDP tunnel GSO frames, including IPv6 outer
> headers, mismatched address families, VLAN-tagged frames, and non-UDP outer
> L4 protocols.
>
> > diff --git a/tools/testing/selftests/net/tun.c 
> > b/tools/testing/selftests/net/tun.c
> > index cfeca53863ce2..a135d3aa10d18 100644
> > --- a/tools/testing/selftests/net/tun.c
> > +++ b/tools/testing/selftests/net/tun.c
> > @@ -869,6 +869,103 @@ TEST_F(tun_vnet_udptnl_proto, outer_proto_link_type)
> >       ASSERT_EQ(ret, len);
> >  }
> >
> > +/* Build a 4in6 Geneve GSO frame whose outer ethertype is @l3proto. */
> > +static int build_udptnl6_frame(uint8_t *buf, uint16_t l3proto,
> > +                            int payload_len)
> > +{
> > +     int hlen = UDP_TUNNEL_GENEVE_4IN6_HDRLEN;
> > +     uint8_t *outer_udph, *cur = buf;
> > +     int pktlen;
> > +
> > +     memset(buf, 0, TUN_VNET_TNL_SIZE + hlen + payload_len);
> > +
> > +     cur += build_virtio_net_hdr_v1_hash_tunnel(cur, true, hlen, 1400,
> > +                                                AF_INET6, AF_INET);
> > +     cur += build_eth(cur, l3proto, param_hwaddr_outer_dst,
> > +                      param_hwaddr_outer_src);
> > +
> > +     pktlen = UDP_TUNNEL_GENEVE_4IN6_HDRLEN - ETH_HLEN -
> > +              sizeof(struct ipv6hdr) + payload_len;
>
> [Severity: Medium]
> Are hlen and pktlen in build_udptnl6_frame() off by ETH_HLEN (14 bytes)?
>

Right, both miss the outer Ethernet header. The tests passed because
the kernel checks under test do not look at these lengths. The
selftests are not part of v4, I will fix this when sending them
separately.


> UDP_TUNNEL_GENEVE_4IN6_HDRLEN only counts one ETH_HLEN for the inner
> Ethernet header encapsulated inside Geneve:
>
> #define UDP_TUNNEL_GENEVE_4IN6_HDRLEN                               \
>         (ETH_HLEN + sizeof(struct iphdr) + sizeof(struct ipv6hdr) + \
>          GENEVE_HLEN + 2 * sizeof(struct udphdr))
>
> For comparison, the 4in4 counterpart in build_udptnl_frame() adds ETH_HLEN
> to hlen for the outer Ethernet header and does not subtract ETH_HLEN when
> computing pktlen:
>
>         int hlen = ETH_HLEN + vlan_len + UDP_TUNNEL_GENEVE_4IN4_HDRLEN;
>         ...
>         pktlen = UDP_TUNNEL_GENEVE_4IN4_HDRLEN - sizeof(struct iphdr) +
>                  payload_len;
>
> Because build_udptnl6_frame() emits both an outer Ethernet header and an
> inner Ethernet header, leaving ETH_HLEN out of hlen and subtracting ETH_HLEN
> from pktlen causes memset() to zero 14 bytes fewer than the returned frame
> length (cur - buf), sets the virtio header hdr_len to 98 instead of 112
> (which is smaller than csum_start at 104), and leaves the outer IPv6
> payload_len, outer UDP length, and outer UDP checksum coverage 14 bytes too
> short when outer_proto_ok_ipv6 and outer_proto_bad_family write the frame to
> the tap device.
>
> --
> Sashiko AI review · 
> https://sashiko.dev/#/patchset/[email protected]?part=7

Reply via email to