]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Support non-linear flag in test loader
authorPaul Chaignon <paul.chaignon@gmail.com>
Thu, 9 Oct 2025 20:11:58 +0000 (22:11 +0200)
committerMartin KaFai Lau <martin.lau@kernel.org>
Fri, 10 Oct 2025 17:43:04 +0000 (10:43 -0700)
This patch adds support for a new tag __linear_size in the test loader,
to specify the size of the linear area in case of non-linear skbs. If
the tag is absent or null, a linear skb is crafted.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/7ad928ec7591daef4f1b84032aeb86c918b3e5a7.1760037899.git.paul.chaignon@gmail.com
tools/testing/selftests/bpf/progs/bpf_misc.h
tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c
tools/testing/selftests/bpf/test_loader.c

index a7a1a684eed116e304028b3ff0f32c3de4900dcf..c9bfbe1bafc127741e3a7ebc368a9f15e8106372 100644 (file)
  *                   Several __arch_* annotations could be specified at once.
  *                   When test case is not run on current arch it is marked as skipped.
  * __caps_unpriv     Specify the capabilities that should be set when running the test.
+ *
+ * __linear_size     Specify the size of the linear area of non-linear skbs, or
+ *                   0 for linear skbs.
  */
 #define __msg(msg)             __attribute__((btf_decl_tag("comment:test_expect_msg=" XSTR(__COUNTER__) "=" msg)))
 #define __not_msg(msg)         __attribute__((btf_decl_tag("comment:test_expect_not_msg=" XSTR(__COUNTER__) "=" msg)))
 #define __stderr_unpriv(msg)   __attribute__((btf_decl_tag("comment:test_expect_stderr_unpriv=" XSTR(__COUNTER__) "=" msg)))
 #define __stdout(msg)          __attribute__((btf_decl_tag("comment:test_expect_stdout=" XSTR(__COUNTER__) "=" msg)))
 #define __stdout_unpriv(msg)   __attribute__((btf_decl_tag("comment:test_expect_stdout_unpriv=" XSTR(__COUNTER__) "=" msg)))
+#define __linear_size(sz)      __attribute__((btf_decl_tag("comment:test_linear_size=" XSTR(sz))))
 
 /* Define common capabilities tested using __caps_unpriv */
 #define CAP_NET_ADMIN          12
index 28b602ac9cbe2ce8e65cf4d34dd5bc6fc662ff3d..a61897e01a50de96c75ab65eee00cd3c13a4dc0b 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Converted from tools/testing/selftests/bpf/verifier/direct_packet_access.c */
 
+#include <linux/if_ether.h>
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
index 74ecc281bb8c12435318a06919f4cf6192faa4cd..338c035c36884c02ac57cd17110122c10b4858e4 100644 (file)
@@ -43,6 +43,7 @@
 #define TEST_TAG_EXPECT_STDERR_PFX_UNPRIV "comment:test_expect_stderr_unpriv="
 #define TEST_TAG_EXPECT_STDOUT_PFX "comment:test_expect_stdout="
 #define TEST_TAG_EXPECT_STDOUT_PFX_UNPRIV "comment:test_expect_stdout_unpriv="
+#define TEST_TAG_LINEAR_SIZE "comment:test_linear_size="
 
 /* Warning: duplicated in bpf_misc.h */
 #define POINTER_VALUE  0xbadcafe
@@ -89,6 +90,7 @@ struct test_spec {
        int mode_mask;
        int arch_mask;
        int load_mask;
+       int linear_sz;
        bool auxiliary;
        bool valid;
 };
@@ -633,6 +635,21 @@ static int parse_test_spec(struct test_loader *tester,
                                              &spec->unpriv.stdout);
                        if (err)
                                goto cleanup;
+               } else if (str_has_pfx(s, TEST_TAG_LINEAR_SIZE)) {
+                       switch (bpf_program__type(prog)) {
+                       case BPF_PROG_TYPE_SCHED_ACT:
+                       case BPF_PROG_TYPE_SCHED_CLS:
+                       case BPF_PROG_TYPE_CGROUP_SKB:
+                               val = s + sizeof(TEST_TAG_LINEAR_SIZE) - 1;
+                               err = parse_int(val, &spec->linear_sz, "test linear size");
+                               if (err)
+                                       goto cleanup;
+                               break;
+                       default:
+                               PRINT_FAIL("__linear_size for unsupported program type");
+                               err = -EINVAL;
+                               goto cleanup;
+                       }
                }
        }
 
@@ -1007,10 +1024,11 @@ static bool is_unpriv_capable_map(struct bpf_map *map)
        }
 }
 
-static int do_prog_test_run(int fd_prog, int *retval, bool empty_opts)
+static int do_prog_test_run(int fd_prog, int *retval, bool empty_opts, int linear_sz)
 {
        __u8 tmp_out[TEST_DATA_LEN << 2] = {};
        __u8 tmp_in[TEST_DATA_LEN] = {};
+       struct __sk_buff ctx = {};
        int err, saved_errno;
        LIBBPF_OPTS(bpf_test_run_opts, topts,
                .data_in = tmp_in,
@@ -1020,6 +1038,12 @@ static int do_prog_test_run(int fd_prog, int *retval, bool empty_opts)
                .repeat = 1,
        );
 
+       if (linear_sz) {
+               ctx.data_end = linear_sz;
+               topts.ctx_in = &ctx;
+               topts.ctx_size_in = sizeof(ctx);
+       }
+
        if (empty_opts) {
                memset(&topts, 0, sizeof(struct bpf_test_run_opts));
                topts.sz = sizeof(struct bpf_test_run_opts);
@@ -1269,7 +1293,8 @@ void run_subtest(struct test_loader *tester,
                }
 
                err = do_prog_test_run(bpf_program__fd(tprog), &retval,
-                                      bpf_program__type(tprog) == BPF_PROG_TYPE_SYSCALL ? true : false);
+                                      bpf_program__type(tprog) == BPF_PROG_TYPE_SYSCALL ? true : false,
+                                      spec->linear_sz);
                if (!err && retval != subspec->retval && subspec->retval != POINTER_VALUE) {
                        PRINT_FAIL("Unexpected retval: %d != %d\n", retval, subspec->retval);
                        goto tobj_cleanup;