18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#include <stdio.h>
38c2ecf20Sopenharmony_ci#include <unistd.h>
48c2ecf20Sopenharmony_ci#include <errno.h>
58c2ecf20Sopenharmony_ci#include <string.h>
68c2ecf20Sopenharmony_ci#include <assert.h>
78c2ecf20Sopenharmony_ci#include <stdlib.h>
88c2ecf20Sopenharmony_ci#include <stdarg.h>
98c2ecf20Sopenharmony_ci#include <time.h>
108c2ecf20Sopenharmony_ci#include <signal.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/types.h>
138c2ecf20Sopenharmony_citypedef __u16 __sum16;
148c2ecf20Sopenharmony_ci#include <arpa/inet.h>
158c2ecf20Sopenharmony_ci#include <linux/if_ether.h>
168c2ecf20Sopenharmony_ci#include <linux/if_packet.h>
178c2ecf20Sopenharmony_ci#include <linux/ip.h>
188c2ecf20Sopenharmony_ci#include <linux/ipv6.h>
198c2ecf20Sopenharmony_ci#include <linux/filter.h>
208c2ecf20Sopenharmony_ci#include <linux/perf_event.h>
218c2ecf20Sopenharmony_ci#include <linux/socket.h>
228c2ecf20Sopenharmony_ci#include <linux/unistd.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include <sys/ioctl.h>
258c2ecf20Sopenharmony_ci#include <sys/wait.h>
268c2ecf20Sopenharmony_ci#include <sys/types.h>
278c2ecf20Sopenharmony_ci#include <sys/time.h>
288c2ecf20Sopenharmony_ci#include <fcntl.h>
298c2ecf20Sopenharmony_ci#include <pthread.h>
308c2ecf20Sopenharmony_ci#include <linux/bpf.h>
318c2ecf20Sopenharmony_ci#include <linux/err.h>
328c2ecf20Sopenharmony_ci#include <bpf/bpf.h>
338c2ecf20Sopenharmony_ci#include <bpf/libbpf.h>
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#include "test_iptunnel_common.h"
368c2ecf20Sopenharmony_ci#include "bpf_util.h"
378c2ecf20Sopenharmony_ci#include <bpf/bpf_endian.h>
388c2ecf20Sopenharmony_ci#include "trace_helpers.h"
398c2ecf20Sopenharmony_ci#include "testing_helpers.h"
408c2ecf20Sopenharmony_ci#include "flow_dissector_load.h"
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cienum verbosity {
438c2ecf20Sopenharmony_ci	VERBOSE_NONE,
448c2ecf20Sopenharmony_ci	VERBOSE_NORMAL,
458c2ecf20Sopenharmony_ci	VERBOSE_VERY,
468c2ecf20Sopenharmony_ci	VERBOSE_SUPER,
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistruct str_set {
508c2ecf20Sopenharmony_ci	const char **strs;
518c2ecf20Sopenharmony_ci	int cnt;
528c2ecf20Sopenharmony_ci};
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistruct test_selector {
558c2ecf20Sopenharmony_ci	struct str_set whitelist;
568c2ecf20Sopenharmony_ci	struct str_set blacklist;
578c2ecf20Sopenharmony_ci	bool *num_set;
588c2ecf20Sopenharmony_ci	int num_set_len;
598c2ecf20Sopenharmony_ci};
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistruct test_env {
628c2ecf20Sopenharmony_ci	struct test_selector test_selector;
638c2ecf20Sopenharmony_ci	struct test_selector subtest_selector;
648c2ecf20Sopenharmony_ci	bool verifier_stats;
658c2ecf20Sopenharmony_ci	enum verbosity verbosity;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	bool jit_enabled;
688c2ecf20Sopenharmony_ci	bool get_test_cnt;
698c2ecf20Sopenharmony_ci	bool list_test_names;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	struct prog_test_def *test;
728c2ecf20Sopenharmony_ci	FILE *stdout;
738c2ecf20Sopenharmony_ci	FILE *stderr;
748c2ecf20Sopenharmony_ci	char *log_buf;
758c2ecf20Sopenharmony_ci	size_t log_cnt;
768c2ecf20Sopenharmony_ci	int nr_cpus;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	int succ_cnt; /* successful tests */
798c2ecf20Sopenharmony_ci	int sub_succ_cnt; /* successful sub-tests */
808c2ecf20Sopenharmony_ci	int fail_cnt; /* total failed tests + sub-tests */
818c2ecf20Sopenharmony_ci	int skip_cnt; /* skipped tests */
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	int saved_netns_fd;
848c2ecf20Sopenharmony_ci};
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciextern struct test_env env;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ciextern void test__force_log();
898c2ecf20Sopenharmony_ciextern bool test__start_subtest(const char *name);
908c2ecf20Sopenharmony_ciextern void test__skip(void);
918c2ecf20Sopenharmony_ciextern void test__fail(void);
928c2ecf20Sopenharmony_ciextern int test__join_cgroup(const char *path);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#define PRINT_FAIL(format...)                                                  \
958c2ecf20Sopenharmony_ci	({                                                                     \
968c2ecf20Sopenharmony_ci		test__fail();                                                  \
978c2ecf20Sopenharmony_ci		fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__);            \
988c2ecf20Sopenharmony_ci		fprintf(stdout, ##format);                                     \
998c2ecf20Sopenharmony_ci	})
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci#define _CHECK(condition, tag, duration, format...) ({			\
1028c2ecf20Sopenharmony_ci	int __ret = !!(condition);					\
1038c2ecf20Sopenharmony_ci	int __save_errno = errno;					\
1048c2ecf20Sopenharmony_ci	if (__ret) {							\
1058c2ecf20Sopenharmony_ci		test__fail();						\
1068c2ecf20Sopenharmony_ci		fprintf(stdout, "%s:FAIL:%s ", __func__, tag);		\
1078c2ecf20Sopenharmony_ci		fprintf(stdout, ##format);				\
1088c2ecf20Sopenharmony_ci	} else {							\
1098c2ecf20Sopenharmony_ci		fprintf(stdout, "%s:PASS:%s %d nsec\n",			\
1108c2ecf20Sopenharmony_ci		       __func__, tag, duration);			\
1118c2ecf20Sopenharmony_ci	}								\
1128c2ecf20Sopenharmony_ci	errno = __save_errno;						\
1138c2ecf20Sopenharmony_ci	__ret;								\
1148c2ecf20Sopenharmony_ci})
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci#define CHECK_FAIL(condition) ({					\
1178c2ecf20Sopenharmony_ci	int __ret = !!(condition);					\
1188c2ecf20Sopenharmony_ci	int __save_errno = errno;					\
1198c2ecf20Sopenharmony_ci	if (__ret) {							\
1208c2ecf20Sopenharmony_ci		test__fail();						\
1218c2ecf20Sopenharmony_ci		fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__);	\
1228c2ecf20Sopenharmony_ci	}								\
1238c2ecf20Sopenharmony_ci	errno = __save_errno;						\
1248c2ecf20Sopenharmony_ci	__ret;								\
1258c2ecf20Sopenharmony_ci})
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci#define CHECK(condition, tag, format...) \
1288c2ecf20Sopenharmony_ci	_CHECK(condition, tag, duration, format)
1298c2ecf20Sopenharmony_ci#define CHECK_ATTR(condition, tag, format...) \
1308c2ecf20Sopenharmony_ci	_CHECK(condition, tag, tattr.duration, format)
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci#define ASSERT_EQ(actual, expected, name) ({				\
1338c2ecf20Sopenharmony_ci	static int duration = 0;					\
1348c2ecf20Sopenharmony_ci	typeof(actual) ___act = (actual);				\
1358c2ecf20Sopenharmony_ci	typeof(expected) ___exp = (expected);				\
1368c2ecf20Sopenharmony_ci	bool ___ok = ___act == ___exp;					\
1378c2ecf20Sopenharmony_ci	CHECK(!___ok, (name),						\
1388c2ecf20Sopenharmony_ci	      "unexpected %s: actual %lld != expected %lld\n",		\
1398c2ecf20Sopenharmony_ci	      (name), (long long)(___act), (long long)(___exp));	\
1408c2ecf20Sopenharmony_ci	___ok;								\
1418c2ecf20Sopenharmony_ci})
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci#define ASSERT_STREQ(actual, expected, name) ({				\
1448c2ecf20Sopenharmony_ci	static int duration = 0;					\
1458c2ecf20Sopenharmony_ci	const char *___act = actual;					\
1468c2ecf20Sopenharmony_ci	const char *___exp = expected;					\
1478c2ecf20Sopenharmony_ci	bool ___ok = strcmp(___act, ___exp) == 0;			\
1488c2ecf20Sopenharmony_ci	CHECK(!___ok, (name),						\
1498c2ecf20Sopenharmony_ci	      "unexpected %s: actual '%s' != expected '%s'\n",		\
1508c2ecf20Sopenharmony_ci	      (name), ___act, ___exp);					\
1518c2ecf20Sopenharmony_ci	___ok;								\
1528c2ecf20Sopenharmony_ci})
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#define ASSERT_OK(res, name) ({						\
1558c2ecf20Sopenharmony_ci	static int duration = 0;					\
1568c2ecf20Sopenharmony_ci	long long ___res = (res);					\
1578c2ecf20Sopenharmony_ci	bool ___ok = ___res == 0;					\
1588c2ecf20Sopenharmony_ci	CHECK(!___ok, (name), "unexpected error: %lld\n", ___res);	\
1598c2ecf20Sopenharmony_ci	___ok;								\
1608c2ecf20Sopenharmony_ci})
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci#define ASSERT_ERR(res, name) ({					\
1638c2ecf20Sopenharmony_ci	static int duration = 0;					\
1648c2ecf20Sopenharmony_ci	long long ___res = (res);					\
1658c2ecf20Sopenharmony_ci	bool ___ok = ___res < 0;					\
1668c2ecf20Sopenharmony_ci	CHECK(!___ok, (name), "unexpected success: %lld\n", ___res);	\
1678c2ecf20Sopenharmony_ci	___ok;								\
1688c2ecf20Sopenharmony_ci})
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci#define ASSERT_NULL(ptr, name) ({					\
1718c2ecf20Sopenharmony_ci	static int duration = 0;					\
1728c2ecf20Sopenharmony_ci	const void *___res = (ptr);					\
1738c2ecf20Sopenharmony_ci	bool ___ok = !___res;						\
1748c2ecf20Sopenharmony_ci	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\
1758c2ecf20Sopenharmony_ci	___ok;								\
1768c2ecf20Sopenharmony_ci})
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci#define ASSERT_OK_PTR(ptr, name) ({					\
1798c2ecf20Sopenharmony_ci	static int duration = 0;					\
1808c2ecf20Sopenharmony_ci	const void *___res = (ptr);					\
1818c2ecf20Sopenharmony_ci	bool ___ok = !IS_ERR_OR_NULL(___res);				\
1828c2ecf20Sopenharmony_ci	CHECK(!___ok, (name),						\
1838c2ecf20Sopenharmony_ci	      "unexpected error: %ld\n", PTR_ERR(___res));		\
1848c2ecf20Sopenharmony_ci	___ok;								\
1858c2ecf20Sopenharmony_ci})
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#define ASSERT_ERR_PTR(ptr, name) ({					\
1888c2ecf20Sopenharmony_ci	static int duration = 0;					\
1898c2ecf20Sopenharmony_ci	const void *___res = (ptr);					\
1908c2ecf20Sopenharmony_ci	bool ___ok = IS_ERR(___res)					\
1918c2ecf20Sopenharmony_ci	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\
1928c2ecf20Sopenharmony_ci	___ok;								\
1938c2ecf20Sopenharmony_ci})
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic inline __u64 ptr_to_u64(const void *ptr)
1968c2ecf20Sopenharmony_ci{
1978c2ecf20Sopenharmony_ci	return (__u64) (unsigned long) ptr;
1988c2ecf20Sopenharmony_ci}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic inline void *u64_to_ptr(__u64 ptr)
2018c2ecf20Sopenharmony_ci{
2028c2ecf20Sopenharmony_ci	return (void *) (unsigned long) ptr;
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ciint bpf_find_map(const char *test, struct bpf_object *obj, const char *name);
2068c2ecf20Sopenharmony_ciint compare_map_keys(int map1_fd, int map2_fd);
2078c2ecf20Sopenharmony_ciint compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
2088c2ecf20Sopenharmony_ciint extract_build_id(char *build_id, size_t size);
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci#ifdef __x86_64__
2118c2ecf20Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"
2128c2ecf20Sopenharmony_ci#elif defined(__s390x__)
2138c2ecf20Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"
2148c2ecf20Sopenharmony_ci#else
2158c2ecf20Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"
2168c2ecf20Sopenharmony_ci#endif
217