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