FILE
aolib.h
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/net/tcp_ao/lib/aolib.h
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 */ 33extern void __test_msg(const char *buf); 34extern void __test_ok(const char *buf); 35extern void __test_fail(const char *buf); 36extern void __test_xfail(const char *buf); 37extern void __test_error(const char *buf); 38extern void __test_skip(const char *buf); 39 40static 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 66static __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 78static __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, ...) \ 108do { \ 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, ...) \ 118do { \ 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 130enum 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}; 140typedef enum test_fault fault_t; 141 142enum 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}; 151extern bool kernel_config_has(enum test_needs_kconfig k); 152extern const char *tests_skip_reason[__KCONFIG_LAST__]; 153static 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 162union tcp_addr { 163 struct in_addr a4; 164 struct in6_addr a6; 165}; 166 167typedef void *(*thread_fn)(void *); 168extern void test_failed(void); 169extern 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 173static 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} 187extern void test_add_destructor(void (*d)(void)); 188extern void test_init_ftrace(int nsfd1, int nsfd2); 189extern 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 196extern void test_set_optmem(size_t value); 197extern size_t test_get_optmem(void); 198 199extern const struct sockaddr_in6 addr_any6; 200extern 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 224static 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 238static 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 256static 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} 262extern void synchronize_threads(void); 263extern void switch_ns(int fd); 264extern int switch_save_ns(int fd); 265extern void switch_close_ns(int fd); 266 267extern __thread union tcp_addr this_ip_addr; 268extern __thread union tcp_addr this_ip_dest; 269extern int test_family; 270 271extern void randomize_buffer(void *buf, size_t buflen); 272extern __printf(3, 4) int test_echo(const char *fname, bool append, 273 const char *fmt, ...); 274 275extern int open_netns(void); 276extern int unshare_open_netns(void); 277extern const char veth_name[]; 278extern int add_veth(const char *name, int nsfda, int nsfdb); 279extern int add_vrf(const char *name, uint32_t tabid, int ifindex, int nsfd); 280extern int ip_addr_add(const char *intf, int family, 281 union tcp_addr addr, uint8_t prefix); 282extern int ip_route_add(const char *intf, int family, 283 union tcp_addr src, union tcp_addr dst); 284extern int ip_route_add_vrf(const char *intf, int family, 285 union tcp_addr src, union tcp_addr dst, 286 uint8_t vrf); 287extern int link_set_up(const char *intf); 288 289extern const unsigned int test_server_port; 290extern int test_wait_fd(int sk, time_t sec, bool write); 291extern int __test_connect_socket(int sk, const char *device, 292 void *addr, size_t addr_sz, bool async); 293extern int __test_listen_socket(int backlog, void *addr, size_t addr_sz); 294 295static 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 340static 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 350static 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 356extern int __test_set_md5(int sk, void *addr, size_t addr_sz, 357 uint8_t prefix, int vrf, const char *password); 358static 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 371extern 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 377static 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 392static 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 405extern 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); 408extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out); 409extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in); 410extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a, 411 const struct tcp_ao_getsockopt *b); 412extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a, 413 const struct tcp_ao_info_opt *b); 414 415static 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 428static 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 448static 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 455static 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 467static 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 486extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec); 487extern int test_client_verify(int sk, const size_t msg_len, const size_t nr); 488 489struct tcp_ao_key_counters { 490 uint8_t sndid; 491 uint8_t rcvid; 492 uint64_t pkt_good; 493 uint64_t pkt_bad; 494}; 495 496struct 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 514struct 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 521extern 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) 538typedef uint16_t test_cnt; 539 540#define _for_each_counter(f) \ 541do { \ 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 571extern test_cnt test_cmp_counters(struct tcp_counters *before, 572 struct tcp_counters *after); 573extern int test_assert_counters_sk(const char *tst_name, 574 struct tcp_counters *before, struct tcp_counters *after, 575 test_cnt expected); 576extern 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); 579extern 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 */ 594extern int test_skpair_wait_poll(int sk, bool write, test_cnt cond, 595 volatile int *err); 596extern int _test_skpair_connect_poll(int sk, const char *device, 597 void *addr, size_t addr_sz, 598 test_cnt cond, volatile int *err); 599static 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 610extern int test_skpair_client(int sk, const size_t msg_len, const size_t nr, 611 test_cnt cond, volatile int *err); 612extern 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 */ 621static 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); 633out: 634 test_tcp_counters_free(before); 635 test_tcp_counters_free(after); 636 return ret; 637} 638 639struct netstat; 640extern struct netstat *netstat_read(void); 641extern void netstat_free(struct netstat *ns); 642extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb); 643extern uint64_t netstat_get(struct netstat *ns, 644 const char *name, bool *not_found); 645 646static 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 657struct tcp_sock_queue { 658 uint32_t seq; 659 void *buf; 660}; 661 662struct 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 674extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state, 675 void *addr, size_t addr_size); 676static 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} 681extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state); 682extern void __test_sock_restore(int sk, const char *device, 683 struct tcp_sock_state *state, 684 void *saddr, void *daddr, size_t addr_size); 685static 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} 695extern void test_ao_restore(int sk, struct tcp_ao_repair *state); 696extern void test_sock_state_free(struct tcp_sock_state *state); 697extern void test_enable_repair(int sk); 698extern void test_disable_repair(int sk); 699extern void test_kill_sk(int sk); 700static 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 723struct test_ftracer; 724extern uint64_t ns_cookie1, ns_cookie2; 725 726enum ftracer_op { 727 FTRACER_LINE_DISCARD = 0, 728 FTRACER_LINE_PRESERVE, 729 FTRACER_EXIT, 730}; 731 732extern 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); 737extern int setup_trace_event(struct test_ftracer *tracer, 738 const char *event, const char *filter); 739extern void destroy_ftracer(struct test_ftracer *tracer); 740extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer); 741extern const char **tracer_get_savedlines(struct test_ftracer *tracer); 742 743enum 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 764extern 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 770static 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 785static 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 801static 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 816static 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 830extern int setup_aolib_ftracer(void); 831 832#endif /* _AOLIB_H_ */
~/
Read-only file preview.