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 if (strcmp(prog_type_name, "__MAX_BPF_PROG_TYPE") == 0) 34 continue; 35 36 if (!test__start_subtest(prog_type_name)) 37 continue; 38 39 res = libbpf_probe_bpf_prog_type(prog_type, NULL); 40 ASSERT_EQ(res, 1, prog_type_name); 41 } 42 43 cleanup: 44 btf__free(btf); 45 } 46 47 void test_libbpf_probe_map_types(void) 48 { 49 struct btf *btf; 50 const struct btf_type *t; 51 const struct btf_enum *e; 52 int i, n, id; 53 54 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 55 if (!ASSERT_OK_PTR(btf, "btf_parse")) 56 return; 57 58 /* find enum bpf_map_type and enumerate each value */ 59 id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM); 60 if (!ASSERT_GT(id, 0, "bpf_map_type_id")) 61 goto cleanup; 62 t = btf__type_by_id(btf, id); 63 if (!ASSERT_OK_PTR(t, "bpf_map_type_enum")) 64 goto cleanup; 65 66 for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) { 67 const char *map_type_name = btf__str_by_offset(btf, e->name_off); 68 enum bpf_map_type map_type = (enum bpf_map_type)e->val; 69 int res; 70 71 if (map_type == BPF_MAP_TYPE_UNSPEC) 72 continue; 73 if (strcmp(map_type_name, "__MAX_BPF_MAP_TYPE") == 0) 74 continue; 75 76 if (!test__start_subtest(map_type_name)) 77 continue; 78 79 res = libbpf_probe_bpf_map_type(map_type, NULL); 80 ASSERT_EQ(res, 1, map_type_name); 81 } 82 83 cleanup: 84 btf__free(btf); 85 } 86 87 void test_libbpf_probe_helpers(void) 88 { 89 #define CASE(prog, helper, supp) { \ 90 .prog_type_name = "BPF_PROG_TYPE_" # prog, \ 91 .helper_name = "bpf_" # helper, \ 92 .prog_type = BPF_PROG_TYPE_ ## prog, \ 93 .helper_id = BPF_FUNC_ ## helper, \ 94 .supported = supp, \ 95 } 96 const struct case_def { 97 const char *prog_type_name; 98 const char *helper_name; 99 enum bpf_prog_type prog_type; 100 enum bpf_func_id helper_id; 101 bool supported; 102 } cases[] = { 103 CASE(KPROBE, unspec, false), 104 CASE(KPROBE, map_lookup_elem, true), 105 CASE(KPROBE, loop, true), 106 107 CASE(KPROBE, ktime_get_coarse_ns, false), 108 CASE(SOCKET_FILTER, ktime_get_coarse_ns, true), 109 110 CASE(KPROBE, sys_bpf, false), 111 CASE(SYSCALL, sys_bpf, true), 112 }; 113 size_t case_cnt = ARRAY_SIZE(cases), i; 114 char buf[128]; 115 116 for (i = 0; i < case_cnt; i++) { 117 const struct case_def *d = &cases[i]; 118 int res; 119 120 snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name); 121 122 if (!test__start_subtest(buf)) 123 continue; 124 125 res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL); 126 ASSERT_EQ(res, d->supported, buf); 127 } 128 } 129