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 uint8_t keyflags, int ifindex); 409 extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out); 410 extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in); 411 extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a, 412 const struct tcp_ao_getsockopt *b); 413 extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a, 414 const struct tcp_ao_info_opt *b); 415 416 static inline int test_verify_socket_key(int sk, struct tcp_ao_add *key) 417 { 418 struct tcp_ao_getsockopt key2 = {}; 419 int err; 420 421 err = test_get_one_ao(sk, &key2, &key->addr, sizeof(key->addr), 422 key->prefix, key->sndid, key->rcvid, 423 key->keyflags, key->ifindex); 424 if (err) 425 return err; 426 427 return test_cmp_getsockopt_setsockopt(key, &key2); 428 } 429 430 static inline int test_add_key_vrf(int sk, 431 const char *key, uint8_t keyflags, 432 union tcp_addr in_addr, uint8_t prefix, 433 uint8_t vrf, uint8_t sndid, uint8_t rcvid) 434 { 435 struct tcp_ao_add tmp = {}; 436 int err; 437 438 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 439 vrf, sndid, rcvid); 440 if (err) 441 return err; 442 443 err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)); 444 if (err < 0) 445 return -errno; 446 447 return test_verify_socket_key(sk, &tmp); 448 } 449 450 static inline int test_add_key(int sk, const char *key, 451 union tcp_addr in_addr, uint8_t prefix, 452 uint8_t sndid, uint8_t rcvid) 453 { 454 return test_add_key_vrf(sk, key, 0, in_addr, prefix, 0, sndid, rcvid); 455 } 456 457 static inline int test_verify_socket_ao(int sk, struct tcp_ao_info_opt *ao) 458 { 459 struct tcp_ao_info_opt ao2 = {}; 460 int err; 461 462 err = test_get_ao_info(sk, &ao2); 463 if (err) 464 return err; 465 466 return test_cmp_getsockopt_setsockopt_ao(ao, &ao2); 467 } 468 469 static inline int test_set_ao_flags(int sk, bool ao_required, bool accept_icmps) 470 { 471 struct tcp_ao_info_opt ao = {}; 472 int err; 473 474 err = test_get_ao_info(sk, &ao); 475 /* Maybe ao_info wasn't allocated yet */ 476 if (err && err != -ENOENT) 477 return err; 478 479 ao.ao_required = !!ao_required; 480 ao.accept_icmps = !!accept_icmps; 481 err = test_set_ao_info(sk, &ao); 482 if (err) 483 return err; 484 485 return test_verify_socket_ao(sk, &ao); 486 } 487 488 extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec); 489 extern int test_client_verify(int sk, const size_t msg_len, const size_t nr); 490 491 struct tcp_ao_key_counters { 492 uint8_t sndid; 493 uint8_t rcvid; 494 uint64_t pkt_good; 495 uint64_t pkt_bad; 496 }; 497 498 struct tcp_ao_counters { 499 /* per-netns */ 500 uint64_t netns_ao_good; 501 uint64_t netns_ao_bad; 502 uint64_t netns_ao_key_not_found; 503 uint64_t netns_ao_required; 504 uint64_t netns_ao_dropped_icmp; 505 /* per-socket */ 506 uint64_t ao_info_pkt_good; 507 uint64_t ao_info_pkt_bad; 508 uint64_t ao_info_pkt_key_not_found; 509 uint64_t ao_info_pkt_ao_required; 510 uint64_t ao_info_pkt_dropped_icmp; 511 /* per-key */ 512 size_t nr_keys; 513 struct tcp_ao_key_counters *key_cnts; 514 }; 515 516 struct tcp_counters { 517 struct tcp_ao_counters ao; 518 uint64_t netns_md5_notfound; 519 uint64_t netns_md5_unexpected; 520 uint64_t netns_md5_failure; 521 }; 522 523 extern int test_get_tcp_counters(int sk, struct tcp_counters *out); 524 525 #define TEST_CNT_KEY_GOOD BIT(0) 526 #define TEST_CNT_KEY_BAD BIT(1) 527 #define TEST_CNT_SOCK_GOOD BIT(2) 528 #define TEST_CNT_SOCK_BAD BIT(3) 529 #define TEST_CNT_SOCK_KEY_NOT_FOUND BIT(4) 530 #define TEST_CNT_SOCK_AO_REQUIRED BIT(5) 531 #define TEST_CNT_SOCK_DROPPED_ICMP BIT(6) 532 #define TEST_CNT_NS_GOOD BIT(7) 533 #define TEST_CNT_NS_BAD BIT(8) 534 #define TEST_CNT_NS_KEY_NOT_FOUND BIT(9) 535 #define TEST_CNT_NS_AO_REQUIRED BIT(10) 536 #define TEST_CNT_NS_DROPPED_ICMP BIT(11) 537 #define TEST_CNT_NS_MD5_NOT_FOUND BIT(12) 538 #define TEST_CNT_NS_MD5_UNEXPECTED BIT(13) 539 #define TEST_CNT_NS_MD5_FAILURE BIT(14) 540 typedef uint16_t test_cnt; 541 542 #define _for_each_counter(f) \ 543 do { \ 544 /* per-netns */ \ 545 f(ao.netns_ao_good, TEST_CNT_NS_GOOD); \ 546 f(ao.netns_ao_bad, TEST_CNT_NS_BAD); \ 547 f(ao.netns_ao_key_not_found, TEST_CNT_NS_KEY_NOT_FOUND); \ 548 f(ao.netns_ao_required, TEST_CNT_NS_AO_REQUIRED); \ 549 f(ao.netns_ao_dropped_icmp, TEST_CNT_NS_DROPPED_ICMP); \ 550 /* per-socket */ \ 551 f(ao.ao_info_pkt_good, TEST_CNT_SOCK_GOOD); \ 552 f(ao.ao_info_pkt_bad, TEST_CNT_SOCK_BAD); \ 553 f(ao.ao_info_pkt_key_not_found, TEST_CNT_SOCK_KEY_NOT_FOUND); \ 554 f(ao.ao_info_pkt_ao_required, TEST_CNT_SOCK_AO_REQUIRED); \ 555 f(ao.ao_info_pkt_dropped_icmp, TEST_CNT_SOCK_DROPPED_ICMP); \ 556 /* non-AO */ \ 557 f(netns_md5_notfound, TEST_CNT_NS_MD5_NOT_FOUND); \ 558 f(netns_md5_unexpected, TEST_CNT_NS_MD5_UNEXPECTED); \ 559 f(netns_md5_failure, TEST_CNT_NS_MD5_FAILURE); \ 560 } while (0) 561 562 #define TEST_CNT_AO_GOOD (TEST_CNT_SOCK_GOOD | TEST_CNT_NS_GOOD) 563 #define TEST_CNT_AO_BAD (TEST_CNT_SOCK_BAD | TEST_CNT_NS_BAD) 564 #define TEST_CNT_AO_KEY_NOT_FOUND (TEST_CNT_SOCK_KEY_NOT_FOUND | \ 565 TEST_CNT_NS_KEY_NOT_FOUND) 566 #define TEST_CNT_AO_REQUIRED (TEST_CNT_SOCK_AO_REQUIRED | \ 567 TEST_CNT_NS_AO_REQUIRED) 568 #define TEST_CNT_AO_DROPPED_ICMP (TEST_CNT_SOCK_DROPPED_ICMP | \ 569 TEST_CNT_NS_DROPPED_ICMP) 570 #define TEST_CNT_GOOD (TEST_CNT_KEY_GOOD | TEST_CNT_AO_GOOD) 571 #define TEST_CNT_BAD (TEST_CNT_KEY_BAD | TEST_CNT_AO_BAD) 572 573 extern test_cnt test_cmp_counters(struct tcp_counters *before, 574 struct tcp_counters *after); 575 extern int test_assert_counters_sk(const char *tst_name, 576 struct tcp_counters *before, struct tcp_counters *after, 577 test_cnt expected); 578 extern int test_assert_counters_key(const char *tst_name, 579 struct tcp_ao_counters *before, struct tcp_ao_counters *after, 580 test_cnt expected, int sndid, int rcvid); 581 extern void test_tcp_counters_free(struct tcp_counters *cnts); 582 583 /* 584 * Polling for netns and socket counters during select()/connect() and also 585 * client/server messaging. Instead of constant timeout on underlying select(), 586 * check the counters and return early. This allows to pass the tests where 587 * timeout is expected without waiting for that fixing timeout (tests speed-up). 588 * Previously shorter timeouts were used for tests expecting to time out, 589 * but that leaded to sporadic false positives on counter checks failures, 590 * as one second timeouts aren't enough for TCP retransmit. 591 * 592 * Two sides of the socketpair (client/server) should synchronize failures 593 * using a shared variable *err, so that they can detect the other side's 594 * failure. 595 */ 596 extern int test_skpair_wait_poll(int sk, bool write, test_cnt cond, 597 volatile int *err); 598 extern int _test_skpair_connect_poll(int sk, const char *device, 599 void *addr, size_t addr_sz, 600 test_cnt cond, volatile int *err); 601 static inline int test_skpair_connect_poll(int sk, const union tcp_addr taddr, 602 unsigned int port, 603 test_cnt cond, volatile int *err) 604 { 605 sockaddr_af addr; 606 607 tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port)); 608 return _test_skpair_connect_poll(sk, veth_name, 609 (void *)&addr, sizeof(addr), cond, err); 610 } 611 612 extern int test_skpair_client(int sk, const size_t msg_len, const size_t nr, 613 test_cnt cond, volatile int *err); 614 extern int test_skpair_server(int sk, ssize_t quota, 615 test_cnt cond, volatile int *err); 616 617 /* 618 * Frees buffers allocated in test_get_tcp_counters(). 619 * The function doesn't expect new keys or keys removed between calls 620 * to test_get_tcp_counters(). Check key counters manually if they 621 * may change. 622 */ 623 static inline int test_assert_counters(const char *tst_name, 624 struct tcp_counters *before, 625 struct tcp_counters *after, 626 test_cnt expected) 627 { 628 int ret; 629 630 ret = test_assert_counters_sk(tst_name, before, after, expected); 631 if (ret) 632 goto out; 633 ret = test_assert_counters_key(tst_name, &before->ao, &after->ao, 634 expected, -1, -1); 635 out: 636 test_tcp_counters_free(before); 637 test_tcp_counters_free(after); 638 return ret; 639 } 640 641 struct netstat; 642 extern struct netstat *netstat_read(void); 643 extern void netstat_free(struct netstat *ns); 644 extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb); 645 extern uint64_t netstat_get(struct netstat *ns, 646 const char *name, bool *not_found); 647 648 static inline uint64_t netstat_get_one(const char *name, bool *not_found) 649 { 650 struct netstat *ns = netstat_read(); 651 uint64_t ret; 652 653 ret = netstat_get(ns, name, not_found); 654 655 netstat_free(ns); 656 return ret; 657 } 658 659 struct tcp_sock_queue { 660 uint32_t seq; 661 void *buf; 662 }; 663 664 struct tcp_sock_state { 665 struct tcp_info info; 666 struct tcp_repair_window trw; 667 struct tcp_sock_queue out; 668 int outq_len; /* output queue size (not sent + not acked) */ 669 int outq_nsd_len; /* output queue size (not sent only) */ 670 struct tcp_sock_queue in; 671 int inq_len; 672 int mss; 673 int timestamp; 674 }; 675 676 extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state, 677 void *addr, size_t addr_size); 678 static inline void test_sock_checkpoint(int sk, struct tcp_sock_state *state, 679 sockaddr_af *saddr) 680 { 681 __test_sock_checkpoint(sk, state, saddr, sizeof(*saddr)); 682 } 683 extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state); 684 extern void __test_sock_restore(int sk, const char *device, 685 struct tcp_sock_state *state, 686 void *saddr, void *daddr, size_t addr_size); 687 static inline void test_sock_restore(int sk, struct tcp_sock_state *state, 688 sockaddr_af *saddr, 689 const union tcp_addr daddr, 690 unsigned int dport) 691 { 692 sockaddr_af addr; 693 694 tcp_addr_to_sockaddr_in(&addr, &daddr, htons(dport)); 695 __test_sock_restore(sk, veth_name, state, saddr, &addr, sizeof(addr)); 696 } 697 extern void test_ao_restore(int sk, struct tcp_ao_repair *state); 698 extern void test_sock_state_free(struct tcp_sock_state *state); 699 extern void test_enable_repair(int sk); 700 extern void test_disable_repair(int sk); 701 extern void test_kill_sk(int sk); 702 static inline int test_add_repaired_key(int sk, 703 const char *key, uint8_t keyflags, 704 union tcp_addr in_addr, uint8_t prefix, 705 uint8_t sndid, uint8_t rcvid) 706 { 707 struct tcp_ao_add tmp = {}; 708 int err; 709 710 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 711 0, sndid, rcvid); 712 if (err) 713 return err; 714 715 tmp.set_current = 1; 716 tmp.set_rnext = 1; 717 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0) 718 return -errno; 719 720 return test_verify_socket_key(sk, &tmp); 721 } 722 723 #define DEFAULT_FTRACE_BUFFER_KB 10000 724 #define DEFAULT_TRACER_LINES_ARR 200 725 struct test_ftracer; 726 extern uint64_t ns_cookie1, ns_cookie2; 727 728 enum ftracer_op { 729 FTRACER_LINE_DISCARD = 0, 730 FTRACER_LINE_PRESERVE, 731 FTRACER_EXIT, 732 }; 733 734 extern struct test_ftracer *create_ftracer(const char *name, 735 enum ftracer_op (*process_line)(const char *line), 736 void (*destructor)(struct test_ftracer *tracer), 737 bool (*expecting_more)(void), 738 size_t lines_buf_sz, size_t buffer_size_kb); 739 extern int setup_trace_event(struct test_ftracer *tracer, 740 const char *event, const char *filter); 741 extern void destroy_ftracer(struct test_ftracer *tracer); 742 extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer); 743 extern const char **tracer_get_savedlines(struct test_ftracer *tracer); 744 745 enum trace_events { 746 /* TCP_HASH_EVENT */ 747 TCP_HASH_BAD_HEADER = 0, 748 TCP_HASH_MD5_REQUIRED, 749 TCP_HASH_MD5_UNEXPECTED, 750 TCP_HASH_MD5_MISMATCH, 751 TCP_HASH_AO_REQUIRED, 752 /* TCP_AO_EVENT */ 753 TCP_AO_HANDSHAKE_FAILURE, 754 TCP_AO_WRONG_MACLEN, 755 TCP_AO_MISMATCH, 756 TCP_AO_KEY_NOT_FOUND, 757 TCP_AO_RNEXT_REQUEST, 758 /* TCP_AO_EVENT_SK */ 759 TCP_AO_SYNACK_NO_KEY, 760 /* TCP_AO_EVENT_SNE */ 761 TCP_AO_SND_SNE_UPDATE, 762 TCP_AO_RCV_SNE_UPDATE, 763 __MAX_TRACE_EVENTS 764 }; 765 766 extern int __trace_event_expect(enum trace_events type, int family, 767 union tcp_addr src, union tcp_addr dst, 768 int src_port, int dst_port, int L3index, 769 int fin, int syn, int rst, int psh, int ack, 770 int keyid, int rnext, int maclen, int sne); 771 772 static inline void trace_hash_event_expect(enum trace_events type, 773 union tcp_addr src, union tcp_addr dst, 774 int src_port, int dst_port, int L3index, 775 int fin, int syn, int rst, int psh, int ack) 776 { 777 int err; 778 779 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 780 src_port, dst_port, L3index, 781 fin, syn, rst, psh, ack, 782 -1, -1, -1, -1); 783 if (err) 784 test_error("Couldn't add a trace event: %d", err); 785 } 786 787 static inline void trace_ao_event_expect(enum trace_events type, 788 union tcp_addr src, union tcp_addr dst, 789 int src_port, int dst_port, int L3index, 790 int fin, int syn, int rst, int psh, int ack, 791 int keyid, int rnext, int maclen) 792 { 793 int err; 794 795 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 796 src_port, dst_port, L3index, 797 fin, syn, rst, psh, ack, 798 keyid, rnext, maclen, -1); 799 if (err) 800 test_error("Couldn't add a trace event: %d", err); 801 } 802 803 static inline void trace_ao_event_sk_expect(enum trace_events type, 804 union tcp_addr src, union tcp_addr dst, 805 int src_port, int dst_port, 806 int keyid, int rnext) 807 { 808 int err; 809 810 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 811 src_port, dst_port, -1, 812 -1, -1, -1, -1, -1, 813 keyid, rnext, -1, -1); 814 if (err) 815 test_error("Couldn't add a trace event: %d", err); 816 } 817 818 static inline void trace_ao_event_sne_expect(enum trace_events type, 819 union tcp_addr src, union tcp_addr dst, 820 int src_port, int dst_port, int sne) 821 { 822 int err; 823 824 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 825 src_port, dst_port, -1, 826 -1, -1, -1, -1, -1, 827 -1, -1, -1, sne); 828 if (err) 829 test_error("Couldn't add a trace event: %d", err); 830 } 831 832 extern int setup_aolib_ftracer(void); 833 834 #endif /* _AOLIB_H_ */ 835