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