1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 3 4 #include <ctype.h> 5 #include <test_progs.h> 6 #include <bpf/btf.h> 7 8 /* 9 * Utility function uppercasing an entire string. 10 */ 11 static void uppercase(char *s) 12 { 13 for (; *s != '\0'; s++) 14 *s = toupper(*s); 15 } 16 17 /* 18 * Test case to check that all bpf_attach_type variants are covered by 19 * libbpf_bpf_attach_type_str. 20 */ 21 static void test_libbpf_bpf_attach_type_str(void) 22 { 23 struct btf *btf; 24 const struct btf_type *t; 25 const struct btf_enum *e; 26 int i, n, id; 27 28 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 29 if (!ASSERT_OK_PTR(btf, "btf_parse")) 30 return; 31 32 /* find enum bpf_attach_type and enumerate each value */ 33 id = btf__find_by_name_kind(btf, "bpf_attach_type", BTF_KIND_ENUM); 34 if (!ASSERT_GT(id, 0, "bpf_attach_type_id")) 35 goto cleanup; 36 t = btf__type_by_id(btf, id); 37 e = btf_enum(t); 38 n = btf_vlen(t); 39 for (i = 0; i < n; e++, i++) { 40 enum bpf_attach_type attach_type = (enum bpf_attach_type)e->val; 41 const char *attach_type_name; 42 const char *attach_type_str; 43 char buf[256]; 44 45 if (attach_type == __MAX_BPF_ATTACH_TYPE) 46 continue; 47 48 attach_type_name = btf__str_by_offset(btf, e->name_off); 49 attach_type_str = libbpf_bpf_attach_type_str(attach_type); 50 ASSERT_OK_PTR(attach_type_str, attach_type_name); 51 52 snprintf(buf, sizeof(buf), "BPF_%s", attach_type_str); 53 uppercase(buf); 54 55 ASSERT_STREQ(buf, attach_type_name, "exp_str_value"); 56 } 57 58 cleanup: 59 btf__free(btf); 60 } 61 62 /* 63 * Test case to check that all bpf_map_type variants are covered by 64 * libbpf_bpf_map_type_str. 65 */ 66 static void test_libbpf_bpf_map_type_str(void) 67 { 68 struct btf *btf; 69 const struct btf_type *t; 70 const struct btf_enum *e; 71 int i, n, id; 72 73 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 74 if (!ASSERT_OK_PTR(btf, "btf_parse")) 75 return; 76 77 /* find enum bpf_map_type and enumerate each value */ 78 id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM); 79 if (!ASSERT_GT(id, 0, "bpf_map_type_id")) 80 goto cleanup; 81 t = btf__type_by_id(btf, id); 82 e = btf_enum(t); 83 n = btf_vlen(t); 84 for (i = 0; i < n; e++, i++) { 85 enum bpf_map_type map_type = (enum bpf_map_type)e->val; 86 const char *map_type_name; 87 const char *map_type_str; 88 char buf[256]; 89 90 map_type_name = btf__str_by_offset(btf, e->name_off); 91 map_type_str = libbpf_bpf_map_type_str(map_type); 92 ASSERT_OK_PTR(map_type_str, map_type_name); 93 94 snprintf(buf, sizeof(buf), "BPF_MAP_TYPE_%s", map_type_str); 95 uppercase(buf); 96 97 ASSERT_STREQ(buf, map_type_name, "exp_str_value"); 98 } 99 100 cleanup: 101 btf__free(btf); 102 } 103 104 /* 105 * Test case to check that all bpf_prog_type variants are covered by 106 * libbpf_bpf_prog_type_str. 107 */ 108 static void test_libbpf_bpf_prog_type_str(void) 109 { 110 struct btf *btf; 111 const struct btf_type *t; 112 const struct btf_enum *e; 113 int i, n, id; 114 115 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 116 if (!ASSERT_OK_PTR(btf, "btf_parse")) 117 return; 118 119 /* find enum bpf_prog_type and enumerate each value */ 120 id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM); 121 if (!ASSERT_GT(id, 0, "bpf_prog_type_id")) 122 goto cleanup; 123 t = btf__type_by_id(btf, id); 124 e = btf_enum(t); 125 n = btf_vlen(t); 126 for (i = 0; i < n; e++, i++) { 127 enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val; 128 const char *prog_type_name; 129 const char *prog_type_str; 130 char buf[256]; 131 132 prog_type_name = btf__str_by_offset(btf, e->name_off); 133 prog_type_str = libbpf_bpf_prog_type_str(prog_type); 134 ASSERT_OK_PTR(prog_type_str, prog_type_name); 135 136 snprintf(buf, sizeof(buf), "BPF_PROG_TYPE_%s", prog_type_str); 137 uppercase(buf); 138 139 ASSERT_STREQ(buf, prog_type_name, "exp_str_value"); 140 } 141 142 cleanup: 143 btf__free(btf); 144 } 145 146 /* 147 * Run all libbpf str conversion tests. 148 */ 149 void test_libbpf_str(void) 150 { 151 if (test__start_subtest("bpf_attach_type_str")) 152 test_libbpf_bpf_attach_type_str(); 153 154 if (test__start_subtest("bpf_map_type_str")) 155 test_libbpf_bpf_map_type_str(); 156 157 if (test__start_subtest("bpf_prog_type_str")) 158 test_libbpf_bpf_prog_type_str(); 159 } 160