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 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 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 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__]; 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 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 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 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 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 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 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 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); 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 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 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 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 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 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 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 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); 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 */ 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 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); 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); 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); 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 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 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 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 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