]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
selftests/net: Add coverage for UDP GSO with IPv6 extension headers
authorJakub Sitnicki <jakub@cloudflare.com>
Thu, 8 Aug 2024 09:56:23 +0000 (11:56 +0200)
committerJakub Kicinski <kuba@kernel.org>
Sat, 10 Aug 2024 04:58:08 +0000 (21:58 -0700)
After enabling UDP GSO for devices not offering checksum offload, we have
hit a regression where a bad offload warning can be triggered when sending
a datagram with IPv6 extension headers.

Extend the UDP GSO IPv6 tests to cover this scenario.

Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://patch.msgid.link/20240808-udp-gso-egress-from-tunnel-v4-3-f5c5b4149ab9@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/testing/selftests/net/udpgso.c

index 3e74cfa1a2bfec6bc8bea1a704e7bc074ad794a5..3f2fca02fec53f52beaddb43ea4255bca24b79b8 100644 (file)
@@ -67,6 +67,7 @@ struct testcase {
        int gso_len;            /* mss after applying gso */
        int r_num_mss;          /* recv(): number of calls of full mss */
        int r_len_last;         /* recv(): size of last non-mss dgram, if any */
+       bool v6_ext_hdr;        /* send() dgrams with IPv6 extension headers */
 };
 
 const struct in6_addr addr6 = {
@@ -77,6 +78,8 @@ const struct in_addr addr4 = {
        __constant_htonl(0x0a000001), /* 10.0.0.1 */
 };
 
+static const char ipv6_hopopts_pad1[8] = { 0 };
+
 struct testcase testcases_v4[] = {
        {
                /* no GSO: send a single byte */
@@ -255,6 +258,13 @@ struct testcase testcases_v6[] = {
                .gso_len = 1,
                .r_num_mss = 2,
        },
+       {
+               /* send 2 1B segments with extension headers */
+               .tlen = 2,
+               .gso_len = 1,
+               .r_num_mss = 2,
+               .v6_ext_hdr = true,
+       },
        {
                /* send 2B + 2B + 1B segments */
                .tlen = 5,
@@ -396,11 +406,18 @@ static void run_one(struct testcase *test, int fdt, int fdr,
        int i, ret, val, mss;
        bool sent;
 
-       fprintf(stderr, "ipv%d tx:%d gso:%d %s\n",
+       fprintf(stderr, "ipv%d tx:%d gso:%d %s%s\n",
                        addr->sa_family == AF_INET ? 4 : 6,
                        test->tlen, test->gso_len,
+                       test->v6_ext_hdr ? "ext-hdr " : "",
                        test->tfail ? "(fail)" : "");
 
+       if (test->v6_ext_hdr) {
+               if (setsockopt(fdt, IPPROTO_IPV6, IPV6_HOPOPTS,
+                              ipv6_hopopts_pad1, sizeof(ipv6_hopopts_pad1)))
+                       error(1, errno, "setsockopt ipv6 hopopts");
+       }
+
        val = test->gso_len;
        if (cfg_do_setsockopt) {
                if (setsockopt(fdt, SOL_UDP, UDP_SEGMENT, &val, sizeof(val)))
@@ -412,6 +429,12 @@ static void run_one(struct testcase *test, int fdt, int fdr,
                error(1, 0, "send succeeded while expecting failure");
        if (!sent && !test->tfail)
                error(1, 0, "send failed while expecting success");
+
+       if (test->v6_ext_hdr) {
+               if (setsockopt(fdt, IPPROTO_IPV6, IPV6_HOPOPTS, NULL, 0))
+                       error(1, errno, "setsockopt ipv6 hopopts clear");
+       }
+
        if (!sent)
                return;