xref: /openbmc/linux/tools/testing/selftests/bpf/prog_tests/libbpf_str.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
18c5d71d9SDaniel Müller // SPDX-License-Identifier: GPL-2.0
28c5d71d9SDaniel Müller /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
38c5d71d9SDaniel Müller 
48c5d71d9SDaniel Müller #include <ctype.h>
58c5d71d9SDaniel Müller #include <test_progs.h>
68c5d71d9SDaniel Müller #include <bpf/btf.h>
78c5d71d9SDaniel Müller 
88c5d71d9SDaniel Müller /*
98c5d71d9SDaniel Müller  * Utility function uppercasing an entire string.
108c5d71d9SDaniel Müller  */
uppercase(char * s)118c5d71d9SDaniel Müller static void uppercase(char *s)
128c5d71d9SDaniel Müller {
138c5d71d9SDaniel Müller 	for (; *s != '\0'; s++)
148c5d71d9SDaniel Müller 		*s = toupper(*s);
158c5d71d9SDaniel Müller }
168c5d71d9SDaniel Müller 
178c5d71d9SDaniel Müller /*
180b27b3d9SDaniel Müller  * Test case to check that all bpf_attach_type variants are covered by
190b27b3d9SDaniel Müller  * libbpf_bpf_attach_type_str.
200b27b3d9SDaniel Müller  */
test_libbpf_bpf_attach_type_str(void)210b27b3d9SDaniel Müller static void test_libbpf_bpf_attach_type_str(void)
220b27b3d9SDaniel Müller {
230b27b3d9SDaniel Müller 	struct btf *btf;
240b27b3d9SDaniel Müller 	const struct btf_type *t;
250b27b3d9SDaniel Müller 	const struct btf_enum *e;
260b27b3d9SDaniel Müller 	int i, n, id;
270b27b3d9SDaniel Müller 
280b27b3d9SDaniel Müller 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
290b27b3d9SDaniel Müller 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
300b27b3d9SDaniel Müller 		return;
310b27b3d9SDaniel Müller 
320b27b3d9SDaniel Müller 	/* find enum bpf_attach_type and enumerate each value */
330b27b3d9SDaniel Müller 	id = btf__find_by_name_kind(btf, "bpf_attach_type", BTF_KIND_ENUM);
340b27b3d9SDaniel Müller 	if (!ASSERT_GT(id, 0, "bpf_attach_type_id"))
350b27b3d9SDaniel Müller 		goto cleanup;
360b27b3d9SDaniel Müller 	t = btf__type_by_id(btf, id);
370b27b3d9SDaniel Müller 	e = btf_enum(t);
380b27b3d9SDaniel Müller 	n = btf_vlen(t);
390b27b3d9SDaniel Müller 	for (i = 0; i < n; e++, i++) {
400b27b3d9SDaniel Müller 		enum bpf_attach_type attach_type = (enum bpf_attach_type)e->val;
410b27b3d9SDaniel Müller 		const char *attach_type_name;
420b27b3d9SDaniel Müller 		const char *attach_type_str;
430b27b3d9SDaniel Müller 		char buf[256];
440b27b3d9SDaniel Müller 
450b27b3d9SDaniel Müller 		if (attach_type == __MAX_BPF_ATTACH_TYPE)
460b27b3d9SDaniel Müller 			continue;
470b27b3d9SDaniel Müller 
480b27b3d9SDaniel Müller 		attach_type_name = btf__str_by_offset(btf, e->name_off);
490b27b3d9SDaniel Müller 		attach_type_str = libbpf_bpf_attach_type_str(attach_type);
500b27b3d9SDaniel Müller 		ASSERT_OK_PTR(attach_type_str, attach_type_name);
510b27b3d9SDaniel Müller 
520b27b3d9SDaniel Müller 		snprintf(buf, sizeof(buf), "BPF_%s", attach_type_str);
530b27b3d9SDaniel Müller 		uppercase(buf);
540b27b3d9SDaniel Müller 
550b27b3d9SDaniel Müller 		ASSERT_STREQ(buf, attach_type_name, "exp_str_value");
560b27b3d9SDaniel Müller 	}
570b27b3d9SDaniel Müller 
580b27b3d9SDaniel Müller cleanup:
590b27b3d9SDaniel Müller 	btf__free(btf);
600b27b3d9SDaniel Müller }
610b27b3d9SDaniel Müller 
620b27b3d9SDaniel Müller /*
63dea73da2SDaniel Müller  * Test case to check that all bpf_link_type variants are covered by
64dea73da2SDaniel Müller  * libbpf_bpf_link_type_str.
65dea73da2SDaniel Müller  */
test_libbpf_bpf_link_type_str(void)66dea73da2SDaniel Müller static void test_libbpf_bpf_link_type_str(void)
67dea73da2SDaniel Müller {
68dea73da2SDaniel Müller 	struct btf *btf;
69dea73da2SDaniel Müller 	const struct btf_type *t;
70dea73da2SDaniel Müller 	const struct btf_enum *e;
71dea73da2SDaniel Müller 	int i, n, id;
72dea73da2SDaniel Müller 
73dea73da2SDaniel Müller 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
74dea73da2SDaniel Müller 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
75dea73da2SDaniel Müller 		return;
76dea73da2SDaniel Müller 
77dea73da2SDaniel Müller 	/* find enum bpf_link_type and enumerate each value */
78dea73da2SDaniel Müller 	id = btf__find_by_name_kind(btf, "bpf_link_type", BTF_KIND_ENUM);
79dea73da2SDaniel Müller 	if (!ASSERT_GT(id, 0, "bpf_link_type_id"))
80dea73da2SDaniel Müller 		goto cleanup;
81dea73da2SDaniel Müller 	t = btf__type_by_id(btf, id);
82dea73da2SDaniel Müller 	e = btf_enum(t);
83dea73da2SDaniel Müller 	n = btf_vlen(t);
84dea73da2SDaniel Müller 	for (i = 0; i < n; e++, i++) {
85dea73da2SDaniel Müller 		enum bpf_link_type link_type = (enum bpf_link_type)e->val;
86dea73da2SDaniel Müller 		const char *link_type_name;
87dea73da2SDaniel Müller 		const char *link_type_str;
88dea73da2SDaniel Müller 		char buf[256];
89dea73da2SDaniel Müller 
90dea73da2SDaniel Müller 		if (link_type == MAX_BPF_LINK_TYPE)
91dea73da2SDaniel Müller 			continue;
92dea73da2SDaniel Müller 
93dea73da2SDaniel Müller 		link_type_name = btf__str_by_offset(btf, e->name_off);
94dea73da2SDaniel Müller 		link_type_str = libbpf_bpf_link_type_str(link_type);
95dea73da2SDaniel Müller 		ASSERT_OK_PTR(link_type_str, link_type_name);
96dea73da2SDaniel Müller 
97dea73da2SDaniel Müller 		snprintf(buf, sizeof(buf), "BPF_LINK_TYPE_%s", link_type_str);
98dea73da2SDaniel Müller 		uppercase(buf);
99dea73da2SDaniel Müller 
100dea73da2SDaniel Müller 		ASSERT_STREQ(buf, link_type_name, "exp_str_value");
101dea73da2SDaniel Müller 	}
102dea73da2SDaniel Müller 
103dea73da2SDaniel Müller cleanup:
104dea73da2SDaniel Müller 	btf__free(btf);
105dea73da2SDaniel Müller }
106dea73da2SDaniel Müller 
107dea73da2SDaniel Müller /*
108c3a25740SDaniel Müller  * Test case to check that all bpf_map_type variants are covered by
109c3a25740SDaniel Müller  * libbpf_bpf_map_type_str.
110c3a25740SDaniel Müller  */
test_libbpf_bpf_map_type_str(void)111c3a25740SDaniel Müller static void test_libbpf_bpf_map_type_str(void)
112c3a25740SDaniel Müller {
113c3a25740SDaniel Müller 	struct btf *btf;
114c3a25740SDaniel Müller 	const struct btf_type *t;
115c3a25740SDaniel Müller 	const struct btf_enum *e;
116c3a25740SDaniel Müller 	int i, n, id;
117c3a25740SDaniel Müller 
118c3a25740SDaniel Müller 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
119c3a25740SDaniel Müller 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
120c3a25740SDaniel Müller 		return;
121c3a25740SDaniel Müller 
122c3a25740SDaniel Müller 	/* find enum bpf_map_type and enumerate each value */
123c3a25740SDaniel Müller 	id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM);
124c3a25740SDaniel Müller 	if (!ASSERT_GT(id, 0, "bpf_map_type_id"))
125c3a25740SDaniel Müller 		goto cleanup;
126c3a25740SDaniel Müller 	t = btf__type_by_id(btf, id);
127c3a25740SDaniel Müller 	e = btf_enum(t);
128c3a25740SDaniel Müller 	n = btf_vlen(t);
129c3a25740SDaniel Müller 	for (i = 0; i < n; e++, i++) {
130c3a25740SDaniel Müller 		enum bpf_map_type map_type = (enum bpf_map_type)e->val;
131c3a25740SDaniel Müller 		const char *map_type_name;
132c3a25740SDaniel Müller 		const char *map_type_str;
133c3a25740SDaniel Müller 		char buf[256];
134c3a25740SDaniel Müller 
135c3a25740SDaniel Müller 		map_type_name = btf__str_by_offset(btf, e->name_off);
136c3a25740SDaniel Müller 		map_type_str = libbpf_bpf_map_type_str(map_type);
137c3a25740SDaniel Müller 		ASSERT_OK_PTR(map_type_str, map_type_name);
138c3a25740SDaniel Müller 
139c3a25740SDaniel Müller 		snprintf(buf, sizeof(buf), "BPF_MAP_TYPE_%s", map_type_str);
140c3a25740SDaniel Müller 		uppercase(buf);
141c3a25740SDaniel Müller 
142*fd4ca6c1SYonghong Song 		/* Special case for map_type_name BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED
143*fd4ca6c1SYonghong Song 		 * where it and BPF_MAP_TYPE_CGROUP_STORAGE have the same enum value
144*fd4ca6c1SYonghong Song 		 * (map_type). For this enum value, libbpf_bpf_map_type_str() picks
145*fd4ca6c1SYonghong Song 		 * BPF_MAP_TYPE_CGROUP_STORAGE.
146*fd4ca6c1SYonghong Song 		 */
147*fd4ca6c1SYonghong Song 		if (strcmp(map_type_name, "BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED") == 0)
148*fd4ca6c1SYonghong Song 			continue;
149*fd4ca6c1SYonghong Song 
150c3a25740SDaniel Müller 		ASSERT_STREQ(buf, map_type_name, "exp_str_value");
151c3a25740SDaniel Müller 	}
152c3a25740SDaniel Müller 
153c3a25740SDaniel Müller cleanup:
154c3a25740SDaniel Müller 	btf__free(btf);
155c3a25740SDaniel Müller }
156c3a25740SDaniel Müller 
157c3a25740SDaniel Müller /*
1588c5d71d9SDaniel Müller  * Test case to check that all bpf_prog_type variants are covered by
1598c5d71d9SDaniel Müller  * libbpf_bpf_prog_type_str.
1608c5d71d9SDaniel Müller  */
test_libbpf_bpf_prog_type_str(void)161c3a25740SDaniel Müller static void test_libbpf_bpf_prog_type_str(void)
1628c5d71d9SDaniel Müller {
1638c5d71d9SDaniel Müller 	struct btf *btf;
1648c5d71d9SDaniel Müller 	const struct btf_type *t;
1658c5d71d9SDaniel Müller 	const struct btf_enum *e;
1668c5d71d9SDaniel Müller 	int i, n, id;
1678c5d71d9SDaniel Müller 
1688c5d71d9SDaniel Müller 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
1698c5d71d9SDaniel Müller 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
1708c5d71d9SDaniel Müller 		return;
1718c5d71d9SDaniel Müller 
1728c5d71d9SDaniel Müller 	/* find enum bpf_prog_type and enumerate each value */
1738c5d71d9SDaniel Müller 	id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM);
1748c5d71d9SDaniel Müller 	if (!ASSERT_GT(id, 0, "bpf_prog_type_id"))
1758c5d71d9SDaniel Müller 		goto cleanup;
1768c5d71d9SDaniel Müller 	t = btf__type_by_id(btf, id);
1778c5d71d9SDaniel Müller 	e = btf_enum(t);
1788c5d71d9SDaniel Müller 	n = btf_vlen(t);
1798c5d71d9SDaniel Müller 	for (i = 0; i < n; e++, i++) {
1808c5d71d9SDaniel Müller 		enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val;
1818c5d71d9SDaniel Müller 		const char *prog_type_name;
1828c5d71d9SDaniel Müller 		const char *prog_type_str;
1838c5d71d9SDaniel Müller 		char buf[256];
1848c5d71d9SDaniel Müller 
1858c5d71d9SDaniel Müller 		prog_type_name = btf__str_by_offset(btf, e->name_off);
1868c5d71d9SDaniel Müller 		prog_type_str = libbpf_bpf_prog_type_str(prog_type);
1878c5d71d9SDaniel Müller 		ASSERT_OK_PTR(prog_type_str, prog_type_name);
1888c5d71d9SDaniel Müller 
1898c5d71d9SDaniel Müller 		snprintf(buf, sizeof(buf), "BPF_PROG_TYPE_%s", prog_type_str);
1908c5d71d9SDaniel Müller 		uppercase(buf);
1918c5d71d9SDaniel Müller 
1928c5d71d9SDaniel Müller 		ASSERT_STREQ(buf, prog_type_name, "exp_str_value");
1938c5d71d9SDaniel Müller 	}
1948c5d71d9SDaniel Müller 
1958c5d71d9SDaniel Müller cleanup:
1968c5d71d9SDaniel Müller 	btf__free(btf);
1978c5d71d9SDaniel Müller }
198c3a25740SDaniel Müller 
199c3a25740SDaniel Müller /*
200c3a25740SDaniel Müller  * Run all libbpf str conversion tests.
201c3a25740SDaniel Müller  */
test_libbpf_str(void)202c3a25740SDaniel Müller void test_libbpf_str(void)
203c3a25740SDaniel Müller {
2040b27b3d9SDaniel Müller 	if (test__start_subtest("bpf_attach_type_str"))
2050b27b3d9SDaniel Müller 		test_libbpf_bpf_attach_type_str();
2060b27b3d9SDaniel Müller 
207dea73da2SDaniel Müller 	if (test__start_subtest("bpf_link_type_str"))
208dea73da2SDaniel Müller 		test_libbpf_bpf_link_type_str();
209dea73da2SDaniel Müller 
210c3a25740SDaniel Müller 	if (test__start_subtest("bpf_map_type_str"))
211c3a25740SDaniel Müller 		test_libbpf_bpf_map_type_str();
212c3a25740SDaniel Müller 
213c3a25740SDaniel Müller 	if (test__start_subtest("bpf_prog_type_str"))
214c3a25740SDaniel Müller 		test_libbpf_bpf_prog_type_str();
215c3a25740SDaniel Müller }
216