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, time_t timeout); 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 */ 335 #ifndef TEST_RETRANSMIT_SEC 336 #define TEST_RETRANSMIT_SEC 1 337 #endif 338 339 static inline int _test_connect_socket(int sk, const union tcp_addr taddr, 340 unsigned int port, time_t timeout) 341 { 342 sockaddr_af addr; 343 344 tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port)); 345 return __test_connect_socket(sk, veth_name, 346 (void *)&addr, sizeof(addr), timeout); 347 } 348 349 static inline int test_connect_socket(int sk, const union tcp_addr taddr, 350 unsigned int port) 351 { 352 return _test_connect_socket(sk, taddr, port, TEST_TIMEOUT_SEC); 353 } 354 355 extern int __test_set_md5(int sk, void *addr, size_t addr_sz, 356 uint8_t prefix, int vrf, const char *password); 357 static inline int test_set_md5(int sk, const union tcp_addr in_addr, 358 uint8_t prefix, int vrf, const char *password) 359 { 360 sockaddr_af addr; 361 362 if (prefix > DEFAULT_TEST_PREFIX) 363 prefix = DEFAULT_TEST_PREFIX; 364 365 tcp_addr_to_sockaddr_in(&addr, &in_addr, 0); 366 return __test_set_md5(sk, (void *)&addr, sizeof(addr), 367 prefix, vrf, password); 368 } 369 370 extern int test_prepare_key_sockaddr(struct tcp_ao_add *ao, const char *alg, 371 void *addr, size_t addr_sz, bool set_current, bool set_rnext, 372 uint8_t prefix, uint8_t vrf, 373 uint8_t sndid, uint8_t rcvid, uint8_t maclen, 374 uint8_t keyflags, uint8_t keylen, const char *key); 375 376 static inline int test_prepare_key(struct tcp_ao_add *ao, 377 const char *alg, union tcp_addr taddr, 378 bool set_current, bool set_rnext, 379 uint8_t prefix, uint8_t vrf, 380 uint8_t sndid, uint8_t rcvid, uint8_t maclen, 381 uint8_t keyflags, uint8_t keylen, const char *key) 382 { 383 sockaddr_af addr; 384 385 tcp_addr_to_sockaddr_in(&addr, &taddr, 0); 386 return test_prepare_key_sockaddr(ao, alg, (void *)&addr, sizeof(addr), 387 set_current, set_rnext, prefix, vrf, sndid, rcvid, 388 maclen, keyflags, keylen, key); 389 } 390 391 static inline int test_prepare_def_key(struct tcp_ao_add *ao, 392 const char *key, uint8_t keyflags, 393 union tcp_addr in_addr, uint8_t prefix, uint8_t vrf, 394 uint8_t sndid, uint8_t rcvid) 395 { 396 if (prefix > DEFAULT_TEST_PREFIX) 397 prefix = DEFAULT_TEST_PREFIX; 398 399 return test_prepare_key(ao, DEFAULT_TEST_ALGO, in_addr, false, false, 400 prefix, vrf, sndid, rcvid, 0, keyflags, 401 strlen(key), key); 402 } 403 404 extern int test_get_one_ao(int sk, struct tcp_ao_getsockopt *out, 405 void *addr, size_t addr_sz, 406 uint8_t prefix, uint8_t sndid, uint8_t rcvid); 407 extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out); 408 extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in); 409 extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a, 410 const struct tcp_ao_getsockopt *b); 411 extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a, 412 const struct tcp_ao_info_opt *b); 413 414 static inline int test_verify_socket_key(int sk, struct tcp_ao_add *key) 415 { 416 struct tcp_ao_getsockopt key2 = {}; 417 int err; 418 419 err = test_get_one_ao(sk, &key2, &key->addr, sizeof(key->addr), 420 key->prefix, key->sndid, key->rcvid); 421 if (err) 422 return err; 423 424 return test_cmp_getsockopt_setsockopt(key, &key2); 425 } 426 427 static inline int test_add_key_vrf(int sk, 428 const char *key, uint8_t keyflags, 429 union tcp_addr in_addr, uint8_t prefix, 430 uint8_t vrf, uint8_t sndid, uint8_t rcvid) 431 { 432 struct tcp_ao_add tmp = {}; 433 int err; 434 435 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 436 vrf, sndid, rcvid); 437 if (err) 438 return err; 439 440 err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)); 441 if (err < 0) 442 return -errno; 443 444 return test_verify_socket_key(sk, &tmp); 445 } 446 447 static inline int test_add_key(int sk, const char *key, 448 union tcp_addr in_addr, uint8_t prefix, 449 uint8_t sndid, uint8_t rcvid) 450 { 451 return test_add_key_vrf(sk, key, 0, in_addr, prefix, 0, sndid, rcvid); 452 } 453 454 static inline int test_verify_socket_ao(int sk, struct tcp_ao_info_opt *ao) 455 { 456 struct tcp_ao_info_opt ao2 = {}; 457 int err; 458 459 err = test_get_ao_info(sk, &ao2); 460 if (err) 461 return err; 462 463 return test_cmp_getsockopt_setsockopt_ao(ao, &ao2); 464 } 465 466 static inline int test_set_ao_flags(int sk, bool ao_required, bool accept_icmps) 467 { 468 struct tcp_ao_info_opt ao = {}; 469 int err; 470 471 err = test_get_ao_info(sk, &ao); 472 /* Maybe ao_info wasn't allocated yet */ 473 if (err && err != -ENOENT) 474 return err; 475 476 ao.ao_required = !!ao_required; 477 ao.accept_icmps = !!accept_icmps; 478 err = test_set_ao_info(sk, &ao); 479 if (err) 480 return err; 481 482 return test_verify_socket_ao(sk, &ao); 483 } 484 485 extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec); 486 extern ssize_t test_client_loop(int sk, char *buf, size_t buf_sz, 487 const size_t msg_len, time_t timeout_sec); 488 extern int test_client_verify(int sk, const size_t msg_len, const size_t nr, 489 time_t timeout_sec); 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 extern int test_get_tcp_ao_counters(int sk, struct tcp_ao_counters *out); 516 517 #define TEST_CNT_KEY_GOOD BIT(0) 518 #define TEST_CNT_KEY_BAD BIT(1) 519 #define TEST_CNT_SOCK_GOOD BIT(2) 520 #define TEST_CNT_SOCK_BAD BIT(3) 521 #define TEST_CNT_SOCK_KEY_NOT_FOUND BIT(4) 522 #define TEST_CNT_SOCK_AO_REQUIRED BIT(5) 523 #define TEST_CNT_SOCK_DROPPED_ICMP BIT(6) 524 #define TEST_CNT_NS_GOOD BIT(7) 525 #define TEST_CNT_NS_BAD BIT(8) 526 #define TEST_CNT_NS_KEY_NOT_FOUND BIT(9) 527 #define TEST_CNT_NS_AO_REQUIRED BIT(10) 528 #define TEST_CNT_NS_DROPPED_ICMP BIT(11) 529 typedef uint16_t test_cnt; 530 531 #define TEST_CNT_AO_GOOD (TEST_CNT_SOCK_GOOD | TEST_CNT_NS_GOOD) 532 #define TEST_CNT_AO_BAD (TEST_CNT_SOCK_BAD | TEST_CNT_NS_BAD) 533 #define TEST_CNT_AO_KEY_NOT_FOUND (TEST_CNT_SOCK_KEY_NOT_FOUND | \ 534 TEST_CNT_NS_KEY_NOT_FOUND) 535 #define TEST_CNT_AO_REQUIRED (TEST_CNT_SOCK_AO_REQUIRED | \ 536 TEST_CNT_NS_AO_REQUIRED) 537 #define TEST_CNT_AO_DROPPED_ICMP (TEST_CNT_SOCK_DROPPED_ICMP | \ 538 TEST_CNT_NS_DROPPED_ICMP) 539 #define TEST_CNT_GOOD (TEST_CNT_KEY_GOOD | TEST_CNT_AO_GOOD) 540 #define TEST_CNT_BAD (TEST_CNT_KEY_BAD | TEST_CNT_AO_BAD) 541 542 extern int __test_tcp_ao_counters_cmp(const char *tst_name, 543 struct tcp_ao_counters *before, struct tcp_ao_counters *after, 544 test_cnt expected); 545 extern int test_tcp_ao_key_counters_cmp(const char *tst_name, 546 struct tcp_ao_counters *before, struct tcp_ao_counters *after, 547 test_cnt expected, int sndid, int rcvid); 548 extern void test_tcp_ao_counters_free(struct tcp_ao_counters *cnts); 549 /* 550 * Frees buffers allocated in test_get_tcp_ao_counters(). 551 * The function doesn't expect new keys or keys removed between calls 552 * to test_get_tcp_ao_counters(). Check key counters manually if they 553 * may change. 554 */ 555 static inline int test_tcp_ao_counters_cmp(const char *tst_name, 556 struct tcp_ao_counters *before, 557 struct tcp_ao_counters *after, 558 test_cnt expected) 559 { 560 int ret; 561 562 ret = __test_tcp_ao_counters_cmp(tst_name, before, after, expected); 563 if (ret) 564 goto out; 565 ret = test_tcp_ao_key_counters_cmp(tst_name, before, after, 566 expected, -1, -1); 567 out: 568 test_tcp_ao_counters_free(before); 569 test_tcp_ao_counters_free(after); 570 return ret; 571 } 572 573 struct netstat; 574 extern struct netstat *netstat_read(void); 575 extern void netstat_free(struct netstat *ns); 576 extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb); 577 extern uint64_t netstat_get(struct netstat *ns, 578 const char *name, bool *not_found); 579 580 static inline uint64_t netstat_get_one(const char *name, bool *not_found) 581 { 582 struct netstat *ns = netstat_read(); 583 uint64_t ret; 584 585 ret = netstat_get(ns, name, not_found); 586 587 netstat_free(ns); 588 return ret; 589 } 590 591 struct tcp_sock_queue { 592 uint32_t seq; 593 void *buf; 594 }; 595 596 struct tcp_sock_state { 597 struct tcp_info info; 598 struct tcp_repair_window trw; 599 struct tcp_sock_queue out; 600 int outq_len; /* output queue size (not sent + not acked) */ 601 int outq_nsd_len; /* output queue size (not sent only) */ 602 struct tcp_sock_queue in; 603 int inq_len; 604 int mss; 605 int timestamp; 606 }; 607 608 extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state, 609 void *addr, size_t addr_size); 610 static inline void test_sock_checkpoint(int sk, struct tcp_sock_state *state, 611 sockaddr_af *saddr) 612 { 613 __test_sock_checkpoint(sk, state, saddr, sizeof(*saddr)); 614 } 615 extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state); 616 extern void __test_sock_restore(int sk, const char *device, 617 struct tcp_sock_state *state, 618 void *saddr, void *daddr, size_t addr_size); 619 static inline void test_sock_restore(int sk, struct tcp_sock_state *state, 620 sockaddr_af *saddr, 621 const union tcp_addr daddr, 622 unsigned int dport) 623 { 624 sockaddr_af addr; 625 626 tcp_addr_to_sockaddr_in(&addr, &daddr, htons(dport)); 627 __test_sock_restore(sk, veth_name, state, saddr, &addr, sizeof(addr)); 628 } 629 extern void test_ao_restore(int sk, struct tcp_ao_repair *state); 630 extern void test_sock_state_free(struct tcp_sock_state *state); 631 extern void test_enable_repair(int sk); 632 extern void test_disable_repair(int sk); 633 extern void test_kill_sk(int sk); 634 static inline int test_add_repaired_key(int sk, 635 const char *key, uint8_t keyflags, 636 union tcp_addr in_addr, uint8_t prefix, 637 uint8_t sndid, uint8_t rcvid) 638 { 639 struct tcp_ao_add tmp = {}; 640 int err; 641 642 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 643 0, sndid, rcvid); 644 if (err) 645 return err; 646 647 tmp.set_current = 1; 648 tmp.set_rnext = 1; 649 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0) 650 return -errno; 651 652 return test_verify_socket_key(sk, &tmp); 653 } 654 655 #define DEFAULT_FTRACE_BUFFER_KB 10000 656 #define DEFAULT_TRACER_LINES_ARR 200 657 struct test_ftracer; 658 extern uint64_t ns_cookie1, ns_cookie2; 659 660 enum ftracer_op { 661 FTRACER_LINE_DISCARD = 0, 662 FTRACER_LINE_PRESERVE, 663 FTRACER_EXIT, 664 }; 665 666 extern struct test_ftracer *create_ftracer(const char *name, 667 enum ftracer_op (*process_line)(const char *line), 668 void (*destructor)(struct test_ftracer *tracer), 669 bool (*expecting_more)(void), 670 size_t lines_buf_sz, size_t buffer_size_kb); 671 extern int setup_trace_event(struct test_ftracer *tracer, 672 const char *event, const char *filter); 673 extern void destroy_ftracer(struct test_ftracer *tracer); 674 extern const size_t tracer_get_savedlines_nr(struct test_ftracer *tracer); 675 extern const char **tracer_get_savedlines(struct test_ftracer *tracer); 676 677 enum trace_events { 678 /* TCP_HASH_EVENT */ 679 TCP_HASH_BAD_HEADER = 0, 680 TCP_HASH_MD5_REQUIRED, 681 TCP_HASH_MD5_UNEXPECTED, 682 TCP_HASH_MD5_MISMATCH, 683 TCP_HASH_AO_REQUIRED, 684 /* TCP_AO_EVENT */ 685 TCP_AO_HANDSHAKE_FAILURE, 686 TCP_AO_WRONG_MACLEN, 687 TCP_AO_MISMATCH, 688 TCP_AO_KEY_NOT_FOUND, 689 TCP_AO_RNEXT_REQUEST, 690 /* TCP_AO_EVENT_SK */ 691 TCP_AO_SYNACK_NO_KEY, 692 /* TCP_AO_EVENT_SNE */ 693 TCP_AO_SND_SNE_UPDATE, 694 TCP_AO_RCV_SNE_UPDATE, 695 __MAX_TRACE_EVENTS 696 }; 697 698 extern int __trace_event_expect(enum trace_events type, int family, 699 union tcp_addr src, union tcp_addr dst, 700 int src_port, int dst_port, int L3index, 701 int fin, int syn, int rst, int psh, int ack, 702 int keyid, int rnext, int maclen, int sne); 703 704 static inline void trace_hash_event_expect(enum trace_events type, 705 union tcp_addr src, union tcp_addr dst, 706 int src_port, int dst_port, int L3index, 707 int fin, int syn, int rst, int psh, int ack) 708 { 709 int err; 710 711 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 712 src_port, dst_port, L3index, 713 fin, syn, rst, psh, ack, 714 -1, -1, -1, -1); 715 if (err) 716 test_error("Couldn't add a trace event: %d", err); 717 } 718 719 static inline void trace_ao_event_expect(enum trace_events type, 720 union tcp_addr src, union tcp_addr dst, 721 int src_port, int dst_port, int L3index, 722 int fin, int syn, int rst, int psh, int ack, 723 int keyid, int rnext, int maclen) 724 { 725 int err; 726 727 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 728 src_port, dst_port, L3index, 729 fin, syn, rst, psh, ack, 730 keyid, rnext, maclen, -1); 731 if (err) 732 test_error("Couldn't add a trace event: %d", err); 733 } 734 735 static inline void trace_ao_event_sk_expect(enum trace_events type, 736 union tcp_addr src, union tcp_addr dst, 737 int src_port, int dst_port, 738 int keyid, int rnext) 739 { 740 int err; 741 742 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 743 src_port, dst_port, -1, 744 -1, -1, -1, -1, -1, 745 keyid, rnext, -1, -1); 746 if (err) 747 test_error("Couldn't add a trace event: %d", err); 748 } 749 750 static inline void trace_ao_event_sne_expect(enum trace_events type, 751 union tcp_addr src, union tcp_addr dst, 752 int src_port, int dst_port, int sne) 753 { 754 int err; 755 756 err = __trace_event_expect(type, TEST_FAMILY, src, dst, 757 src_port, dst_port, -1, 758 -1, -1, -1, -1, -1, 759 -1, -1, -1, sne); 760 if (err) 761 test_error("Couldn't add a trace event: %d", err); 762 } 763 764 extern int setup_aolib_ftracer(void); 765 766 #endif /* _AOLIB_H_ */ 767