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)? 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
