xref: /linux/tools/testing/selftests/net/tcp_ao/lib/aolib.h (revision 1a9239bb4253f9076b5b4b2a1a4e8d7defd77a95)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * TCP-AO selftest library. Provides helpers to unshare network
4  * namespaces, create veth, assign ip addresses, set routes,
5  * manipulate socket options, read network counter and etc.
6  * Author: Dmitry Safonov <dima@arista.com>
7  */
8 #ifndef _AOLIB_H_
9 #define _AOLIB_H_
10 
11 #include <arpa/inet.h>
12 #include <errno.h>
13 #include <linux/snmp.h>
14 #include <linux/tcp.h>
15 #include <netinet/in.h>
16 #include <stdarg.h>
17 #include <stdbool.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/syscall.h>
22 #include <unistd.h>
23 
24 #include "../../../../../include/linux/stringify.h"
25 #include "../../../../../include/linux/bits.h"
26 
27 #ifndef SOL_TCP
28 /* can't include <netinet/tcp.h> as including <linux/tcp.h> */
29 # define SOL_TCP		6	/* TCP level */
30 #endif
31 
32 /* Working around ksft, see the comment in lib/setup.c */
33 extern void __test_msg(const char *buf);
34 extern void __test_ok(const char *buf);
35 extern void __test_fail(const char *buf);
36 extern void __test_xfail(const char *buf);
37 extern void __test_error(const char *buf);
38 extern void __test_skip(const char *buf);
39 
test_snprintf(const char * fmt,va_list vargs)40 static inline char *test_snprintf(const char *fmt, va_list vargs)
41 {
42 	char *ret = NULL;
43 	size_t size = 0;
44 	va_list tmp;
45 	int n = 0;
46 
47 	va_copy(tmp, vargs);
48 	n = vsnprintf(ret, size, fmt, tmp);
49 	va_end(tmp);
50 	if (n < 0)
51 		return NULL;
52 
53 	size = n + 1;
54 	ret = malloc(size);
55 	if (!ret)
56 		return NULL;
57 
58 	n = vsnprintf(ret, size, fmt, vargs);
59 	if (n < 0 || n > size - 1) {
60 		free(ret);
61 		return NULL;
62 	}
63 	return ret;
64 }
65 
test_sprintf(const char * fmt,...)66 static __printf(1, 2) inline char *test_sprintf(const char *fmt, ...)
67 {
68 	va_list vargs;
69 	char *ret;
70 
71 	va_start(vargs, fmt);
72 	ret = test_snprintf(fmt, vargs);
73 	va_end(vargs);
74 
75 	return ret;
76 }
77 
__test_print(void (* fn)(const char *),const char * fmt,...)78 static __printf(2, 3) inline void __test_print(void (*fn)(const char *),
79 					       const char *fmt, ...)
80 {
81 	va_list vargs;
82 	char *msg;
83 
84 	va_start(vargs, fmt);
85 	msg = test_snprintf(fmt, vargs);
86 	va_end(vargs);
87 
88 	if (!msg)
89 		return;
90 
91 	fn(msg);
92 	free(msg);
93 }
94 
95 #define test_print(fmt, ...)						\
96 	__test_print(__test_msg, "%ld[%s:%u] " fmt "\n",		\
97 		     syscall(SYS_gettid),				\
98 		     __FILE__, __LINE__, ##__VA_ARGS__)
99 
100 #define test_ok(fmt, ...)						\
101 	__test_print(__test_ok, fmt "\n", ##__VA_ARGS__)
102 #define test_skip(fmt, ...)						\
103 	__test_print(__test_skip, fmt "\n", ##__VA_ARGS__)
104 #define test_xfail(fmt, ...)						\
105 	__test_print(__test_xfail, fmt "\n", ##__VA_ARGS__)
106 
107 #define test_fail(fmt, ...)						\
108 do {									\
109 	if (errno)							\
110 		__test_print(__test_fail, fmt ": %m\n", ##__VA_ARGS__);	\
111 	else								\
112 		__test_print(__test_fail, fmt "\n", ##__VA_ARGS__);	\
113 	test_failed();							\
114 } while (0)
115 
116 #define KSFT_FAIL  1
117 #define test_error(fmt, ...)						\
118 do {									\
119 	if (errno)							\
120 		__test_print(__test_error, "%ld[%s:%u] " fmt ": %m\n",	\
121 			     syscall(SYS_gettid), __FILE__, __LINE__,	\
122 			     ##__VA_ARGS__);				\
123 	else								\
124 		__test_print(__test_error, "%ld[%s:%u] " fmt "\n",	\
125 			     syscall(SYS_gettid), __FILE__, __LINE__,	\
126 			     ##__VA_ARGS__);				\
127 	exit(KSFT_FAIL);						\
128 } while (0)
129 
130 enum test_fault {
131 	FAULT_TIMEOUT = 1,
132 	FAULT_KEYREJECT,
133 	FAULT_PREINSTALL_AO,
134 	FAULT_PREINSTALL_MD5,
135 	FAULT_POSTINSTALL,
136 	FAULT_BUSY,
137 	FAULT_CURRNEXT,
138 	FAULT_FIXME,
139 };
140 typedef enum test_fault fault_t;
141 
142 enum test_needs_kconfig {
143 	KCONFIG_NET_NS = 0,		/* required */
144 	KCONFIG_VETH,			/* required */
145 	KCONFIG_TCP_AO,			/* required */
146 	KCONFIG_TCP_MD5,		/* optional, for TCP-MD5 features */
147 	KCONFIG_NET_VRF,		/* optional, for L3/VRF testing */
148 	KCONFIG_FTRACE,			/* optional, for tracepoints checks */
149 	__KCONFIG_LAST__
150 };
151 extern bool kernel_config_has(enum test_needs_kconfig k);
152 extern const char *tests_skip_reason[__KCONFIG_LAST__];
should_skip_test(const char * tst_name,enum test_needs_kconfig k)153 static inline bool should_skip_test(const char *tst_name,
154 				    enum test_needs_kconfig k)
155 {
156 	if (kernel_config_has(k))
157 		return false;
158 	test_skip("%s: %s", tst_name, tests_skip_reason[k]);
159 	return true;
160 }
161 
162 union tcp_addr {
163 	struct in_addr a4;
164 	struct in6_addr a6;
165 };
166 
167 typedef void *(*thread_fn)(void *);
168 extern void test_failed(void);
169 extern void __test_init(unsigned int ntests, int family, unsigned int prefix,
170 			union tcp_addr addr1, union tcp_addr addr2,
171 			thread_fn peer1, thread_fn peer2);
172 
test_init2(unsigned int ntests,thread_fn peer1,thread_fn peer2,int family,unsigned int prefix,const char * addr1,const char * addr2)173 static inline void test_init2(unsigned int ntests,
174 			      thread_fn peer1, thread_fn peer2,
175 			      int family, unsigned int prefix,
176 			      const char *addr1, const char *addr2)
177 {
178 	union tcp_addr taddr1, taddr2;
179 
180 	if (inet_pton(family, addr1, &taddr1) != 1)
181 		test_error("Can't convert ip address %s", addr1);
182 	if (inet_pton(family, addr2, &taddr2) != 1)
183 		test_error("Can't convert ip address %s", addr2);
184 
185 	__test_init(ntests, family, prefix, taddr1, taddr2, peer1, peer2);
186 }
187 extern void test_add_destructor(void (*d)(void));
188 extern void test_init_ftrace(int nsfd1, int nsfd2);
189 extern int test_setup_tracing(void);
190 
191 /* To adjust optmem socket limit, approximately estimate a number,
192  * that is bigger than sizeof(struct tcp_ao_key).
193  */
194 #define KERNEL_TCP_AO_KEY_SZ_ROUND_UP	300
195 
196 extern void test_set_optmem(size_t value);
197 extern size_t test_get_optmem(void);
198 
199 extern const struct sockaddr_in6 addr_any6;
200 extern const struct sockaddr_in addr_any4;
201 
202 #ifdef IPV6_TEST
203 # define __TEST_CLIENT_IP(n)	("2001:db8:" __stringify(n) "::1")
204 # define TEST_CLIENT_IP	__TEST_CLIENT_IP(1)
205 # define TEST_WRONG_IP	"2001:db8:253::1"
206 # define TEST_SERVER_IP	"2001:db8:254::1"
207 # define TEST_NETWORK	"2001::"
208 # define TEST_PREFIX	128
209 # define TEST_FAMILY	AF_INET6
210 # define SOCKADDR_ANY	addr_any6
211 # define sockaddr_af	struct sockaddr_in6
212 #else
213 # define __TEST_CLIENT_IP(n)	("10.0." __stringify(n) ".1")
214 # define TEST_CLIENT_IP	__TEST_CLIENT_IP(1)
215 # define TEST_WRONG_IP	"10.0.253.1"
216 # define TEST_SERVER_IP	"10.0.254.1"
217 # define TEST_NETWORK	"10.0.0.0"
218 # define TEST_PREFIX	32
219 # define TEST_FAMILY	AF_INET
220 # define SOCKADDR_ANY	addr_any4
221 # define sockaddr_af	struct sockaddr_in
222 #endif
223 
gen_tcp_addr(union tcp_addr net,size_t n)224 static inline union tcp_addr gen_tcp_addr(union tcp_addr net, size_t n)
225 {
226 	union tcp_addr ret = net;
227 
228 #ifdef IPV6_TEST
229 	ret.a6.s6_addr32[3] = htonl(n & (BIT(32) - 1));
230 	ret.a6.s6_addr32[2] = htonl((n >> 32) & (BIT(32) - 1));
231 #else
232 	ret.a4.s_addr = htonl(ntohl(net.a4.s_addr) + n);
233 #endif
234 
235 	return ret;
236 }
237 
tcp_addr_to_sockaddr_in(void * dest,const union tcp_addr * src,unsigned int port)238 static inline void tcp_addr_to_sockaddr_in(void *dest,
239 					   const union tcp_addr *src,
240 					   unsigned int port)
241 {
242 	sockaddr_af *out = dest;
243 
244 	memset(out, 0, sizeof(*out));
245 #ifdef IPV6_TEST
246 	out->sin6_family = AF_INET6;
247 	out->sin6_port   = port;
248 	out->sin6_addr   = src->a6;
249 #else
250 	out->sin_family  = AF_INET;
251 	out->sin_port    = port;
252 	out->sin_addr    = src->a4;
253 #endif
254 }
255 
test_init(unsigned int ntests,thread_fn peer1,thread_fn peer2)256 static inline void test_init(unsigned int ntests,
257 			     thread_fn peer1, thread_fn peer2)
258 {
259 	test_init2(ntests, peer1, peer2, TEST_FAMILY, TEST_PREFIX,
260 			TEST_SERVER_IP, TEST_CLIENT_IP);
261 }
262 extern void synchronize_threads(void);
263 extern void switch_ns(int fd);
264 extern int switch_save_ns(int fd);
265 extern void switch_close_ns(int fd);
266 
267 extern __thread union tcp_addr this_ip_addr;
268 extern __thread union tcp_addr this_ip_dest;
269 extern int test_family;
270 
271 extern void randomize_buffer(void *buf, size_t buflen);
272 extern __printf(3, 4) int test_echo(const char *fname, bool append,
273 				    const char *fmt, ...);
274 
275 extern int open_netns(void);
276 extern int unshare_open_netns(void);
277 extern const char veth_name[];
278 extern int add_veth(const char *name, int nsfda, int nsfdb);
279 extern int add_vrf(const char *name, uint32_t tabid, int ifindex, int nsfd);
280 extern int ip_addr_add(const char *intf, int family,
281 		       union tcp_addr addr, uint8_t prefix);
282 extern int ip_route_add(const char *intf, int family,
283 			union tcp_addr src, union tcp_addr dst);
284 extern int ip_route_add_vrf(const char *intf, int family,
285 			    union tcp_addr src, union tcp_addr dst,
286 			    uint8_t vrf);
287 extern int link_set_up(const char *intf);
288 
289 extern const unsigned int test_server_port;
290 extern int test_wait_fd(int sk, time_t sec, bool write);
291 extern int __test_connect_socket(int sk, const char *device,
292 				 void *addr, size_t addr_sz, bool async);
293 extern int __test_listen_socket(int backlog, void *addr, size_t addr_sz);
294 
test_listen_socket(const union tcp_addr taddr,unsigned int port,int backlog)295 static inline int test_listen_socket(const union tcp_addr taddr,
296 				     unsigned int port, int backlog)
297 {
298 	sockaddr_af addr;
299 
300 	tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port));
301 	return __test_listen_socket(backlog, (void *)&addr, sizeof(addr));
302 }
303 
304 /*
305  * In order for selftests to work under CONFIG_CRYPTO_FIPS=y,
306  * the password should be loger than 14 bytes, see hmac_setkey()
307  */
308 #define TEST_TCP_AO_MINKEYLEN	14
309 #define DEFAULT_TEST_PASSWORD	"In this hour, I do not believe that any darkness will endure."
310 
311 #ifndef DEFAULT_TEST_ALGO
312 #define DEFAULT_TEST_ALGO	"cmac(aes128)"
313 #endif
314 
315 #ifdef IPV6_TEST
316 #define DEFAULT_TEST_PREFIX	128
317 #else
318 #define DEFAULT_TEST_PREFIX	32
319 #endif
320 
321 /*
322  * Timeout on syscalls where failure is not expected.
323  * You may want to rise it if the test machine is very busy.
324  */
325 #ifndef TEST_TIMEOUT_SEC
326 #define TEST_TIMEOUT_SEC	5
327 #endif
328 
329 /*
330  * Timeout on connect() where a failure is expected.
331  * If set to 0 - kernel will try to retransmit SYN number of times, set in
332  * /proc/sys/net/ipv4/tcp_syn_retries
333  * By default set to 1 to make tests pass faster on non-busy machine.
334  * [in process of removal, don't use in new tests]
335  */
336 #ifndef TEST_RETRANSMIT_SEC
337 #define TEST_RETRANSMIT_SEC	1
338 #endif
339 
_test_connect_socket(int sk,const union tcp_addr taddr,unsigned int port,bool async)340 static inline int _test_connect_socket(int sk, const union tcp_addr taddr,
341 				       unsigned int port, bool async)
342 {
343 	sockaddr_af addr;
344 
345 	tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port));
346 	return __test_connect_socket(sk, veth_name,
347 				     (void *)&addr, sizeof(addr), async);
348 }
349 
test_connect_socket(int sk,const union tcp_addr taddr,unsigned int port)350 static inline int test_connect_socket(int sk, const union tcp_addr taddr,
351 				      unsigned int port)
352 {
353 	return _test_connect_socket(sk, taddr, port, false);
354 }
355 
356 extern int __test_set_md5(int sk, void *addr, size_t addr_sz,
357 			  uint8_t prefix, int vrf, const char *password);
test_set_md5(int sk,const union tcp_addr in_addr,uint8_t prefix,int vrf,const char * password)358 static inline int test_set_md5(int sk, const union tcp_addr in_addr,
359 			       uint8_t prefix, int vrf, const char *password)
360 {
361 	sockaddr_af addr;
362 
363 	if (prefix > DEFAULT_TEST_PREFIX)
364 		prefix = DEFAULT_TEST_PREFIX;
365 
366 	tcp_addr_to_sockaddr_in(&addr, &in_addr, 0);
367 	return __test_set_md5(sk, (void *)&addr, sizeof(addr),
368 			prefix, vrf, password);
369 }
370 
371 extern int test_prepare_key_sockaddr(struct tcp_ao_add *ao, const char *alg,
372 		void *addr, size_t addr_sz, bool set_current, bool set_rnext,
373 		uint8_t prefix, uint8_t vrf,
374 		uint8_t sndid, uint8_t rcvid, uint8_t maclen,
375 		uint8_t keyflags, uint8_t keylen, const char *key);
376 
test_prepare_key(struct tcp_ao_add * ao,const char * alg,union tcp_addr taddr,bool set_current,bool set_rnext,uint8_t prefix,uint8_t vrf,uint8_t sndid,uint8_t rcvid,uint8_t maclen,uint8_t keyflags,uint8_t keylen,const char * key)377 static inline int test_prepare_key(struct tcp_ao_add *ao,
378 		const char *alg, union tcp_addr taddr,
379 		bool set_current, bool set_rnext,
380 		uint8_t prefix, uint8_t vrf,
381 		uint8_t sndid, uint8_t rcvid, uint8_t maclen,
382 		uint8_t keyflags, uint8_t keylen, const char *key)
383 {
384 	sockaddr_af addr;
385 
386 	tcp_addr_to_sockaddr_in(&addr, &taddr, 0);
387 	return test_prepare_key_sockaddr(ao, alg, (void *)&addr, sizeof(addr),
388 			set_current, set_rnext, prefix, vrf, sndid, rcvid,
389 			maclen, keyflags, keylen, key);
390 }
391 
test_prepare_def_key(struct tcp_ao_add * ao,const char * key,uint8_t keyflags,union tcp_addr in_addr,uint8_t prefix,uint8_t vrf,uint8_t sndid,uint8_t rcvid)392 static inline int test_prepare_def_key(struct tcp_ao_add *ao,
393 		const char *key, uint8_t keyflags,
394 		union tcp_addr in_addr, uint8_t prefix, uint8_t vrf,
395 		uint8_t sndid, uint8_t rcvid)
396 {
397 	if (prefix > DEFAULT_TEST_PREFIX)
398 		prefix = DEFAULT_TEST_PREFIX;
399 
400 	return test_prepare_key(ao, DEFAULT_TEST_ALGO, in_addr, false, false,
401 				prefix, vrf, sndid, rcvid, 0, keyflags,
402 				strlen(key), key);
403 }
404 
405 extern int test_get_one_ao(int sk, struct tcp_ao_getsockopt *out,
406 			   void *addr, size_t addr_sz,
407 			   uint8_t prefix, uint8_t sndid, uint8_t rcvid);
408 extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out);
409 extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in);
410 extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a,
411 					  const struct tcp_ao_getsockopt *b);
412 extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a,
413 					     const struct tcp_ao_info_opt *b);
414 
test_verify_socket_key(int sk,struct tcp_ao_add * key)415 static inline int test_verify_socket_key(int sk, struct tcp_ao_add *key)
416 {
417 	struct tcp_ao_getsockopt key2 = {};
418 	int err;
419 
420 	err = test_get_one_ao(sk, &key2, &key->addr, sizeof(key->addr),
421 			      key->prefix, key->sndid, key->rcvid);
422 	if (err)
423 		return err;
424 
425 	return test_cmp_getsockopt_setsockopt(key, &key2);
426 }
427 
test_add_key_vrf(int sk,const char * key,uint8_t keyflags,union tcp_addr in_addr,uint8_t prefix,uint8_t vrf,uint8_t sndid,uint8_t rcvid)428 static inline int test_add_key_vrf(int sk,
429 				   const char *key, uint8_t keyflags,
430 				   union tcp_addr in_addr, uint8_t prefix,
431 				   uint8_t vrf, uint8_t sndid, uint8_t rcvid)
432 {
433 	struct tcp_ao_add tmp = {};
434 	int err;
435 
436 	err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix,
437 				   vrf, sndid, rcvid);
438 	if (err)
439 		return err;
440 
441 	err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp));
442 	if (err < 0)
443 		return -errno;
444 
445 	return test_verify_socket_key(sk, &tmp);
446 }
447 
test_add_key(int sk,const char * key,union tcp_addr in_addr,uint8_t prefix,uint8_t sndid,uint8_t rcvid)448 static inline int test_add_key(int sk, const char *key,
449 			      union tcp_addr in_addr, uint8_t prefix,
450 			      uint8_t sndid, uint8_t rcvid)
451 {
452 	return test_add_key_vrf(sk, key, 0, in_addr, prefix, 0, sndid, rcvid);
453 }
454 
test_verify_socket_ao(int sk,struct tcp_ao_info_opt * ao)455 static inline int test_verify_socket_ao(int sk, struct tcp_ao_info_opt *ao)
456 {
457 	struct tcp_ao_info_opt ao2 = {};
458 	int err;
459 
460 	err = test_get_ao_info(sk, &ao2);
461 	if (err)
462 		return err;
463 
464 	return test_cmp_getsockopt_setsockopt_ao(ao, &ao2);
465 }
466 
test_set_ao_flags(int sk,bool ao_required,bool accept_icmps)467 static inline int test_set_ao_flags(int sk, bool ao_required, bool accept_icmps)
468 {
469 	struct tcp_ao_info_opt ao = {};
470 	int err;
471 
472 	err = test_get_ao_info(sk, &ao);
473 	/* Maybe ao_info wasn't allocated yet */
474 	if (err && err != -ENOENT)
475 		return err;
476 
477 	ao.ao_required = !!ao_required;
478 	ao.accept_icmps = !!accept_icmps;
479 	err = test_set_ao_info(sk, &ao);
480 	if (err)
481 		return err;
482 
483 	return test_verify_socket_ao(sk, &ao);
484 }
485 
486 extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec);
487 extern int test_client_verify(int sk, const size_t msg_len, const size_t nr);
488 
489 struct tcp_ao_key_counters {
490 	uint8_t sndid;
491 	uint8_t rcvid;
492 	uint64_t pkt_good;
493 	uint64_t pkt_bad;
494 };
495 
496 struct tcp_ao_counters {
497 	/* per-netns */
498 	uint64_t netns_ao_good;
499 	uint64_t netns_ao_bad;
500 	uint64_t netns_ao_key_not_found;
501 	uint64_t netns_ao_required;
502 	uint64_t netns_ao_dropped_icmp;
503 	/* per-socket */
504 	uint64_t ao_info_pkt_good;
505 	uint64_t ao_info_pkt_bad;
506 	uint64_t ao_info_pkt_key_not_found;
507 	uint64_t ao_info_pkt_ao_required;
508 	uint64_t ao_info_pkt_dropped_icmp;
509 	/* per-key */
510 	size_t nr_keys;
511 	struct tcp_ao_key_counters *key_cnts;
512 };
513 
514 struct tcp_counters {
515 	struct tcp_ao_counters ao;
516 	uint64_t netns_md5_notfound;
517 	uint64_t netns_md5_unexpected;
518 	uint64_t netns_md5_failure;
519 };
520 
521 extern int test_get_tcp_counters(int sk, struct tcp_counters *out);
522 
523 #define TEST_CNT_KEY_GOOD		BIT(0)
524 #define TEST_CNT_KEY_BAD		BIT(1)
525 #define TEST_CNT_SOCK_GOOD		BIT(2)
526 #define TEST_CNT_SOCK_BAD		BIT(3)
527 #define TEST_CNT_SOCK_KEY_NOT_FOUND	BIT(4)
528 #define TEST_CNT_SOCK_AO_REQUIRED	BIT(5)
529 #define TEST_CNT_SOCK_DROPPED_ICMP	BIT(6)
530 #define TEST_CNT_NS_GOOD		BIT(7)
531 #define TEST_CNT_NS_BAD			BIT(8)
532 #define TEST_CNT_NS_KEY_NOT_FOUND	BIT(9)
533 #define TEST_CNT_NS_AO_REQUIRED		BIT(10)
534 #define TEST_CNT_NS_DROPPED_ICMP	BIT(11)
535 #define TEST_CNT_NS_MD5_NOT_FOUND	BIT(12)
536 #define TEST_CNT_NS_MD5_UNEXPECTED	BIT(13)
537 #define TEST_CNT_NS_MD5_FAILURE		BIT(14)
538 typedef uint16_t test_cnt;
539 
540 #define _for_each_counter(f)						\
541 do {									\
542 	/* per-netns */							\
543 	f(ao.netns_ao_good,		TEST_CNT_NS_GOOD);		\
544 	f(ao.netns_ao_bad,		TEST_CNT_NS_BAD);		\
545 	f(ao.netns_ao_key_not_found,	TEST_CNT_NS_KEY_NOT_FOUND);	\
546 	f(ao.netns_ao_required,		TEST_CNT_NS_AO_REQUIRED);	\
547 	f(ao.netns_ao_dropped_icmp,	TEST_CNT_NS_DROPPED_ICMP);	\
548 	/* per-socket */						\
549 	f(ao.ao_info_pkt_good,		TEST_CNT_SOCK_GOOD);		\
550 	f(ao.ao_info_pkt_bad,		TEST_CNT_SOCK_BAD);		\
551 	f(ao.ao_info_pkt_key_not_found,	TEST_CNT_SOCK_KEY_NOT_FOUND);	\
552 	f(ao.ao_info_pkt_ao_required,	TEST_CNT_SOCK_AO_REQUIRED);	\
553 	f(ao.ao_info_pkt_dropped_icmp,	TEST_CNT_SOCK_DROPPED_ICMP);	\
554 	/* non-AO */							\
555 	f(netns_md5_notfound,		TEST_CNT_NS_MD5_NOT_FOUND);	\
556 	f(netns_md5_unexpected,		TEST_CNT_NS_MD5_UNEXPECTED);	\
557 	f(netns_md5_failure,		TEST_CNT_NS_MD5_FAILURE);	\
558 } while (0)
559 
560 #define TEST_CNT_AO_GOOD		(TEST_CNT_SOCK_GOOD | TEST_CNT_NS_GOOD)
561 #define TEST_CNT_AO_BAD			(TEST_CNT_SOCK_BAD | TEST_CNT_NS_BAD)
562 #define TEST_CNT_AO_KEY_NOT_FOUND	(TEST_CNT_SOCK_KEY_NOT_FOUND | \
563 					 TEST_CNT_NS_KEY_NOT_FOUND)
564 #define TEST_CNT_AO_REQUIRED		(TEST_CNT_SOCK_AO_REQUIRED | \
565 					 TEST_CNT_NS_AO_REQUIRED)
566 #define TEST_CNT_AO_DROPPED_ICMP	(TEST_CNT_SOCK_DROPPED_ICMP | \
567 					 TEST_CNT_NS_DROPPED_ICMP)
568 #define TEST_CNT_GOOD			(TEST_CNT_KEY_GOOD | TEST_CNT_AO_GOOD)
569 #define TEST_CNT_BAD			(TEST_CNT_KEY_BAD | TEST_CNT_AO_BAD)
570 
571 extern test_cnt test_cmp_counters(struct tcp_counters *before,
572 				  struct tcp_counters *after);
573 extern int test_assert_counters_sk(const char *tst_name,
574 		struct tcp_counters *before, struct tcp_counters *after,
575 		test_cnt expected);
576 extern int test_assert_counters_key(const char *tst_name,
577 		struct tcp_ao_counters *before, struct tcp_ao_counters *after,
578 		test_cnt expected, int sndid, int rcvid);
579 extern void test_tcp_counters_free(struct tcp_counters *cnts);
580 
581 /*
582  * Polling for netns and socket counters during select()/connect() and also
583  * client/server messaging. Instead of constant timeout on underlying select(),
584  * check the counters and return early. This allows to pass the tests where
585  * timeout is expected without waiting for that fixing timeout (tests speed-up).
586  * Previously shorter timeouts were used for tests expecting to time out,
587  * but that leaded to sporadic false positives on counter checks failures,
588  * as one second timeouts aren't enough for TCP retransmit.
589  *
590  * Two sides of the socketpair (client/server) should synchronize failures
591  * using a shared variable *err, so that they can detect the other side's
592  * failure.
593  */
594 extern int test_skpair_wait_poll(int sk, bool write, test_cnt cond,
595 				 volatile int *err);
596 extern int _test_skpair_connect_poll(int sk, const char *device,
597 				     void *addr, size_t addr_sz,
598 				     test_cnt cond, volatile int *err);
test_skpair_connect_poll(int sk,const union tcp_addr taddr,unsigned int port,test_cnt cond,volatile int * err)599 static inline int test_skpair_connect_poll(int sk, const union tcp_addr taddr,
600 					   unsigned int port,
601 					   test_cnt cond, volatile int *err)
602 {
603 	sockaddr_af addr;
604 
605 	tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port));
606 	return _test_skpair_connect_poll(sk, veth_name,
607 					 (void *)&addr, sizeof(addr), cond, err);
608 }
609 
610 extern int test_skpair_client(int sk, const size_t msg_len, const size_t nr,
611 			      test_cnt cond, volatile int *err);
612 extern int test_skpair_server(int sk, ssize_t quota,
613 			      test_cnt cond, volatile int *err);
614 
615 /*
616  * Frees buffers allocated in test_get_tcp_counters().
617  * The function doesn't expect new keys or keys removed between calls
618  * to test_get_tcp_counters(). Check key counters manually if they
619  * may change.
620  */
test_assert_counters(const char * tst_name,struct tcp_counters * before,struct tcp_counters * after,test_cnt expected)621 static inline int test_assert_counters(const char *tst_name,
622 				       struct tcp_counters *before,
623 				       struct tcp_counters *after,
624 				       test_cnt expected)
625 {
626 	int ret;
627 
628 	ret = test_assert_counters_sk(tst_name, before, after, expected);
629 	if (ret)
630 		goto out;
631 	ret = test_assert_counters_key(tst_name, &before->ao, &after->ao,
632 				       expected, -1, -1);
633 out:
634 	test_tcp_counters_free(before);
635 	test_tcp_counters_free(after);
636 	return ret;
637 }
638 
639 struct netstat;
640 extern struct netstat *netstat_read(void);
641 extern void netstat_free(struct netstat *ns);
642 extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb);
643 extern uint64_t netstat_get(struct netstat *ns,
644 			    const char *name, bool *not_found);
645 
netstat_get_one(const char * name,bool * not_found)646 static inline uint64_t netstat_get_one(const char *name, bool *not_found)
647 {
648 	struct netstat *ns = netstat_read();
649 	uint64_t ret;
650 
651 	ret = netstat_get(ns, name, not_found);
652 
653 	netstat_free(ns);
654 	return ret;
655 }
656 
657 struct tcp_sock_queue {
658 	uint32_t seq;
659 	void *buf;
660 };
661 
662 struct tcp_sock_state {
663 	struct tcp_info info;
664 	struct tcp_repair_window trw;
665 	struct tcp_sock_queue out;
666 	int outq_len;		/* output queue size (not sent + not acked) */
667 	int outq_nsd_len;	/* output queue size (not sent only) */
668 	struct tcp_sock_queue in;
669 	int inq_len;
670 	int mss;
671 	int timestamp;
672 };
673 
674 extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state,
675 				   void *addr, size_t addr_size);
test_sock_checkpoint(int sk,struct tcp_sock_state * state,sockaddr_af * saddr)676 static inline void test_sock_checkpoint(int sk, struct tcp_sock_state *state,
677 					sockaddr_af *saddr)
678 {
679 	__test_sock_checkpoint(sk, state, saddr, sizeof(*saddr));
680 }
681 extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state);
682 extern void __test_sock_restore(int sk, const char *device,
683 				struct tcp_sock_state *state,
684 				void *saddr, void *daddr, size_t addr_size);
test_sock_restore(int sk,struct tcp_sock_state * state,sockaddr_af * saddr,const union tcp_addr daddr,unsigned int dport)685 static inline void test_sock_restore(int sk, struct tcp_sock_state *state,
686 				     sockaddr_af *saddr,
687 				     const union tcp_addr daddr,
688 				     unsigned int dport)
689 {
690 	sockaddr_af addr;
691 
692 	tcp_addr_to_sockaddr_in(&addr, &daddr, htons(dport));
693 	__test_sock_restore(sk, veth_name, state, saddr, &addr, sizeof(addr));
694 }
695 extern void test_ao_restore(int sk, struct tcp_ao_repair *state);
696 extern void test_sock_state_free(struct tcp_sock_state *state);
697 extern void test_enable_repair(int sk);
698 extern void test_disable_repair(int sk);
699 extern void test_kill_sk(int sk);
test_add_repaired_key(int sk,const char * key,uint8_t keyflags,union tcp_addr in_addr,uint8_t prefix,uint8_t sndid,uint8_t rcvid)700 static inline int test_add_repaired_key(int sk,
701 					const char *key, uint8_t keyflags,
702 					union tcp_addr in_addr, uint8_t prefix,
703 					uint8_t sndid, uint8_t rcvid)
704 {
705 	struct tcp_ao_add tmp = {};
706 	int err;
707 
708 	err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix,
709 				   0, sndid, rcvid);
710 	if (err)
711 		return err;
712 
713 	tmp.set_current = 1;
714 	tmp.set_rnext = 1;
715 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0)
716 		return -errno;
717 
718 	return test_verify_socket_key(sk, &tmp);
719 }
720 
721 #define DEFAULT_FTRACE_BUFFER_KB	10000
722 #define DEFAULT_TRACER_LINES_ARR	200
723 struct test_ftracer;
724 extern uint64_t ns_cookie1, ns_cookie2;
725 
726 enum ftracer_op {
727 	FTRACER_LINE_DISCARD = 0,
728 	FTRACER_LINE_PRESERVE,
729 	FTRACER_EXIT,
730 };
731 
732 extern struct test_ftracer *create_ftracer(const char *name,
733 		enum ftracer_op (*process_line)(const char *line),
734 		void (*destructor)(struct test_ftracer *tracer),
735 		bool (*expecting_more)(void),
736 		size_t lines_buf_sz, size_t buffer_size_kb);
737 extern int setup_trace_event(struct test_ftracer *tracer,
738 			     const char *event, const char *filter);
739 extern void destroy_ftracer(struct test_ftracer *tracer);
740 extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer);
741 extern const char **tracer_get_savedlines(struct test_ftracer *tracer);
742 
743 enum trace_events {
744 	/* TCP_HASH_EVENT */
745 	TCP_HASH_BAD_HEADER = 0,
746 	TCP_HASH_MD5_REQUIRED,
747 	TCP_HASH_MD5_UNEXPECTED,
748 	TCP_HASH_MD5_MISMATCH,
749 	TCP_HASH_AO_REQUIRED,
750 	/* TCP_AO_EVENT */
751 	TCP_AO_HANDSHAKE_FAILURE,
752 	TCP_AO_WRONG_MACLEN,
753 	TCP_AO_MISMATCH,
754 	TCP_AO_KEY_NOT_FOUND,
755 	TCP_AO_RNEXT_REQUEST,
756 	/* TCP_AO_EVENT_SK */
757 	TCP_AO_SYNACK_NO_KEY,
758 	/* TCP_AO_EVENT_SNE */
759 	TCP_AO_SND_SNE_UPDATE,
760 	TCP_AO_RCV_SNE_UPDATE,
761 	__MAX_TRACE_EVENTS
762 };
763 
764 extern int __trace_event_expect(enum trace_events type, int family,
765 				union tcp_addr src, union tcp_addr dst,
766 				int src_port, int dst_port, int L3index,
767 				int fin, int syn, int rst, int psh, int ack,
768 				int keyid, int rnext, int maclen, int sne);
769 
trace_hash_event_expect(enum trace_events type,union tcp_addr src,union tcp_addr dst,int src_port,int dst_port,int L3index,int fin,int syn,int rst,int psh,int ack)770 static inline void trace_hash_event_expect(enum trace_events type,
771 				union tcp_addr src, union tcp_addr dst,
772 				int src_port, int dst_port, int L3index,
773 				int fin, int syn, int rst, int psh, int ack)
774 {
775 	int err;
776 
777 	err = __trace_event_expect(type, TEST_FAMILY, src, dst,
778 				   src_port, dst_port, L3index,
779 				   fin, syn, rst, psh, ack,
780 				   -1, -1, -1, -1);
781 	if (err)
782 		test_error("Couldn't add a trace event: %d", err);
783 }
784 
trace_ao_event_expect(enum trace_events type,union tcp_addr src,union tcp_addr dst,int src_port,int dst_port,int L3index,int fin,int syn,int rst,int psh,int ack,int keyid,int rnext,int maclen)785 static inline void trace_ao_event_expect(enum trace_events type,
786 				union tcp_addr src, union tcp_addr dst,
787 				int src_port, int dst_port, int L3index,
788 				int fin, int syn, int rst, int psh, int ack,
789 				int keyid, int rnext, int maclen)
790 {
791 	int err;
792 
793 	err = __trace_event_expect(type, TEST_FAMILY, src, dst,
794 				   src_port, dst_port, L3index,
795 				   fin, syn, rst, psh, ack,
796 				   keyid, rnext, maclen, -1);
797 	if (err)
798 		test_error("Couldn't add a trace event: %d", err);
799 }
800 
trace_ao_event_sk_expect(enum trace_events type,union tcp_addr src,union tcp_addr dst,int src_port,int dst_port,int keyid,int rnext)801 static inline void trace_ao_event_sk_expect(enum trace_events type,
802 				union tcp_addr src, union tcp_addr dst,
803 				int src_port, int dst_port,
804 				int keyid, int rnext)
805 {
806 	int err;
807 
808 	err = __trace_event_expect(type, TEST_FAMILY, src, dst,
809 				   src_port, dst_port, -1,
810 				   -1, -1, -1, -1, -1,
811 				   keyid, rnext, -1, -1);
812 	if (err)
813 		test_error("Couldn't add a trace event: %d", err);
814 }
815 
trace_ao_event_sne_expect(enum trace_events type,union tcp_addr src,union tcp_addr dst,int src_port,int dst_port,int sne)816 static inline void trace_ao_event_sne_expect(enum trace_events type,
817 				union tcp_addr src, union tcp_addr dst,
818 				int src_port, int dst_port, int sne)
819 {
820 	int err;
821 
822 	err = __trace_event_expect(type, TEST_FAMILY, src, dst,
823 				   src_port, dst_port, -1,
824 				   -1, -1, -1, -1, -1,
825 				   -1, -1, -1, sne);
826 	if (err)
827 		test_error("Couldn't add a trace event: %d", err);
828 }
829 
830 extern int setup_aolib_ftracer(void);
831 
832 #endif /* _AOLIB_H_ */
833