1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #include <stdio.h>
3*4882a593Smuzhiyun #include <unistd.h>
4*4882a593Smuzhiyun #include <errno.h>
5*4882a593Smuzhiyun #include <string.h>
6*4882a593Smuzhiyun #include <assert.h>
7*4882a593Smuzhiyun #include <stdlib.h>
8*4882a593Smuzhiyun #include <stdarg.h>
9*4882a593Smuzhiyun #include <time.h>
10*4882a593Smuzhiyun #include <signal.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/types.h>
13*4882a593Smuzhiyun typedef __u16 __sum16;
14*4882a593Smuzhiyun #include <arpa/inet.h>
15*4882a593Smuzhiyun #include <linux/if_ether.h>
16*4882a593Smuzhiyun #include <linux/if_packet.h>
17*4882a593Smuzhiyun #include <linux/ip.h>
18*4882a593Smuzhiyun #include <linux/ipv6.h>
19*4882a593Smuzhiyun #include <netinet/tcp.h>
20*4882a593Smuzhiyun #include <linux/filter.h>
21*4882a593Smuzhiyun #include <linux/perf_event.h>
22*4882a593Smuzhiyun #include <linux/socket.h>
23*4882a593Smuzhiyun #include <linux/unistd.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #include <sys/ioctl.h>
26*4882a593Smuzhiyun #include <sys/wait.h>
27*4882a593Smuzhiyun #include <sys/types.h>
28*4882a593Smuzhiyun #include <sys/time.h>
29*4882a593Smuzhiyun #include <fcntl.h>
30*4882a593Smuzhiyun #include <pthread.h>
31*4882a593Smuzhiyun #include <linux/bpf.h>
32*4882a593Smuzhiyun #include <linux/err.h>
33*4882a593Smuzhiyun #include <bpf/bpf.h>
34*4882a593Smuzhiyun #include <bpf/libbpf.h>
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include "test_iptunnel_common.h"
37*4882a593Smuzhiyun #include "bpf_util.h"
38*4882a593Smuzhiyun #include <bpf/bpf_endian.h>
39*4882a593Smuzhiyun #include "trace_helpers.h"
40*4882a593Smuzhiyun #include "testing_helpers.h"
41*4882a593Smuzhiyun #include "flow_dissector_load.h"
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun enum verbosity {
44*4882a593Smuzhiyun VERBOSE_NONE,
45*4882a593Smuzhiyun VERBOSE_NORMAL,
46*4882a593Smuzhiyun VERBOSE_VERY,
47*4882a593Smuzhiyun VERBOSE_SUPER,
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun struct str_set {
51*4882a593Smuzhiyun const char **strs;
52*4882a593Smuzhiyun int cnt;
53*4882a593Smuzhiyun };
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun struct test_selector {
56*4882a593Smuzhiyun struct str_set whitelist;
57*4882a593Smuzhiyun struct str_set blacklist;
58*4882a593Smuzhiyun bool *num_set;
59*4882a593Smuzhiyun int num_set_len;
60*4882a593Smuzhiyun };
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun struct test_env {
63*4882a593Smuzhiyun struct test_selector test_selector;
64*4882a593Smuzhiyun struct test_selector subtest_selector;
65*4882a593Smuzhiyun bool verifier_stats;
66*4882a593Smuzhiyun enum verbosity verbosity;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun bool jit_enabled;
69*4882a593Smuzhiyun bool get_test_cnt;
70*4882a593Smuzhiyun bool list_test_names;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun struct prog_test_def *test;
73*4882a593Smuzhiyun FILE *stdout;
74*4882a593Smuzhiyun FILE *stderr;
75*4882a593Smuzhiyun char *log_buf;
76*4882a593Smuzhiyun size_t log_cnt;
77*4882a593Smuzhiyun int nr_cpus;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun int succ_cnt; /* successful tests */
80*4882a593Smuzhiyun int sub_succ_cnt; /* successful sub-tests */
81*4882a593Smuzhiyun int fail_cnt; /* total failed tests + sub-tests */
82*4882a593Smuzhiyun int skip_cnt; /* skipped tests */
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun int saved_netns_fd;
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun extern struct test_env env;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun extern void test__force_log();
90*4882a593Smuzhiyun extern bool test__start_subtest(const char *name);
91*4882a593Smuzhiyun extern void test__skip(void);
92*4882a593Smuzhiyun extern void test__fail(void);
93*4882a593Smuzhiyun extern int test__join_cgroup(const char *path);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #define PRINT_FAIL(format...) \
96*4882a593Smuzhiyun ({ \
97*4882a593Smuzhiyun test__fail(); \
98*4882a593Smuzhiyun fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__); \
99*4882a593Smuzhiyun fprintf(stdout, ##format); \
100*4882a593Smuzhiyun })
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun #define _CHECK(condition, tag, duration, format...) ({ \
103*4882a593Smuzhiyun int __ret = !!(condition); \
104*4882a593Smuzhiyun int __save_errno = errno; \
105*4882a593Smuzhiyun if (__ret) { \
106*4882a593Smuzhiyun test__fail(); \
107*4882a593Smuzhiyun fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \
108*4882a593Smuzhiyun fprintf(stdout, ##format); \
109*4882a593Smuzhiyun } else { \
110*4882a593Smuzhiyun fprintf(stdout, "%s:PASS:%s %d nsec\n", \
111*4882a593Smuzhiyun __func__, tag, duration); \
112*4882a593Smuzhiyun } \
113*4882a593Smuzhiyun errno = __save_errno; \
114*4882a593Smuzhiyun __ret; \
115*4882a593Smuzhiyun })
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun #define CHECK_FAIL(condition) ({ \
118*4882a593Smuzhiyun int __ret = !!(condition); \
119*4882a593Smuzhiyun int __save_errno = errno; \
120*4882a593Smuzhiyun if (__ret) { \
121*4882a593Smuzhiyun test__fail(); \
122*4882a593Smuzhiyun fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \
123*4882a593Smuzhiyun } \
124*4882a593Smuzhiyun errno = __save_errno; \
125*4882a593Smuzhiyun __ret; \
126*4882a593Smuzhiyun })
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun #define CHECK(condition, tag, format...) \
129*4882a593Smuzhiyun _CHECK(condition, tag, duration, format)
130*4882a593Smuzhiyun #define CHECK_ATTR(condition, tag, format...) \
131*4882a593Smuzhiyun _CHECK(condition, tag, tattr.duration, format)
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #define ASSERT_EQ(actual, expected, name) ({ \
134*4882a593Smuzhiyun static int duration = 0; \
135*4882a593Smuzhiyun typeof(actual) ___act = (actual); \
136*4882a593Smuzhiyun typeof(expected) ___exp = (expected); \
137*4882a593Smuzhiyun bool ___ok = ___act == ___exp; \
138*4882a593Smuzhiyun CHECK(!___ok, (name), \
139*4882a593Smuzhiyun "unexpected %s: actual %lld != expected %lld\n", \
140*4882a593Smuzhiyun (name), (long long)(___act), (long long)(___exp)); \
141*4882a593Smuzhiyun ___ok; \
142*4882a593Smuzhiyun })
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #define ASSERT_STREQ(actual, expected, name) ({ \
145*4882a593Smuzhiyun static int duration = 0; \
146*4882a593Smuzhiyun const char *___act = actual; \
147*4882a593Smuzhiyun const char *___exp = expected; \
148*4882a593Smuzhiyun bool ___ok = strcmp(___act, ___exp) == 0; \
149*4882a593Smuzhiyun CHECK(!___ok, (name), \
150*4882a593Smuzhiyun "unexpected %s: actual '%s' != expected '%s'\n", \
151*4882a593Smuzhiyun (name), ___act, ___exp); \
152*4882a593Smuzhiyun ___ok; \
153*4882a593Smuzhiyun })
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun #define ASSERT_OK(res, name) ({ \
156*4882a593Smuzhiyun static int duration = 0; \
157*4882a593Smuzhiyun long long ___res = (res); \
158*4882a593Smuzhiyun bool ___ok = ___res == 0; \
159*4882a593Smuzhiyun CHECK(!___ok, (name), "unexpected error: %lld\n", ___res); \
160*4882a593Smuzhiyun ___ok; \
161*4882a593Smuzhiyun })
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun #define ASSERT_ERR(res, name) ({ \
164*4882a593Smuzhiyun static int duration = 0; \
165*4882a593Smuzhiyun long long ___res = (res); \
166*4882a593Smuzhiyun bool ___ok = ___res < 0; \
167*4882a593Smuzhiyun CHECK(!___ok, (name), "unexpected success: %lld\n", ___res); \
168*4882a593Smuzhiyun ___ok; \
169*4882a593Smuzhiyun })
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun #define ASSERT_NULL(ptr, name) ({ \
172*4882a593Smuzhiyun static int duration = 0; \
173*4882a593Smuzhiyun const void *___res = (ptr); \
174*4882a593Smuzhiyun bool ___ok = !___res; \
175*4882a593Smuzhiyun CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \
176*4882a593Smuzhiyun ___ok; \
177*4882a593Smuzhiyun })
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun #define ASSERT_OK_PTR(ptr, name) ({ \
180*4882a593Smuzhiyun static int duration = 0; \
181*4882a593Smuzhiyun const void *___res = (ptr); \
182*4882a593Smuzhiyun bool ___ok = !IS_ERR_OR_NULL(___res); \
183*4882a593Smuzhiyun CHECK(!___ok, (name), \
184*4882a593Smuzhiyun "unexpected error: %ld\n", PTR_ERR(___res)); \
185*4882a593Smuzhiyun ___ok; \
186*4882a593Smuzhiyun })
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun #define ASSERT_ERR_PTR(ptr, name) ({ \
189*4882a593Smuzhiyun static int duration = 0; \
190*4882a593Smuzhiyun const void *___res = (ptr); \
191*4882a593Smuzhiyun bool ___ok = IS_ERR(___res) \
192*4882a593Smuzhiyun CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \
193*4882a593Smuzhiyun ___ok; \
194*4882a593Smuzhiyun })
195*4882a593Smuzhiyun
ptr_to_u64(const void * ptr)196*4882a593Smuzhiyun static inline __u64 ptr_to_u64(const void *ptr)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun return (__u64) (unsigned long) ptr;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
u64_to_ptr(__u64 ptr)201*4882a593Smuzhiyun static inline void *u64_to_ptr(__u64 ptr)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun return (void *) (unsigned long) ptr;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun int bpf_find_map(const char *test, struct bpf_object *obj, const char *name);
207*4882a593Smuzhiyun int compare_map_keys(int map1_fd, int map2_fd);
208*4882a593Smuzhiyun int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
209*4882a593Smuzhiyun int extract_build_id(char *build_id, size_t size);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun #ifdef __x86_64__
212*4882a593Smuzhiyun #define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"
213*4882a593Smuzhiyun #elif defined(__s390x__)
214*4882a593Smuzhiyun #define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"
215*4882a593Smuzhiyun #else
216*4882a593Smuzhiyun #define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"
217*4882a593Smuzhiyun #endif
218