0001
0002
0003
0004 #include <test_progs.h>
0005 #include <bpf/btf.h>
0006
0007 void test_libbpf_probe_prog_types(void)
0008 {
0009 struct btf *btf;
0010 const struct btf_type *t;
0011 const struct btf_enum *e;
0012 int i, n, id;
0013
0014 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
0015 if (!ASSERT_OK_PTR(btf, "btf_parse"))
0016 return;
0017
0018
0019 id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM);
0020 if (!ASSERT_GT(id, 0, "bpf_prog_type_id"))
0021 goto cleanup;
0022 t = btf__type_by_id(btf, id);
0023 if (!ASSERT_OK_PTR(t, "bpf_prog_type_enum"))
0024 goto cleanup;
0025
0026 for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
0027 const char *prog_type_name = btf__str_by_offset(btf, e->name_off);
0028 enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val;
0029 int res;
0030
0031 if (prog_type == BPF_PROG_TYPE_UNSPEC)
0032 continue;
0033
0034 if (!test__start_subtest(prog_type_name))
0035 continue;
0036
0037 res = libbpf_probe_bpf_prog_type(prog_type, NULL);
0038 ASSERT_EQ(res, 1, prog_type_name);
0039 }
0040
0041 cleanup:
0042 btf__free(btf);
0043 }
0044
0045 void test_libbpf_probe_map_types(void)
0046 {
0047 struct btf *btf;
0048 const struct btf_type *t;
0049 const struct btf_enum *e;
0050 int i, n, id;
0051
0052 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
0053 if (!ASSERT_OK_PTR(btf, "btf_parse"))
0054 return;
0055
0056
0057 id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM);
0058 if (!ASSERT_GT(id, 0, "bpf_map_type_id"))
0059 goto cleanup;
0060 t = btf__type_by_id(btf, id);
0061 if (!ASSERT_OK_PTR(t, "bpf_map_type_enum"))
0062 goto cleanup;
0063
0064 for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
0065 const char *map_type_name = btf__str_by_offset(btf, e->name_off);
0066 enum bpf_map_type map_type = (enum bpf_map_type)e->val;
0067 int res;
0068
0069 if (map_type == BPF_MAP_TYPE_UNSPEC)
0070 continue;
0071
0072 if (!test__start_subtest(map_type_name))
0073 continue;
0074
0075 res = libbpf_probe_bpf_map_type(map_type, NULL);
0076 ASSERT_EQ(res, 1, map_type_name);
0077 }
0078
0079 cleanup:
0080 btf__free(btf);
0081 }
0082
0083 void test_libbpf_probe_helpers(void)
0084 {
0085 #define CASE(prog, helper, supp) { \
0086 .prog_type_name = "BPF_PROG_TYPE_" # prog, \
0087 .helper_name = "bpf_" # helper, \
0088 .prog_type = BPF_PROG_TYPE_ ## prog, \
0089 .helper_id = BPF_FUNC_ ## helper, \
0090 .supported = supp, \
0091 }
0092 const struct case_def {
0093 const char *prog_type_name;
0094 const char *helper_name;
0095 enum bpf_prog_type prog_type;
0096 enum bpf_func_id helper_id;
0097 bool supported;
0098 } cases[] = {
0099 CASE(KPROBE, unspec, false),
0100 CASE(KPROBE, map_lookup_elem, true),
0101 CASE(KPROBE, loop, true),
0102
0103 CASE(KPROBE, ktime_get_coarse_ns, false),
0104 CASE(SOCKET_FILTER, ktime_get_coarse_ns, true),
0105
0106 CASE(KPROBE, sys_bpf, false),
0107 CASE(SYSCALL, sys_bpf, true),
0108 };
0109 size_t case_cnt = ARRAY_SIZE(cases), i;
0110 char buf[128];
0111
0112 for (i = 0; i < case_cnt; i++) {
0113 const struct case_def *d = &cases[i];
0114 int res;
0115
0116 snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name);
0117
0118 if (!test__start_subtest(buf))
0119 continue;
0120
0121 res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL);
0122 ASSERT_EQ(res, d->supported, buf);
0123 }
0124 }