1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __TEST_PROGS_H
3#define __TEST_PROGS_H
4
5#include <stdio.h>
6#include <unistd.h>
7#include <errno.h>
8#include <string.h>
9#include <assert.h>
10#include <stdlib.h>
11#include <stdarg.h>
12#include <time.h>
13#include <signal.h>
14
15#include <linux/types.h>
16typedef __u16 __sum16;
17#include <arpa/inet.h>
18#include <linux/if_ether.h>
19#include <linux/if_packet.h>
20#include <linux/ip.h>
21#include <linux/ipv6.h>
22#include <linux/filter.h>
23#include <linux/perf_event.h>
24#include <linux/socket.h>
25#include <linux/unistd.h>
26
27#include <sys/ioctl.h>
28#include <sys/wait.h>
29#include <sys/types.h>
30#include <sys/time.h>
31#include <sys/param.h>
32#include <fcntl.h>
33#include <pthread.h>
34#include <linux/bpf.h>
35#include <linux/err.h>
36#include <bpf/bpf.h>
37#include <bpf/libbpf.h>
38
39#include "test_iptunnel_common.h"
40#include "bpf_util.h"
41#include <bpf/bpf_endian.h>
42#include "trace_helpers.h"
43#include "testing_helpers.h"
44
45enum verbosity {
46	VERBOSE_NONE,
47	VERBOSE_NORMAL,
48	VERBOSE_VERY,
49	VERBOSE_SUPER,
50};
51
52struct test_filter {
53	char *name;
54	char **subtests;
55	int subtest_cnt;
56};
57
58struct test_filter_set {
59	struct test_filter *tests;
60	int cnt;
61};
62
63struct test_selector {
64	struct test_filter_set whitelist;
65	struct test_filter_set blacklist;
66	bool *num_set;
67	int num_set_len;
68};
69
70struct subtest_state {
71	char *name;
72	size_t log_cnt;
73	char *log_buf;
74	int error_cnt;
75	bool skipped;
76	bool filtered;
77
78	FILE *stdout;
79};
80
81struct test_state {
82	bool tested;
83	bool force_log;
84
85	int error_cnt;
86	int skip_cnt;
87	int sub_succ_cnt;
88
89	struct subtest_state *subtest_states;
90	int subtest_num;
91
92	size_t log_cnt;
93	char *log_buf;
94
95	FILE *stdout;
96};
97
98struct test_env {
99	struct test_selector test_selector;
100	struct test_selector subtest_selector;
101	bool verifier_stats;
102	bool debug;
103	enum verbosity verbosity;
104
105	bool jit_enabled;
106	bool has_testmod;
107	bool get_test_cnt;
108	bool list_test_names;
109
110	struct prog_test_def *test; /* current running test */
111	struct test_state *test_state; /* current running test state */
112	struct subtest_state *subtest_state; /* current running subtest state */
113
114	FILE *stdout;
115	FILE *stderr;
116	int nr_cpus;
117	FILE *json;
118
119	int succ_cnt; /* successful tests */
120	int sub_succ_cnt; /* successful sub-tests */
121	int fail_cnt; /* total failed tests + sub-tests */
122	int skip_cnt; /* skipped tests */
123
124	int saved_netns_fd;
125	int workers; /* number of worker process */
126	int worker_id; /* id number of current worker, main process is -1 */
127	pid_t *worker_pids; /* array of worker pids */
128	int *worker_socks; /* array of worker socks */
129	int *worker_current_test; /* array of current running test for each worker */
130};
131
132#define MAX_LOG_TRUNK_SIZE 8192
133#define MAX_SUBTEST_NAME 1024
134enum msg_type {
135	MSG_DO_TEST = 0,
136	MSG_TEST_DONE = 1,
137	MSG_TEST_LOG = 2,
138	MSG_SUBTEST_DONE = 3,
139	MSG_EXIT = 255,
140};
141struct msg {
142	enum msg_type type;
143	union {
144		struct {
145			int num;
146		} do_test;
147		struct {
148			int num;
149			int sub_succ_cnt;
150			int error_cnt;
151			int skip_cnt;
152			bool have_log;
153			int subtest_num;
154		} test_done;
155		struct {
156			char log_buf[MAX_LOG_TRUNK_SIZE + 1];
157			bool is_last;
158		} test_log;
159		struct {
160			int num;
161			char name[MAX_SUBTEST_NAME + 1];
162			int error_cnt;
163			bool skipped;
164			bool filtered;
165			bool have_log;
166		} subtest_done;
167	};
168};
169
170extern struct test_env env;
171
172void test__force_log(void);
173bool test__start_subtest(const char *name);
174void test__end_subtest(void);
175void test__skip(void);
176void test__fail(void);
177int test__join_cgroup(const char *path);
178
179#define PRINT_FAIL(format...)                                                  \
180	({                                                                     \
181		test__fail();                                                  \
182		fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__);            \
183		fprintf(stdout, ##format);                                     \
184	})
185
186#define _CHECK(condition, tag, duration, format...) ({			\
187	int __ret = !!(condition);					\
188	int __save_errno = errno;					\
189	if (__ret) {							\
190		test__fail();						\
191		fprintf(stdout, "%s:FAIL:%s ", __func__, tag);		\
192		fprintf(stdout, ##format);				\
193	} else {							\
194		fprintf(stdout, "%s:PASS:%s %d nsec\n",			\
195		       __func__, tag, duration);			\
196	}								\
197	errno = __save_errno;						\
198	__ret;								\
199})
200
201#define CHECK_FAIL(condition) ({					\
202	int __ret = !!(condition);					\
203	int __save_errno = errno;					\
204	if (__ret) {							\
205		test__fail();						\
206		fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__);	\
207	}								\
208	errno = __save_errno;						\
209	__ret;								\
210})
211
212#define CHECK(condition, tag, format...) \
213	_CHECK(condition, tag, duration, format)
214#define CHECK_ATTR(condition, tag, format...) \
215	_CHECK(condition, tag, tattr.duration, format)
216
217#define ASSERT_FAIL(fmt, args...) ({					\
218	static int duration = 0;					\
219	CHECK(false, "", fmt"\n", ##args);				\
220	false;								\
221})
222
223#define ASSERT_TRUE(actual, name) ({					\
224	static int duration = 0;					\
225	bool ___ok = (actual);						\
226	CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name));	\
227	___ok;								\
228})
229
230#define ASSERT_FALSE(actual, name) ({					\
231	static int duration = 0;					\
232	bool ___ok = !(actual);						\
233	CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name));	\
234	___ok;								\
235})
236
237#define ASSERT_EQ(actual, expected, name) ({				\
238	static int duration = 0;					\
239	typeof(actual) ___act = (actual);				\
240	typeof(expected) ___exp = (expected);				\
241	bool ___ok = ___act == ___exp;					\
242	CHECK(!___ok, (name),						\
243	      "unexpected %s: actual %lld != expected %lld\n",		\
244	      (name), (long long)(___act), (long long)(___exp));	\
245	___ok;								\
246})
247
248#define ASSERT_NEQ(actual, expected, name) ({				\
249	static int duration = 0;					\
250	typeof(actual) ___act = (actual);				\
251	typeof(expected) ___exp = (expected);				\
252	bool ___ok = ___act != ___exp;					\
253	CHECK(!___ok, (name),						\
254	      "unexpected %s: actual %lld == expected %lld\n",		\
255	      (name), (long long)(___act), (long long)(___exp));	\
256	___ok;								\
257})
258
259#define ASSERT_LT(actual, expected, name) ({				\
260	static int duration = 0;					\
261	typeof(actual) ___act = (actual);				\
262	typeof(expected) ___exp = (expected);				\
263	bool ___ok = ___act < ___exp;					\
264	CHECK(!___ok, (name),						\
265	      "unexpected %s: actual %lld >= expected %lld\n",		\
266	      (name), (long long)(___act), (long long)(___exp));	\
267	___ok;								\
268})
269
270#define ASSERT_LE(actual, expected, name) ({				\
271	static int duration = 0;					\
272	typeof(actual) ___act = (actual);				\
273	typeof(expected) ___exp = (expected);				\
274	bool ___ok = ___act <= ___exp;					\
275	CHECK(!___ok, (name),						\
276	      "unexpected %s: actual %lld > expected %lld\n",		\
277	      (name), (long long)(___act), (long long)(___exp));	\
278	___ok;								\
279})
280
281#define ASSERT_GT(actual, expected, name) ({				\
282	static int duration = 0;					\
283	typeof(actual) ___act = (actual);				\
284	typeof(expected) ___exp = (expected);				\
285	bool ___ok = ___act > ___exp;					\
286	CHECK(!___ok, (name),						\
287	      "unexpected %s: actual %lld <= expected %lld\n",		\
288	      (name), (long long)(___act), (long long)(___exp));	\
289	___ok;								\
290})
291
292#define ASSERT_GE(actual, expected, name) ({				\
293	static int duration = 0;					\
294	typeof(actual) ___act = (actual);				\
295	typeof(expected) ___exp = (expected);				\
296	bool ___ok = ___act >= ___exp;					\
297	CHECK(!___ok, (name),						\
298	      "unexpected %s: actual %lld < expected %lld\n",		\
299	      (name), (long long)(___act), (long long)(___exp));	\
300	___ok;								\
301})
302
303#define ASSERT_STREQ(actual, expected, name) ({				\
304	static int duration = 0;					\
305	const char *___act = actual;					\
306	const char *___exp = expected;					\
307	bool ___ok = strcmp(___act, ___exp) == 0;			\
308	CHECK(!___ok, (name),						\
309	      "unexpected %s: actual '%s' != expected '%s'\n",		\
310	      (name), ___act, ___exp);					\
311	___ok;								\
312})
313
314#define ASSERT_STRNEQ(actual, expected, len, name) ({			\
315	static int duration = 0;					\
316	const char *___act = actual;					\
317	const char *___exp = expected;					\
318	int ___len = len;						\
319	bool ___ok = strncmp(___act, ___exp, ___len) == 0;		\
320	CHECK(!___ok, (name),						\
321	      "unexpected %s: actual '%.*s' != expected '%.*s'\n",	\
322	      (name), ___len, ___act, ___len, ___exp);			\
323	___ok;								\
324})
325
326#define ASSERT_HAS_SUBSTR(str, substr, name) ({				\
327	static int duration = 0;					\
328	const char *___str = str;					\
329	const char *___substr = substr;					\
330	bool ___ok = strstr(___str, ___substr) != NULL;			\
331	CHECK(!___ok, (name),						\
332	      "unexpected %s: '%s' is not a substring of '%s'\n",	\
333	      (name), ___substr, ___str);				\
334	___ok;								\
335})
336
337#define ASSERT_OK(res, name) ({						\
338	static int duration = 0;					\
339	long long ___res = (res);					\
340	bool ___ok = ___res == 0;					\
341	CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n",	\
342	      ___res, errno);						\
343	___ok;								\
344})
345
346#define ASSERT_ERR(res, name) ({					\
347	static int duration = 0;					\
348	long long ___res = (res);					\
349	bool ___ok = ___res < 0;					\
350	CHECK(!___ok, (name), "unexpected success: %lld\n", ___res);	\
351	___ok;								\
352})
353
354#define ASSERT_NULL(ptr, name) ({					\
355	static int duration = 0;					\
356	const void *___res = (ptr);					\
357	bool ___ok = !___res;						\
358	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\
359	___ok;								\
360})
361
362#define ASSERT_OK_PTR(ptr, name) ({					\
363	static int duration = 0;					\
364	const void *___res = (ptr);					\
365	int ___err = libbpf_get_error(___res);				\
366	bool ___ok = ___err == 0;					\
367	CHECK(!___ok, (name), "unexpected error: %d\n", ___err);	\
368	___ok;								\
369})
370
371#define ASSERT_ERR_PTR(ptr, name) ({					\
372	static int duration = 0;					\
373	const void *___res = (ptr);					\
374	int ___err = libbpf_get_error(___res);				\
375	bool ___ok = ___err != 0;					\
376	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\
377	___ok;								\
378})
379
380#define SYS(goto_label, fmt, ...)					\
381	({								\
382		char cmd[1024];						\
383		snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__);		\
384		if (!ASSERT_OK(system(cmd), cmd))			\
385			goto goto_label;				\
386	})
387
388#define ALL_TO_DEV_NULL " >/dev/null 2>&1"
389
390#define SYS_NOFAIL(fmt, ...)						\
391	({								\
392		char cmd[1024];						\
393		int n;							\
394		n = snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__);	\
395		if (n < sizeof(cmd) && sizeof(cmd) - n >= sizeof(ALL_TO_DEV_NULL)) \
396			strcat(cmd, ALL_TO_DEV_NULL);			\
397		system(cmd);						\
398	})
399
400int start_libbpf_log_capture(void);
401char *stop_libbpf_log_capture(void);
402
403static inline __u64 ptr_to_u64(const void *ptr)
404{
405	return (__u64) (unsigned long) ptr;
406}
407
408static inline void *u64_to_ptr(__u64 ptr)
409{
410	return (void *) (unsigned long) ptr;
411}
412
413int bpf_find_map(const char *test, struct bpf_object *obj, const char *name);
414int compare_map_keys(int map1_fd, int map2_fd);
415int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
416int trigger_module_test_read(int read_sz);
417int trigger_module_test_write(int write_sz);
418int write_sysctl(const char *sysctl, const char *value);
419int get_bpf_max_tramp_links_from(struct btf *btf);
420int get_bpf_max_tramp_links(void);
421
422#ifdef __x86_64__
423#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"
424#elif defined(__s390x__)
425#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"
426#elif defined(__aarch64__)
427#define SYS_NANOSLEEP_KPROBE_NAME "__arm64_sys_nanosleep"
428#elif defined(__riscv)
429#define SYS_NANOSLEEP_KPROBE_NAME "__riscv_sys_nanosleep"
430#else
431#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"
432#endif
433
434#define BPF_TESTMOD_TEST_FILE "/sys/kernel/bpf_testmod"
435
436typedef int (*pre_execution_cb)(struct bpf_object *obj);
437
438struct test_loader {
439	char *log_buf;
440	size_t log_buf_sz;
441	size_t next_match_pos;
442	pre_execution_cb pre_execution_cb;
443
444	struct bpf_object *obj;
445};
446
447static inline void test_loader__set_pre_execution_cb(struct test_loader *tester,
448						     pre_execution_cb cb)
449{
450	tester->pre_execution_cb = cb;
451}
452
453typedef const void *(*skel_elf_bytes_fn)(size_t *sz);
454
455extern void test_loader__run_subtests(struct test_loader *tester,
456				      const char *skel_name,
457				      skel_elf_bytes_fn elf_bytes_factory);
458
459extern void test_loader_fini(struct test_loader *tester);
460
461#define RUN_TESTS(skel) ({						       \
462	struct test_loader tester = {};					       \
463									       \
464	test_loader__run_subtests(&tester, #skel, skel##__elf_bytes);	       \
465	test_loader_fini(&tester);					       \
466})
467
468#endif /* __TEST_PROGS_H */
469