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_LAST__ 148 }; 149 extern bool kernel_config_has(enum test_needs_kconfig k); 150 extern const char *tests_skip_reason[__KCONFIG_LAST__]; 151 static inline bool should_skip_test(const char *tst_name, 152 enum test_needs_kconfig k) 153 { 154 if (kernel_config_has(k)) 155 return false; 156 test_skip("%s: %s", tst_name, tests_skip_reason[k]); 157 return true; 158 } 159 160 union tcp_addr { 161 struct in_addr a4; 162 struct in6_addr a6; 163 }; 164 165 typedef void *(*thread_fn)(void *); 166 extern void test_failed(void); 167 extern void __test_init(unsigned int ntests, int family, unsigned int prefix, 168 union tcp_addr addr1, union tcp_addr addr2, 169 thread_fn peer1, thread_fn peer2); 170 171 static inline void test_init2(unsigned int ntests, 172 thread_fn peer1, thread_fn peer2, 173 int family, unsigned int prefix, 174 const char *addr1, const char *addr2) 175 { 176 union tcp_addr taddr1, taddr2; 177 178 if (inet_pton(family, addr1, &taddr1) != 1) 179 test_error("Can't convert ip address %s", addr1); 180 if (inet_pton(family, addr2, &taddr2) != 1) 181 test_error("Can't convert ip address %s", addr2); 182 183 __test_init(ntests, family, prefix, taddr1, taddr2, peer1, peer2); 184 } 185 extern void test_add_destructor(void (*d)(void)); 186 187 /* To adjust optmem socket limit, approximately estimate a number, 188 * that is bigger than sizeof(struct tcp_ao_key). 189 */ 190 #define KERNEL_TCP_AO_KEY_SZ_ROUND_UP 300 191 192 extern void test_set_optmem(size_t value); 193 extern size_t test_get_optmem(void); 194 195 extern const struct sockaddr_in6 addr_any6; 196 extern const struct sockaddr_in addr_any4; 197 198 #ifdef IPV6_TEST 199 # define __TEST_CLIENT_IP(n) ("2001:db8:" __stringify(n) "::1") 200 # define TEST_CLIENT_IP __TEST_CLIENT_IP(1) 201 # define TEST_WRONG_IP "2001:db8:253::1" 202 # define TEST_SERVER_IP "2001:db8:254::1" 203 # define TEST_NETWORK "2001::" 204 # define TEST_PREFIX 128 205 # define TEST_FAMILY AF_INET6 206 # define SOCKADDR_ANY addr_any6 207 # define sockaddr_af struct sockaddr_in6 208 #else 209 # define __TEST_CLIENT_IP(n) ("10.0." __stringify(n) ".1") 210 # define TEST_CLIENT_IP __TEST_CLIENT_IP(1) 211 # define TEST_WRONG_IP "10.0.253.1" 212 # define TEST_SERVER_IP "10.0.254.1" 213 # define TEST_NETWORK "10.0.0.0" 214 # define TEST_PREFIX 32 215 # define TEST_FAMILY AF_INET 216 # define SOCKADDR_ANY addr_any4 217 # define sockaddr_af struct sockaddr_in 218 #endif 219 220 static inline union tcp_addr gen_tcp_addr(union tcp_addr net, size_t n) 221 { 222 union tcp_addr ret = net; 223 224 #ifdef IPV6_TEST 225 ret.a6.s6_addr32[3] = htonl(n & (BIT(32) - 1)); 226 ret.a6.s6_addr32[2] = htonl((n >> 32) & (BIT(32) - 1)); 227 #else 228 ret.a4.s_addr = htonl(ntohl(net.a4.s_addr) + n); 229 #endif 230 231 return ret; 232 } 233 234 static inline void tcp_addr_to_sockaddr_in(void *dest, 235 const union tcp_addr *src, 236 unsigned int port) 237 { 238 sockaddr_af *out = dest; 239 240 memset(out, 0, sizeof(*out)); 241 #ifdef IPV6_TEST 242 out->sin6_family = AF_INET6; 243 out->sin6_port = port; 244 out->sin6_addr = src->a6; 245 #else 246 out->sin_family = AF_INET; 247 out->sin_port = port; 248 out->sin_addr = src->a4; 249 #endif 250 } 251 252 static inline void test_init(unsigned int ntests, 253 thread_fn peer1, thread_fn peer2) 254 { 255 test_init2(ntests, peer1, peer2, TEST_FAMILY, TEST_PREFIX, 256 TEST_SERVER_IP, TEST_CLIENT_IP); 257 } 258 extern void synchronize_threads(void); 259 extern void switch_ns(int fd); 260 261 extern __thread union tcp_addr this_ip_addr; 262 extern __thread union tcp_addr this_ip_dest; 263 extern int test_family; 264 265 extern void randomize_buffer(void *buf, size_t buflen); 266 extern int open_netns(void); 267 extern int unshare_open_netns(void); 268 extern const char veth_name[]; 269 extern int add_veth(const char *name, int nsfda, int nsfdb); 270 extern int add_vrf(const char *name, uint32_t tabid, int ifindex, int nsfd); 271 extern int ip_addr_add(const char *intf, int family, 272 union tcp_addr addr, uint8_t prefix); 273 extern int ip_route_add(const char *intf, int family, 274 union tcp_addr src, union tcp_addr dst); 275 extern int ip_route_add_vrf(const char *intf, int family, 276 union tcp_addr src, union tcp_addr dst, 277 uint8_t vrf); 278 extern int link_set_up(const char *intf); 279 280 extern const unsigned int test_server_port; 281 extern int test_wait_fd(int sk, time_t sec, bool write); 282 extern int __test_connect_socket(int sk, const char *device, 283 void *addr, size_t addr_sz, time_t timeout); 284 extern int __test_listen_socket(int backlog, void *addr, size_t addr_sz); 285 286 static inline int test_listen_socket(const union tcp_addr taddr, 287 unsigned int port, int backlog) 288 { 289 sockaddr_af addr; 290 291 tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port)); 292 return __test_listen_socket(backlog, (void *)&addr, sizeof(addr)); 293 } 294 295 /* 296 * In order for selftests to work under CONFIG_CRYPTO_FIPS=y, 297 * the password should be loger than 14 bytes, see hmac_setkey() 298 */ 299 #define TEST_TCP_AO_MINKEYLEN 14 300 #define DEFAULT_TEST_PASSWORD "In this hour, I do not believe that any darkness will endure." 301 302 #ifndef DEFAULT_TEST_ALGO 303 #define DEFAULT_TEST_ALGO "cmac(aes128)" 304 #endif 305 306 #ifdef IPV6_TEST 307 #define DEFAULT_TEST_PREFIX 128 308 #else 309 #define DEFAULT_TEST_PREFIX 32 310 #endif 311 312 /* 313 * Timeout on syscalls where failure is not expected. 314 * You may want to rise it if the test machine is very busy. 315 */ 316 #ifndef TEST_TIMEOUT_SEC 317 #define TEST_TIMEOUT_SEC 5 318 #endif 319 320 /* 321 * Timeout on connect() where a failure is expected. 322 * If set to 0 - kernel will try to retransmit SYN number of times, set in 323 * /proc/sys/net/ipv4/tcp_syn_retries 324 * By default set to 1 to make tests pass faster on non-busy machine. 325 */ 326 #ifndef TEST_RETRANSMIT_SEC 327 #define TEST_RETRANSMIT_SEC 1 328 #endif 329 330 static inline int _test_connect_socket(int sk, const union tcp_addr taddr, 331 unsigned int port, time_t timeout) 332 { 333 sockaddr_af addr; 334 335 tcp_addr_to_sockaddr_in(&addr, &taddr, htons(port)); 336 return __test_connect_socket(sk, veth_name, 337 (void *)&addr, sizeof(addr), timeout); 338 } 339 340 static inline int test_connect_socket(int sk, const union tcp_addr taddr, 341 unsigned int port) 342 { 343 return _test_connect_socket(sk, taddr, port, TEST_TIMEOUT_SEC); 344 } 345 346 extern int __test_set_md5(int sk, void *addr, size_t addr_sz, 347 uint8_t prefix, int vrf, const char *password); 348 static inline int test_set_md5(int sk, const union tcp_addr in_addr, 349 uint8_t prefix, int vrf, const char *password) 350 { 351 sockaddr_af addr; 352 353 if (prefix > DEFAULT_TEST_PREFIX) 354 prefix = DEFAULT_TEST_PREFIX; 355 356 tcp_addr_to_sockaddr_in(&addr, &in_addr, 0); 357 return __test_set_md5(sk, (void *)&addr, sizeof(addr), 358 prefix, vrf, password); 359 } 360 361 extern int test_prepare_key_sockaddr(struct tcp_ao_add *ao, const char *alg, 362 void *addr, size_t addr_sz, bool set_current, bool set_rnext, 363 uint8_t prefix, uint8_t vrf, 364 uint8_t sndid, uint8_t rcvid, uint8_t maclen, 365 uint8_t keyflags, uint8_t keylen, const char *key); 366 367 static inline int test_prepare_key(struct tcp_ao_add *ao, 368 const char *alg, union tcp_addr taddr, 369 bool set_current, bool set_rnext, 370 uint8_t prefix, uint8_t vrf, 371 uint8_t sndid, uint8_t rcvid, uint8_t maclen, 372 uint8_t keyflags, uint8_t keylen, const char *key) 373 { 374 sockaddr_af addr; 375 376 tcp_addr_to_sockaddr_in(&addr, &taddr, 0); 377 return test_prepare_key_sockaddr(ao, alg, (void *)&addr, sizeof(addr), 378 set_current, set_rnext, prefix, vrf, sndid, rcvid, 379 maclen, keyflags, keylen, key); 380 } 381 382 static inline int test_prepare_def_key(struct tcp_ao_add *ao, 383 const char *key, uint8_t keyflags, 384 union tcp_addr in_addr, uint8_t prefix, uint8_t vrf, 385 uint8_t sndid, uint8_t rcvid) 386 { 387 if (prefix > DEFAULT_TEST_PREFIX) 388 prefix = DEFAULT_TEST_PREFIX; 389 390 return test_prepare_key(ao, DEFAULT_TEST_ALGO, in_addr, false, false, 391 prefix, vrf, sndid, rcvid, 0, keyflags, 392 strlen(key), key); 393 } 394 395 extern int test_get_one_ao(int sk, struct tcp_ao_getsockopt *out, 396 void *addr, size_t addr_sz, 397 uint8_t prefix, uint8_t sndid, uint8_t rcvid); 398 extern int test_get_ao_info(int sk, struct tcp_ao_info_opt *out); 399 extern int test_set_ao_info(int sk, struct tcp_ao_info_opt *in); 400 extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao_add *a, 401 const struct tcp_ao_getsockopt *b); 402 extern int test_cmp_getsockopt_setsockopt_ao(const struct tcp_ao_info_opt *a, 403 const struct tcp_ao_info_opt *b); 404 405 static inline int test_verify_socket_key(int sk, struct tcp_ao_add *key) 406 { 407 struct tcp_ao_getsockopt key2 = {}; 408 int err; 409 410 err = test_get_one_ao(sk, &key2, &key->addr, sizeof(key->addr), 411 key->prefix, key->sndid, key->rcvid); 412 if (err) 413 return err; 414 415 return test_cmp_getsockopt_setsockopt(key, &key2); 416 } 417 418 static inline int test_add_key_vrf(int sk, 419 const char *key, uint8_t keyflags, 420 union tcp_addr in_addr, uint8_t prefix, 421 uint8_t vrf, uint8_t sndid, uint8_t rcvid) 422 { 423 struct tcp_ao_add tmp = {}; 424 int err; 425 426 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 427 vrf, sndid, rcvid); 428 if (err) 429 return err; 430 431 err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)); 432 if (err < 0) 433 return -errno; 434 435 return test_verify_socket_key(sk, &tmp); 436 } 437 438 static inline int test_add_key(int sk, const char *key, 439 union tcp_addr in_addr, uint8_t prefix, 440 uint8_t sndid, uint8_t rcvid) 441 { 442 return test_add_key_vrf(sk, key, 0, in_addr, prefix, 0, sndid, rcvid); 443 } 444 445 static inline int test_verify_socket_ao(int sk, struct tcp_ao_info_opt *ao) 446 { 447 struct tcp_ao_info_opt ao2 = {}; 448 int err; 449 450 err = test_get_ao_info(sk, &ao2); 451 if (err) 452 return err; 453 454 return test_cmp_getsockopt_setsockopt_ao(ao, &ao2); 455 } 456 457 static inline int test_set_ao_flags(int sk, bool ao_required, bool accept_icmps) 458 { 459 struct tcp_ao_info_opt ao = {}; 460 int err; 461 462 err = test_get_ao_info(sk, &ao); 463 /* Maybe ao_info wasn't allocated yet */ 464 if (err && err != -ENOENT) 465 return err; 466 467 ao.ao_required = !!ao_required; 468 ao.accept_icmps = !!accept_icmps; 469 err = test_set_ao_info(sk, &ao); 470 if (err) 471 return err; 472 473 return test_verify_socket_ao(sk, &ao); 474 } 475 476 extern ssize_t test_server_run(int sk, ssize_t quota, time_t timeout_sec); 477 extern ssize_t test_client_loop(int sk, char *buf, size_t buf_sz, 478 const size_t msg_len, time_t timeout_sec); 479 extern int test_client_verify(int sk, const size_t msg_len, const size_t nr, 480 time_t timeout_sec); 481 482 struct tcp_ao_key_counters { 483 uint8_t sndid; 484 uint8_t rcvid; 485 uint64_t pkt_good; 486 uint64_t pkt_bad; 487 }; 488 489 struct tcp_ao_counters { 490 /* per-netns */ 491 uint64_t netns_ao_good; 492 uint64_t netns_ao_bad; 493 uint64_t netns_ao_key_not_found; 494 uint64_t netns_ao_required; 495 uint64_t netns_ao_dropped_icmp; 496 /* per-socket */ 497 uint64_t ao_info_pkt_good; 498 uint64_t ao_info_pkt_bad; 499 uint64_t ao_info_pkt_key_not_found; 500 uint64_t ao_info_pkt_ao_required; 501 uint64_t ao_info_pkt_dropped_icmp; 502 /* per-key */ 503 size_t nr_keys; 504 struct tcp_ao_key_counters *key_cnts; 505 }; 506 extern int test_get_tcp_ao_counters(int sk, struct tcp_ao_counters *out); 507 508 #define TEST_CNT_KEY_GOOD BIT(0) 509 #define TEST_CNT_KEY_BAD BIT(1) 510 #define TEST_CNT_SOCK_GOOD BIT(2) 511 #define TEST_CNT_SOCK_BAD BIT(3) 512 #define TEST_CNT_SOCK_KEY_NOT_FOUND BIT(4) 513 #define TEST_CNT_SOCK_AO_REQUIRED BIT(5) 514 #define TEST_CNT_SOCK_DROPPED_ICMP BIT(6) 515 #define TEST_CNT_NS_GOOD BIT(7) 516 #define TEST_CNT_NS_BAD BIT(8) 517 #define TEST_CNT_NS_KEY_NOT_FOUND BIT(9) 518 #define TEST_CNT_NS_AO_REQUIRED BIT(10) 519 #define TEST_CNT_NS_DROPPED_ICMP BIT(11) 520 typedef uint16_t test_cnt; 521 522 #define TEST_CNT_AO_GOOD (TEST_CNT_SOCK_GOOD | TEST_CNT_NS_GOOD) 523 #define TEST_CNT_AO_BAD (TEST_CNT_SOCK_BAD | TEST_CNT_NS_BAD) 524 #define TEST_CNT_AO_KEY_NOT_FOUND (TEST_CNT_SOCK_KEY_NOT_FOUND | \ 525 TEST_CNT_NS_KEY_NOT_FOUND) 526 #define TEST_CNT_AO_REQUIRED (TEST_CNT_SOCK_AO_REQUIRED | \ 527 TEST_CNT_NS_AO_REQUIRED) 528 #define TEST_CNT_AO_DROPPED_ICMP (TEST_CNT_SOCK_DROPPED_ICMP | \ 529 TEST_CNT_NS_DROPPED_ICMP) 530 #define TEST_CNT_GOOD (TEST_CNT_KEY_GOOD | TEST_CNT_AO_GOOD) 531 #define TEST_CNT_BAD (TEST_CNT_KEY_BAD | TEST_CNT_AO_BAD) 532 533 extern int __test_tcp_ao_counters_cmp(const char *tst_name, 534 struct tcp_ao_counters *before, struct tcp_ao_counters *after, 535 test_cnt expected); 536 extern int test_tcp_ao_key_counters_cmp(const char *tst_name, 537 struct tcp_ao_counters *before, struct tcp_ao_counters *after, 538 test_cnt expected, int sndid, int rcvid); 539 extern void test_tcp_ao_counters_free(struct tcp_ao_counters *cnts); 540 /* 541 * Frees buffers allocated in test_get_tcp_ao_counters(). 542 * The function doesn't expect new keys or keys removed between calls 543 * to test_get_tcp_ao_counters(). Check key counters manually if they 544 * may change. 545 */ 546 static inline int test_tcp_ao_counters_cmp(const char *tst_name, 547 struct tcp_ao_counters *before, 548 struct tcp_ao_counters *after, 549 test_cnt expected) 550 { 551 int ret; 552 553 ret = __test_tcp_ao_counters_cmp(tst_name, before, after, expected); 554 if (ret) 555 goto out; 556 ret = test_tcp_ao_key_counters_cmp(tst_name, before, after, 557 expected, -1, -1); 558 out: 559 test_tcp_ao_counters_free(before); 560 test_tcp_ao_counters_free(after); 561 return ret; 562 } 563 564 struct netstat; 565 extern struct netstat *netstat_read(void); 566 extern void netstat_free(struct netstat *ns); 567 extern void netstat_print_diff(struct netstat *nsa, struct netstat *nsb); 568 extern uint64_t netstat_get(struct netstat *ns, 569 const char *name, bool *not_found); 570 571 static inline uint64_t netstat_get_one(const char *name, bool *not_found) 572 { 573 struct netstat *ns = netstat_read(); 574 uint64_t ret; 575 576 ret = netstat_get(ns, name, not_found); 577 578 netstat_free(ns); 579 return ret; 580 } 581 582 struct tcp_sock_queue { 583 uint32_t seq; 584 void *buf; 585 }; 586 587 struct tcp_sock_state { 588 struct tcp_info info; 589 struct tcp_repair_window trw; 590 struct tcp_sock_queue out; 591 int outq_len; /* output queue size (not sent + not acked) */ 592 int outq_nsd_len; /* output queue size (not sent only) */ 593 struct tcp_sock_queue in; 594 int inq_len; 595 int mss; 596 int timestamp; 597 }; 598 599 extern void __test_sock_checkpoint(int sk, struct tcp_sock_state *state, 600 void *addr, size_t addr_size); 601 static inline void test_sock_checkpoint(int sk, struct tcp_sock_state *state, 602 sockaddr_af *saddr) 603 { 604 __test_sock_checkpoint(sk, state, saddr, sizeof(*saddr)); 605 } 606 extern void test_ao_checkpoint(int sk, struct tcp_ao_repair *state); 607 extern void __test_sock_restore(int sk, const char *device, 608 struct tcp_sock_state *state, 609 void *saddr, void *daddr, size_t addr_size); 610 static inline void test_sock_restore(int sk, struct tcp_sock_state *state, 611 sockaddr_af *saddr, 612 const union tcp_addr daddr, 613 unsigned int dport) 614 { 615 sockaddr_af addr; 616 617 tcp_addr_to_sockaddr_in(&addr, &daddr, htons(dport)); 618 __test_sock_restore(sk, veth_name, state, saddr, &addr, sizeof(addr)); 619 } 620 extern void test_ao_restore(int sk, struct tcp_ao_repair *state); 621 extern void test_sock_state_free(struct tcp_sock_state *state); 622 extern void test_enable_repair(int sk); 623 extern void test_disable_repair(int sk); 624 extern void test_kill_sk(int sk); 625 static inline int test_add_repaired_key(int sk, 626 const char *key, uint8_t keyflags, 627 union tcp_addr in_addr, uint8_t prefix, 628 uint8_t sndid, uint8_t rcvid) 629 { 630 struct tcp_ao_add tmp = {}; 631 int err; 632 633 err = test_prepare_def_key(&tmp, key, keyflags, in_addr, prefix, 634 0, sndid, rcvid); 635 if (err) 636 return err; 637 638 tmp.set_current = 1; 639 tmp.set_rnext = 1; 640 if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0) 641 return -errno; 642 643 return test_verify_socket_key(sk, &tmp); 644 } 645 646 #endif /* _AOLIB_H_ */ 647