selftests/bpf: add raw_tp/tp_btf BPF cookie subtests
authorAndrii Nakryiko <andrii@kernel.org>
Tue, 19 Mar 2024 23:38:52 +0000 (16:38 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 20 Mar 2024 06:05:34 +0000 (23:05 -0700)
Add test validating BPF cookie can be passed during raw_tp/tp_btf
attachment and can be retried at runtime with bpf_get_attach_cookie()
helper.

Acked-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Message-ID: <20240319233852.1977493-6-andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/bpf_cookie.c
tools/testing/selftests/bpf/progs/test_bpf_cookie.c

index 1454cebc262b64c67d03267fbb6a37774d7f9a09..4407ea428e77c528664b3c5e590d5b8e1e93b36a 100644 (file)
@@ -573,6 +573,115 @@ cleanup:
                close(lsm_fd);
 }
 
+static void tp_btf_subtest(struct test_bpf_cookie *skel)
+{
+       __u64 cookie;
+       int prog_fd, link_fd = -1;
+       struct bpf_link *link = NULL;
+       LIBBPF_OPTS(bpf_link_create_opts, link_opts);
+       LIBBPF_OPTS(bpf_raw_tp_opts, raw_tp_opts);
+       LIBBPF_OPTS(bpf_trace_opts, trace_opts);
+
+       /* There are three different ways to attach tp_btf (BTF-aware raw
+        * tracepoint) programs. Let's test all of them.
+        */
+       prog_fd = bpf_program__fd(skel->progs.handle_tp_btf);
+
+       /* low-level BPF_RAW_TRACEPOINT_OPEN command wrapper */
+       skel->bss->tp_btf_res = 0;
+
+       raw_tp_opts.cookie = cookie = 0x11000000000000L;
+       link_fd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_tp_opts);
+       if (!ASSERT_GE(link_fd, 0, "bpf_raw_tracepoint_open_opts"))
+               goto cleanup;
+
+       usleep(1); /* trigger */
+       close(link_fd); /* detach */
+       link_fd = -1;
+
+       ASSERT_EQ(skel->bss->tp_btf_res, cookie, "raw_tp_open_res");
+
+       /* low-level generic bpf_link_create() API */
+       skel->bss->tp_btf_res = 0;
+
+       link_opts.tracing.cookie = cookie = 0x22000000000000L;
+       link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_RAW_TP, &link_opts);
+       if (!ASSERT_GE(link_fd, 0, "bpf_link_create"))
+               goto cleanup;
+
+       usleep(1); /* trigger */
+       close(link_fd); /* detach */
+       link_fd = -1;
+
+       ASSERT_EQ(skel->bss->tp_btf_res, cookie, "link_create_res");
+
+       /* high-level bpf_link-based bpf_program__attach_trace_opts() API */
+       skel->bss->tp_btf_res = 0;
+
+       trace_opts.cookie = cookie = 0x33000000000000L;
+       link = bpf_program__attach_trace_opts(skel->progs.handle_tp_btf, &trace_opts);
+       if (!ASSERT_OK_PTR(link, "attach_trace_opts"))
+               goto cleanup;
+
+       usleep(1); /* trigger */
+       bpf_link__destroy(link); /* detach */
+       link = NULL;
+
+       ASSERT_EQ(skel->bss->tp_btf_res, cookie, "attach_trace_opts_res");
+
+cleanup:
+       if (link_fd >= 0)
+               close(link_fd);
+       bpf_link__destroy(link);
+}
+
+static void raw_tp_subtest(struct test_bpf_cookie *skel)
+{
+       __u64 cookie;
+       int prog_fd, link_fd = -1;
+       struct bpf_link *link = NULL;
+       LIBBPF_OPTS(bpf_raw_tp_opts, raw_tp_opts);
+       LIBBPF_OPTS(bpf_raw_tracepoint_opts, opts);
+
+       /* There are two different ways to attach raw_tp programs */
+       prog_fd = bpf_program__fd(skel->progs.handle_raw_tp);
+
+       /* low-level BPF_RAW_TRACEPOINT_OPEN command wrapper */
+       skel->bss->raw_tp_res = 0;
+
+       raw_tp_opts.tp_name = "sys_enter";
+       raw_tp_opts.cookie = cookie = 0x55000000000000L;
+       link_fd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_tp_opts);
+       if (!ASSERT_GE(link_fd, 0, "bpf_raw_tracepoint_open_opts"))
+               goto cleanup;
+
+       usleep(1); /* trigger */
+       close(link_fd); /* detach */
+       link_fd = -1;
+
+       ASSERT_EQ(skel->bss->raw_tp_res, cookie, "raw_tp_open_res");
+
+       /* high-level bpf_link-based bpf_program__attach_raw_tracepoint_opts() API */
+       skel->bss->raw_tp_res = 0;
+
+       opts.cookie = cookie = 0x66000000000000L;
+       link = bpf_program__attach_raw_tracepoint_opts(skel->progs.handle_raw_tp,
+                                                      "sys_enter", &opts);
+       if (!ASSERT_OK_PTR(link, "attach_raw_tp_opts"))
+               goto cleanup;
+
+       usleep(1); /* trigger */
+       bpf_link__destroy(link); /* detach */
+       link = NULL;
+
+       ASSERT_EQ(skel->bss->raw_tp_res, cookie, "attach_raw_tp_opts_res");
+
+cleanup:
+       if (link_fd >= 0)
+               close(link_fd);
+       bpf_link__destroy(link);
+}
+
 void test_bpf_cookie(void)
 {
        struct test_bpf_cookie *skel;
@@ -601,6 +710,9 @@ void test_bpf_cookie(void)
                tracing_subtest(skel);
        if (test__start_subtest("lsm"))
                lsm_subtest(skel);
-
+       if (test__start_subtest("tp_btf"))
+               tp_btf_subtest(skel);
+       if (test__start_subtest("raw_tp"))
+               raw_tp_subtest(skel);
        test_bpf_cookie__destroy(skel);
 }
index 5a3a80f751c42e30ee78bbe220772bbd4e4d4e52..c83142b55f4724e0c30960ebffccf8aec028dfd6 100644 (file)
@@ -15,6 +15,8 @@ __u64 uprobe_res;
 __u64 uretprobe_res;
 __u64 tp_res;
 __u64 pe_res;
+__u64 raw_tp_res;
+__u64 tp_btf_res;
 __u64 fentry_res;
 __u64 fexit_res;
 __u64 fmod_ret_res;
@@ -87,6 +89,20 @@ int handle_pe(struct pt_regs *ctx)
        return 0;
 }
 
+SEC("raw_tp/sys_enter")
+int handle_raw_tp(void *ctx)
+{
+       update(ctx, &raw_tp_res);
+       return 0;
+}
+
+SEC("tp_btf/sys_enter")
+int handle_tp_btf(void *ctx)
+{
+       update(ctx, &tp_btf_res);
+       return 0;
+}
+
 SEC("fentry/bpf_fentry_test1")
 int BPF_PROG(fentry_test1, int a)
 {