1*5a8ea82fSAndrii Nakryiko /* SPDX-License-Identifier: GPL-2.0 */
2*5a8ea82fSAndrii Nakryiko /* Copyright (c) 2021 Facebook */
3*5a8ea82fSAndrii Nakryiko
4*5a8ea82fSAndrii Nakryiko #include <test_progs.h>
5*5a8ea82fSAndrii Nakryiko #include <bpf/btf.h>
6*5a8ea82fSAndrii Nakryiko
test_libbpf_probe_prog_types(void)7*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_prog_types(void)
8*5a8ea82fSAndrii Nakryiko {
9*5a8ea82fSAndrii Nakryiko struct btf *btf;
10*5a8ea82fSAndrii Nakryiko const struct btf_type *t;
11*5a8ea82fSAndrii Nakryiko const struct btf_enum *e;
12*5a8ea82fSAndrii Nakryiko int i, n, id;
13*5a8ea82fSAndrii Nakryiko
14*5a8ea82fSAndrii Nakryiko btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
15*5a8ea82fSAndrii Nakryiko if (!ASSERT_OK_PTR(btf, "btf_parse"))
16*5a8ea82fSAndrii Nakryiko return;
17*5a8ea82fSAndrii Nakryiko
18*5a8ea82fSAndrii Nakryiko /* find enum bpf_prog_type and enumerate each value */
19*5a8ea82fSAndrii Nakryiko id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM);
20*5a8ea82fSAndrii Nakryiko if (!ASSERT_GT(id, 0, "bpf_prog_type_id"))
21*5a8ea82fSAndrii Nakryiko goto cleanup;
22*5a8ea82fSAndrii Nakryiko t = btf__type_by_id(btf, id);
23*5a8ea82fSAndrii Nakryiko if (!ASSERT_OK_PTR(t, "bpf_prog_type_enum"))
24*5a8ea82fSAndrii Nakryiko goto cleanup;
25*5a8ea82fSAndrii Nakryiko
26*5a8ea82fSAndrii Nakryiko for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
27*5a8ea82fSAndrii Nakryiko const char *prog_type_name = btf__str_by_offset(btf, e->name_off);
28*5a8ea82fSAndrii Nakryiko enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val;
29*5a8ea82fSAndrii Nakryiko int res;
30*5a8ea82fSAndrii Nakryiko
31*5a8ea82fSAndrii Nakryiko if (prog_type == BPF_PROG_TYPE_UNSPEC)
32*5a8ea82fSAndrii Nakryiko continue;
33*5a8ea82fSAndrii Nakryiko
34*5a8ea82fSAndrii Nakryiko if (!test__start_subtest(prog_type_name))
35*5a8ea82fSAndrii Nakryiko continue;
36*5a8ea82fSAndrii Nakryiko
37*5a8ea82fSAndrii Nakryiko res = libbpf_probe_bpf_prog_type(prog_type, NULL);
38*5a8ea82fSAndrii Nakryiko ASSERT_EQ(res, 1, prog_type_name);
39*5a8ea82fSAndrii Nakryiko }
40*5a8ea82fSAndrii Nakryiko
41*5a8ea82fSAndrii Nakryiko cleanup:
42*5a8ea82fSAndrii Nakryiko btf__free(btf);
43*5a8ea82fSAndrii Nakryiko }
44*5a8ea82fSAndrii Nakryiko
test_libbpf_probe_map_types(void)45*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_map_types(void)
46*5a8ea82fSAndrii Nakryiko {
47*5a8ea82fSAndrii Nakryiko struct btf *btf;
48*5a8ea82fSAndrii Nakryiko const struct btf_type *t;
49*5a8ea82fSAndrii Nakryiko const struct btf_enum *e;
50*5a8ea82fSAndrii Nakryiko int i, n, id;
51*5a8ea82fSAndrii Nakryiko
52*5a8ea82fSAndrii Nakryiko btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
53*5a8ea82fSAndrii Nakryiko if (!ASSERT_OK_PTR(btf, "btf_parse"))
54*5a8ea82fSAndrii Nakryiko return;
55*5a8ea82fSAndrii Nakryiko
56*5a8ea82fSAndrii Nakryiko /* find enum bpf_map_type and enumerate each value */
57*5a8ea82fSAndrii Nakryiko id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM);
58*5a8ea82fSAndrii Nakryiko if (!ASSERT_GT(id, 0, "bpf_map_type_id"))
59*5a8ea82fSAndrii Nakryiko goto cleanup;
60*5a8ea82fSAndrii Nakryiko t = btf__type_by_id(btf, id);
61*5a8ea82fSAndrii Nakryiko if (!ASSERT_OK_PTR(t, "bpf_map_type_enum"))
62*5a8ea82fSAndrii Nakryiko goto cleanup;
63*5a8ea82fSAndrii Nakryiko
64*5a8ea82fSAndrii Nakryiko for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
65*5a8ea82fSAndrii Nakryiko const char *map_type_name = btf__str_by_offset(btf, e->name_off);
66*5a8ea82fSAndrii Nakryiko enum bpf_map_type map_type = (enum bpf_map_type)e->val;
67*5a8ea82fSAndrii Nakryiko int res;
68*5a8ea82fSAndrii Nakryiko
69*5a8ea82fSAndrii Nakryiko if (map_type == BPF_MAP_TYPE_UNSPEC)
70*5a8ea82fSAndrii Nakryiko continue;
71*5a8ea82fSAndrii Nakryiko
72*5a8ea82fSAndrii Nakryiko if (!test__start_subtest(map_type_name))
73*5a8ea82fSAndrii Nakryiko continue;
74*5a8ea82fSAndrii Nakryiko
75*5a8ea82fSAndrii Nakryiko res = libbpf_probe_bpf_map_type(map_type, NULL);
76*5a8ea82fSAndrii Nakryiko ASSERT_EQ(res, 1, map_type_name);
77*5a8ea82fSAndrii Nakryiko }
78*5a8ea82fSAndrii Nakryiko
79*5a8ea82fSAndrii Nakryiko cleanup:
80*5a8ea82fSAndrii Nakryiko btf__free(btf);
81*5a8ea82fSAndrii Nakryiko }
82*5a8ea82fSAndrii Nakryiko
test_libbpf_probe_helpers(void)83*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_helpers(void)
84*5a8ea82fSAndrii Nakryiko {
85*5a8ea82fSAndrii Nakryiko #define CASE(prog, helper, supp) { \
86*5a8ea82fSAndrii Nakryiko .prog_type_name = "BPF_PROG_TYPE_" # prog, \
87*5a8ea82fSAndrii Nakryiko .helper_name = "bpf_" # helper, \
88*5a8ea82fSAndrii Nakryiko .prog_type = BPF_PROG_TYPE_ ## prog, \
89*5a8ea82fSAndrii Nakryiko .helper_id = BPF_FUNC_ ## helper, \
90*5a8ea82fSAndrii Nakryiko .supported = supp, \
91*5a8ea82fSAndrii Nakryiko }
92*5a8ea82fSAndrii Nakryiko const struct case_def {
93*5a8ea82fSAndrii Nakryiko const char *prog_type_name;
94*5a8ea82fSAndrii Nakryiko const char *helper_name;
95*5a8ea82fSAndrii Nakryiko enum bpf_prog_type prog_type;
96*5a8ea82fSAndrii Nakryiko enum bpf_func_id helper_id;
97*5a8ea82fSAndrii Nakryiko bool supported;
98*5a8ea82fSAndrii Nakryiko } cases[] = {
99*5a8ea82fSAndrii Nakryiko CASE(KPROBE, unspec, false),
100*5a8ea82fSAndrii Nakryiko CASE(KPROBE, map_lookup_elem, true),
101*5a8ea82fSAndrii Nakryiko CASE(KPROBE, loop, true),
102*5a8ea82fSAndrii Nakryiko
103*5a8ea82fSAndrii Nakryiko CASE(KPROBE, ktime_get_coarse_ns, false),
104*5a8ea82fSAndrii Nakryiko CASE(SOCKET_FILTER, ktime_get_coarse_ns, true),
105*5a8ea82fSAndrii Nakryiko
106*5a8ea82fSAndrii Nakryiko CASE(KPROBE, sys_bpf, false),
107*5a8ea82fSAndrii Nakryiko CASE(SYSCALL, sys_bpf, true),
108*5a8ea82fSAndrii Nakryiko };
109*5a8ea82fSAndrii Nakryiko size_t case_cnt = ARRAY_SIZE(cases), i;
110*5a8ea82fSAndrii Nakryiko char buf[128];
111*5a8ea82fSAndrii Nakryiko
112*5a8ea82fSAndrii Nakryiko for (i = 0; i < case_cnt; i++) {
113*5a8ea82fSAndrii Nakryiko const struct case_def *d = &cases[i];
114*5a8ea82fSAndrii Nakryiko int res;
115*5a8ea82fSAndrii Nakryiko
116*5a8ea82fSAndrii Nakryiko snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name);
117*5a8ea82fSAndrii Nakryiko
118*5a8ea82fSAndrii Nakryiko if (!test__start_subtest(buf))
119*5a8ea82fSAndrii Nakryiko continue;
120*5a8ea82fSAndrii Nakryiko
121*5a8ea82fSAndrii Nakryiko res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL);
122*5a8ea82fSAndrii Nakryiko ASSERT_EQ(res, d->supported, buf);
123*5a8ea82fSAndrii Nakryiko }
124*5a8ea82fSAndrii Nakryiko }
125