File Index
Files and directories
Sign in
FILE

test_progs.h

File preview with syntax highlighting.

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