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