Commit | Line | Data |
---|---|---|
8c5d71d9 DM |
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 | ||
0b27b3d9 DM |
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 | ||
dea73da2 DM |
62 | /* |
63 | * Test case to check that all bpf_link_type variants are covered by | |
64 | * libbpf_bpf_link_type_str. | |
65 | */ | |
66 | static void test_libbpf_bpf_link_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_link_type and enumerate each value */ | |
78 | id = btf__find_by_name_kind(btf, "bpf_link_type", BTF_KIND_ENUM); | |
79 | if (!ASSERT_GT(id, 0, "bpf_link_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_link_type link_type = (enum bpf_link_type)e->val; | |
86 | const char *link_type_name; | |
87 | const char *link_type_str; | |
88 | char buf[256]; | |
89 | ||
7065eefb | 90 | if (link_type == __MAX_BPF_LINK_TYPE) |
dea73da2 DM |
91 | continue; |
92 | ||
93 | link_type_name = btf__str_by_offset(btf, e->name_off); | |
94 | link_type_str = libbpf_bpf_link_type_str(link_type); | |
95 | ASSERT_OK_PTR(link_type_str, link_type_name); | |
96 | ||
97 | snprintf(buf, sizeof(buf), "BPF_LINK_TYPE_%s", link_type_str); | |
98 | uppercase(buf); | |
99 | ||
100 | ASSERT_STREQ(buf, link_type_name, "exp_str_value"); | |
101 | } | |
102 | ||
103 | cleanup: | |
104 | btf__free(btf); | |
105 | } | |
106 | ||
c3a25740 DM |
107 | /* |
108 | * Test case to check that all bpf_map_type variants are covered by | |
109 | * libbpf_bpf_map_type_str. | |
110 | */ | |
111 | static void test_libbpf_bpf_map_type_str(void) | |
112 | { | |
113 | struct btf *btf; | |
114 | const struct btf_type *t; | |
115 | const struct btf_enum *e; | |
116 | int i, n, id; | |
117 | ||
118 | btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); | |
119 | if (!ASSERT_OK_PTR(btf, "btf_parse")) | |
120 | return; | |
121 | ||
122 | /* find enum bpf_map_type and enumerate each value */ | |
123 | id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM); | |
124 | if (!ASSERT_GT(id, 0, "bpf_map_type_id")) | |
125 | goto cleanup; | |
126 | t = btf__type_by_id(btf, id); | |
127 | e = btf_enum(t); | |
128 | n = btf_vlen(t); | |
129 | for (i = 0; i < n; e++, i++) { | |
130 | enum bpf_map_type map_type = (enum bpf_map_type)e->val; | |
131 | const char *map_type_name; | |
132 | const char *map_type_str; | |
133 | char buf[256]; | |
134 | ||
135 | map_type_name = btf__str_by_offset(btf, e->name_off); | |
136 | map_type_str = libbpf_bpf_map_type_str(map_type); | |
137 | ASSERT_OK_PTR(map_type_str, map_type_name); | |
138 | ||
139 | snprintf(buf, sizeof(buf), "BPF_MAP_TYPE_%s", map_type_str); | |
140 | uppercase(buf); | |
141 | ||
fd4ca6c1 YS |
142 | /* Special case for map_type_name BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED |
143 | * where it and BPF_MAP_TYPE_CGROUP_STORAGE have the same enum value | |
144 | * (map_type). For this enum value, libbpf_bpf_map_type_str() picks | |
9bc95a95 YS |
145 | * BPF_MAP_TYPE_CGROUP_STORAGE. The same for |
146 | * BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED and | |
147 | * BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE. | |
fd4ca6c1 YS |
148 | */ |
149 | if (strcmp(map_type_name, "BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED") == 0) | |
150 | continue; | |
9bc95a95 YS |
151 | if (strcmp(map_type_name, "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED") == 0) |
152 | continue; | |
fd4ca6c1 | 153 | |
c3a25740 DM |
154 | ASSERT_STREQ(buf, map_type_name, "exp_str_value"); |
155 | } | |
156 | ||
157 | cleanup: | |
158 | btf__free(btf); | |
159 | } | |
160 | ||
8c5d71d9 DM |
161 | /* |
162 | * Test case to check that all bpf_prog_type variants are covered by | |
163 | * libbpf_bpf_prog_type_str. | |
164 | */ | |
c3a25740 | 165 | static void test_libbpf_bpf_prog_type_str(void) |
8c5d71d9 DM |
166 | { |
167 | struct btf *btf; | |
168 | const struct btf_type *t; | |
169 | const struct btf_enum *e; | |
170 | int i, n, id; | |
171 | ||
172 | btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); | |
173 | if (!ASSERT_OK_PTR(btf, "btf_parse")) | |
174 | return; | |
175 | ||
176 | /* find enum bpf_prog_type and enumerate each value */ | |
177 | id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM); | |
178 | if (!ASSERT_GT(id, 0, "bpf_prog_type_id")) | |
179 | goto cleanup; | |
180 | t = btf__type_by_id(btf, id); | |
181 | e = btf_enum(t); | |
182 | n = btf_vlen(t); | |
183 | for (i = 0; i < n; e++, i++) { | |
184 | enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val; | |
185 | const char *prog_type_name; | |
186 | const char *prog_type_str; | |
187 | char buf[256]; | |
188 | ||
189 | prog_type_name = btf__str_by_offset(btf, e->name_off); | |
190 | prog_type_str = libbpf_bpf_prog_type_str(prog_type); | |
191 | ASSERT_OK_PTR(prog_type_str, prog_type_name); | |
192 | ||
193 | snprintf(buf, sizeof(buf), "BPF_PROG_TYPE_%s", prog_type_str); | |
194 | uppercase(buf); | |
195 | ||
196 | ASSERT_STREQ(buf, prog_type_name, "exp_str_value"); | |
197 | } | |
198 | ||
199 | cleanup: | |
200 | btf__free(btf); | |
201 | } | |
c3a25740 DM |
202 | |
203 | /* | |
204 | * Run all libbpf str conversion tests. | |
205 | */ | |
206 | void test_libbpf_str(void) | |
207 | { | |
0b27b3d9 DM |
208 | if (test__start_subtest("bpf_attach_type_str")) |
209 | test_libbpf_bpf_attach_type_str(); | |
210 | ||
dea73da2 DM |
211 | if (test__start_subtest("bpf_link_type_str")) |
212 | test_libbpf_bpf_link_type_str(); | |
213 | ||
c3a25740 DM |
214 | if (test__start_subtest("bpf_map_type_str")) |
215 | test_libbpf_bpf_map_type_str(); | |
216 | ||
217 | if (test__start_subtest("bpf_prog_type_str")) | |
218 | test_libbpf_bpf_prog_type_str(); | |
219 | } |