1 // SPDX-License-Identifier: GPL-2.0 2 /* Author: Dmitry Safonov <dima@arista.com> */ 3 #include <inttypes.h> 4 #include "aolib.h" 5 6 #define fault(type) (inj == FAULT_ ## type) 7 static const char *md5_password = "Some evil genius, enemy to mankind, must have been the first contriver."; 8 static const char *ao_password = DEFAULT_TEST_PASSWORD; 9 static volatile int sk_pair; 10 11 static union tcp_addr client2; 12 static union tcp_addr client3; 13 14 static const int test_vrf_ifindex = 200; 15 static const uint8_t test_vrf_tabid = 42; 16 static void setup_vrfs(void) 17 { 18 int err; 19 20 if (!kernel_config_has(KCONFIG_NET_VRF)) 21 return; 22 23 err = add_vrf("ksft-vrf", test_vrf_tabid, test_vrf_ifindex, -1); 24 if (err) 25 test_error("Failed to add a VRF: %d", err); 26 27 err = link_set_up("ksft-vrf"); 28 if (err) 29 test_error("Failed to bring up a VRF"); 30 31 err = ip_route_add_vrf(veth_name, TEST_FAMILY, 32 this_ip_addr, this_ip_dest, test_vrf_tabid); 33 if (err) 34 test_error("Failed to add a route to VRF: %d", err); 35 } 36 37 static void try_accept(const char *tst_name, unsigned int port, 38 union tcp_addr *md5_addr, uint8_t md5_prefix, 39 union tcp_addr *ao_addr, uint8_t ao_prefix, 40 bool set_ao_required, 41 uint8_t sndid, uint8_t rcvid, uint8_t vrf, 42 const char *cnt_name, test_cnt cnt_expected, 43 int needs_tcp_md5, fault_t inj) 44 { 45 struct tcp_counters cnt1, cnt2; 46 uint64_t before_cnt = 0, after_cnt = 0; /* silence GCC */ 47 test_cnt poll_cnt = (cnt_expected == TEST_CNT_GOOD) ? 0 : cnt_expected; 48 int lsk, err, sk = -1; 49 50 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5)) 51 return; 52 53 lsk = test_listen_socket(this_ip_addr, port, 1); 54 55 if (md5_addr && test_set_md5(lsk, *md5_addr, md5_prefix, -1, md5_password)) 56 test_error("setsockopt(TCP_MD5SIG_EXT)"); 57 58 if (ao_addr && test_add_key(lsk, ao_password, 59 *ao_addr, ao_prefix, sndid, rcvid)) 60 test_error("setsockopt(TCP_AO_ADD_KEY)"); 61 62 if (set_ao_required && test_set_ao_flags(lsk, true, false)) 63 test_error("setsockopt(TCP_AO_INFO)"); 64 65 if (cnt_name) 66 before_cnt = netstat_get_one(cnt_name, NULL); 67 if (ao_addr && test_get_tcp_counters(lsk, &cnt1)) 68 test_error("test_get_tcp_counters()"); 69 70 synchronize_threads(); /* preparations done */ 71 72 err = test_skpair_wait_poll(lsk, 0, poll_cnt, &sk_pair); 73 synchronize_threads(); /* connect()/accept() timeouts */ 74 if (err == -ETIMEDOUT) { 75 sk_pair = err; 76 if (!fault(TIMEOUT)) 77 test_fail("%s: timed out for accept()", tst_name); 78 } else if (err == -EKEYREJECTED) { 79 if (!fault(KEYREJECT)) 80 test_fail("%s: key was rejected", tst_name); 81 } else if (err < 0) { 82 test_error("test_skpair_wait_poll()"); 83 } else { 84 if (fault(TIMEOUT)) 85 test_fail("%s: ready to accept", tst_name); 86 87 sk = accept(lsk, NULL, NULL); 88 if (sk < 0) { 89 test_error("accept()"); 90 } else { 91 if (fault(TIMEOUT)) 92 test_fail("%s: accepted", tst_name); 93 } 94 } 95 96 if (ao_addr && test_get_tcp_counters(lsk, &cnt2)) 97 test_error("test_get_tcp_counters()"); 98 close(lsk); 99 100 if (!cnt_name) { 101 test_ok("%s: no counter checks", tst_name); 102 goto out; 103 } 104 105 after_cnt = netstat_get_one(cnt_name, NULL); 106 107 if (after_cnt <= before_cnt) { 108 test_fail("%s: %s counter did not increase: %" PRIu64 " <= %" PRIu64, 109 tst_name, cnt_name, after_cnt, before_cnt); 110 } else { 111 test_ok("%s: counter %s increased %" PRIu64 " => %" PRIu64, 112 tst_name, cnt_name, before_cnt, after_cnt); 113 } 114 if (ao_addr) 115 test_assert_counters(tst_name, &cnt1, &cnt2, cnt_expected); 116 117 out: 118 synchronize_threads(); /* test_kill_sk() */ 119 if (sk >= 0) 120 test_kill_sk(sk); 121 } 122 123 static void server_add_routes(void) 124 { 125 int family = TEST_FAMILY; 126 127 synchronize_threads(); /* client_add_ips() */ 128 129 if (ip_route_add(veth_name, family, this_ip_addr, client2)) 130 test_error("Failed to add route"); 131 if (ip_route_add(veth_name, family, this_ip_addr, client3)) 132 test_error("Failed to add route"); 133 } 134 135 static void server_add_fail_tests(unsigned int *port) 136 { 137 union tcp_addr addr_any = {}; 138 139 try_accept("TCP-AO established: add TCP-MD5 key", (*port)++, NULL, 0, 140 &addr_any, 0, 0, 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD, 141 1, 0); 142 try_accept("TCP-MD5 established: add TCP-AO key", (*port)++, &addr_any, 143 0, NULL, 0, 0, 0, 0, 0, NULL, 0, 1, 0); 144 try_accept("non-signed established: add TCP-AO key", (*port)++, NULL, 0, 145 NULL, 0, 0, 0, 0, 0, "CurrEstab", 0, 0, 0); 146 } 147 148 static void server_vrf_tests(unsigned int *port) 149 { 150 setup_vrfs(); 151 } 152 153 static void *server_fn(void *arg) 154 { 155 unsigned int port = test_server_port; 156 union tcp_addr addr_any = {}; 157 158 server_add_routes(); 159 160 try_accept("[server] AO server (INADDR_ANY): AO client", port++, NULL, 0, 161 &addr_any, 0, 0, 100, 100, 0, "TCPAOGood", 162 TEST_CNT_GOOD, 0, 0); 163 try_accept("[server] AO server (INADDR_ANY): MD5 client", port++, NULL, 0, 164 &addr_any, 0, 0, 100, 100, 0, "TCPMD5Unexpected", 165 TEST_CNT_NS_MD5_UNEXPECTED, 1, FAULT_TIMEOUT); 166 try_accept("[server] AO server (INADDR_ANY): no sign client", port++, NULL, 0, 167 &addr_any, 0, 0, 100, 100, 0, "TCPAORequired", 168 TEST_CNT_AO_REQUIRED, 0, FAULT_TIMEOUT); 169 try_accept("[server] AO server (AO_REQUIRED): AO client", port++, NULL, 0, 170 &this_ip_dest, TEST_PREFIX, true, 171 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD, 0, 0); 172 try_accept("[server] AO server (AO_REQUIRED): unsigned client", port++, NULL, 0, 173 &this_ip_dest, TEST_PREFIX, true, 174 100, 100, 0, "TCPAORequired", 175 TEST_CNT_AO_REQUIRED, 0, FAULT_TIMEOUT); 176 177 try_accept("[server] MD5 server (INADDR_ANY): AO client", port++, &addr_any, 0, 178 NULL, 0, 0, 0, 0, 0, "TCPAOKeyNotFound", 179 TEST_CNT_NS_KEY_NOT_FOUND, 1, FAULT_TIMEOUT); 180 try_accept("[server] MD5 server (INADDR_ANY): MD5 client", port++, &addr_any, 0, 181 NULL, 0, 0, 0, 0, 0, NULL, 0, 1, 0); 182 try_accept("[server] MD5 server (INADDR_ANY): no sign client", port++, &addr_any, 183 0, NULL, 0, 0, 0, 0, 0, "TCPMD5NotFound", 184 TEST_CNT_NS_MD5_NOT_FOUND, 1, FAULT_TIMEOUT); 185 186 try_accept("[server] no sign server: AO client", port++, NULL, 0, 187 NULL, 0, 0, 0, 0, 0, "TCPAOKeyNotFound", 188 TEST_CNT_NS_KEY_NOT_FOUND, 0, FAULT_TIMEOUT); 189 try_accept("[server] no sign server: MD5 client", port++, NULL, 0, 190 NULL, 0, 0, 0, 0, 0, "TCPMD5Unexpected", 191 TEST_CNT_NS_MD5_UNEXPECTED, 1, FAULT_TIMEOUT); 192 try_accept("[server] no sign server: no sign client", port++, NULL, 0, 193 NULL, 0, 0, 0, 0, 0, "CurrEstab", 0, 0, 0); 194 195 try_accept("[server] AO+MD5 server: AO client (matching)", port++, 196 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 197 100, 100, 0, "TCPAOGood", TEST_CNT_GOOD, 1, 0); 198 try_accept("[server] AO+MD5 server: AO client (misconfig, matching MD5)", port++, 199 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 200 100, 100, 0, "TCPAOKeyNotFound", TEST_CNT_AO_KEY_NOT_FOUND, 201 1, FAULT_TIMEOUT); 202 try_accept("[server] AO+MD5 server: AO client (misconfig, non-matching)", port++, 203 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 204 100, 100, 0, "TCPAOKeyNotFound", TEST_CNT_AO_KEY_NOT_FOUND, 205 1, FAULT_TIMEOUT); 206 try_accept("[server] AO+MD5 server: MD5 client (matching)", port++, 207 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 208 100, 100, 0, NULL, 0, 1, 0); 209 try_accept("[server] AO+MD5 server: MD5 client (misconfig, matching AO)", port++, 210 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 211 100, 100, 0, "TCPMD5Unexpected", 212 TEST_CNT_NS_MD5_UNEXPECTED, 1, FAULT_TIMEOUT); 213 try_accept("[server] AO+MD5 server: MD5 client (misconfig, non-matching)", port++, 214 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 215 100, 100, 0, "TCPMD5Unexpected", 216 TEST_CNT_NS_MD5_UNEXPECTED, 1, FAULT_TIMEOUT); 217 try_accept("[server] AO+MD5 server: no sign client (unmatched)", port++, 218 &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 219 100, 100, 0, "CurrEstab", 0, 1, 0); 220 try_accept("[server] AO+MD5 server: no sign client (misconfig, matching AO)", 221 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 222 100, 100, 0, "TCPAORequired", 223 TEST_CNT_AO_REQUIRED, 1, FAULT_TIMEOUT); 224 try_accept("[server] AO+MD5 server: no sign client (misconfig, matching MD5)", 225 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 226 100, 100, 0, "TCPMD5NotFound", 227 TEST_CNT_NS_MD5_NOT_FOUND, 1, FAULT_TIMEOUT); 228 229 /* Key rejected by the other side, failing short through skpair */ 230 try_accept("[server] AO+MD5 server: client with both [TCP-MD5] and TCP-AO keys", 231 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 232 100, 100, 0, NULL, 0, 1, FAULT_KEYREJECT); 233 try_accept("[server] AO+MD5 server: client with both TCP-MD5 and [TCP-AO] keys", 234 port++, &this_ip_dest, TEST_PREFIX, &client2, TEST_PREFIX, 0, 235 100, 100, 0, NULL, 0, 1, FAULT_KEYREJECT); 236 237 server_add_fail_tests(&port); 238 239 server_vrf_tests(&port); 240 241 /* client exits */ 242 synchronize_threads(); 243 return NULL; 244 } 245 246 static int client_bind(int sk, union tcp_addr bind_addr) 247 { 248 #ifdef IPV6_TEST 249 struct sockaddr_in6 addr = { 250 .sin6_family = AF_INET6, 251 .sin6_port = 0, 252 .sin6_addr = bind_addr.a6, 253 }; 254 #else 255 struct sockaddr_in addr = { 256 .sin_family = AF_INET, 257 .sin_port = 0, 258 .sin_addr = bind_addr.a4, 259 }; 260 #endif 261 return bind(sk, &addr, sizeof(addr)); 262 } 263 264 static void try_connect(const char *tst_name, unsigned int port, 265 union tcp_addr *md5_addr, uint8_t md5_prefix, 266 union tcp_addr *ao_addr, uint8_t ao_prefix, 267 uint8_t sndid, uint8_t rcvid, uint8_t vrf, 268 fault_t inj, int needs_tcp_md5, union tcp_addr *bind_addr) 269 { 270 int sk, ret; 271 272 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5)) 273 return; 274 275 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); 276 if (sk < 0) 277 test_error("socket()"); 278 279 if (bind_addr && client_bind(sk, *bind_addr)) 280 test_error("bind()"); 281 282 if (md5_addr && test_set_md5(sk, *md5_addr, md5_prefix, -1, md5_password)) 283 test_error("setsockopt(TCP_MD5SIG_EXT)"); 284 285 if (ao_addr && test_add_key(sk, ao_password, *ao_addr, 286 ao_prefix, sndid, rcvid)) 287 test_error("setsockopt(TCP_AO_ADD_KEY)"); 288 289 synchronize_threads(); /* preparations done */ 290 291 ret = test_skpair_connect_poll(sk, this_ip_dest, port, 0, &sk_pair); 292 synchronize_threads(); /* connect()/accept() timeouts */ 293 if (ret < 0) { 294 sk_pair = ret; 295 if (fault(KEYREJECT) && ret == -EKEYREJECTED) 296 test_ok("%s: connect() was prevented", tst_name); 297 else if (ret == -ETIMEDOUT && fault(TIMEOUT)) 298 test_ok("%s", tst_name); 299 else if (ret == -ECONNREFUSED && 300 (fault(TIMEOUT) || fault(KEYREJECT))) 301 test_ok("%s: refused to connect", tst_name); 302 else 303 test_error("%s: connect() returned %d", tst_name, ret); 304 goto out; 305 } 306 307 if (fault(TIMEOUT) || fault(KEYREJECT)) 308 test_fail("%s: connected", tst_name); 309 else 310 test_ok("%s: connected", tst_name); 311 312 out: 313 synchronize_threads(); /* test_kill_sk() */ 314 if (ret > 0) /* test_skpair_connect_poll() cleans up on failure */ 315 test_kill_sk(sk); 316 } 317 318 #define PREINSTALL_MD5_FIRST BIT(0) 319 #define PREINSTALL_AO BIT(1) 320 #define POSTINSTALL_AO BIT(2) 321 #define PREINSTALL_MD5 BIT(3) 322 #define POSTINSTALL_MD5 BIT(4) 323 324 static int try_add_key_vrf(int sk, union tcp_addr in_addr, uint8_t prefix, 325 int vrf, uint8_t sndid, uint8_t rcvid, 326 bool set_ao_required) 327 { 328 uint8_t keyflags = 0; 329 330 if (vrf >= 0) 331 keyflags |= TCP_AO_KEYF_IFINDEX; 332 else 333 vrf = 0; 334 if (set_ao_required) { 335 int err = test_set_ao_flags(sk, true, 0); 336 337 if (err) 338 return err; 339 } 340 return test_add_key_vrf(sk, ao_password, keyflags, in_addr, prefix, 341 (uint8_t)vrf, sndid, rcvid); 342 } 343 344 static bool test_continue(const char *tst_name, int err, 345 fault_t inj, bool added_ao) 346 { 347 bool expected_to_fail; 348 349 expected_to_fail = fault(PREINSTALL_AO) && added_ao; 350 expected_to_fail |= fault(PREINSTALL_MD5) && !added_ao; 351 352 if (!err) { 353 if (!expected_to_fail) 354 return true; 355 test_fail("%s: setsockopt()s were expected to fail", tst_name); 356 return false; 357 } 358 if (err != -EKEYREJECTED || !expected_to_fail) { 359 test_error("%s: setsockopt(%s) = %d", tst_name, 360 added_ao ? "TCP_AO_ADD_KEY" : "TCP_MD5SIG_EXT", err); 361 return false; 362 } 363 test_ok("%s: prefailed as expected: %m", tst_name); 364 return false; 365 } 366 367 static int open_add(const char *tst_name, unsigned int port, 368 unsigned int strategy, 369 union tcp_addr md5_addr, uint8_t md5_prefix, int md5_vrf, 370 union tcp_addr ao_addr, uint8_t ao_prefix, 371 int ao_vrf, bool set_ao_required, 372 uint8_t sndid, uint8_t rcvid, 373 fault_t inj) 374 { 375 int sk; 376 377 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); 378 if (sk < 0) 379 test_error("socket()"); 380 381 if (client_bind(sk, this_ip_addr)) 382 test_error("bind()"); 383 384 if (strategy & PREINSTALL_MD5_FIRST) { 385 if (test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password)) 386 test_error("setsockopt(TCP_MD5SIG_EXT)"); 387 } 388 389 if (strategy & PREINSTALL_AO) { 390 int err = try_add_key_vrf(sk, ao_addr, ao_prefix, ao_vrf, 391 sndid, rcvid, set_ao_required); 392 393 if (!test_continue(tst_name, err, inj, true)) { 394 close(sk); 395 return -1; 396 } 397 } 398 399 if (strategy & PREINSTALL_MD5) { 400 errno = 0; 401 test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password); 402 if (!test_continue(tst_name, -errno, inj, false)) { 403 close(sk); 404 return -1; 405 } 406 } 407 408 return sk; 409 } 410 411 static void try_to_preadd(const char *tst_name, unsigned int port, 412 unsigned int strategy, 413 union tcp_addr md5_addr, uint8_t md5_prefix, 414 int md5_vrf, 415 union tcp_addr ao_addr, uint8_t ao_prefix, 416 int ao_vrf, bool set_ao_required, 417 uint8_t sndid, uint8_t rcvid, 418 int needs_tcp_md5, int needs_vrf, fault_t inj) 419 { 420 int sk; 421 422 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5)) 423 return; 424 if (needs_vrf && should_skip_test(tst_name, KCONFIG_NET_VRF)) 425 return; 426 427 sk = open_add(tst_name, port, strategy, md5_addr, md5_prefix, md5_vrf, 428 ao_addr, ao_prefix, ao_vrf, set_ao_required, 429 sndid, rcvid, inj); 430 if (sk < 0) 431 return; 432 433 test_ok("%s", tst_name); 434 close(sk); 435 } 436 437 static void try_to_add(const char *tst_name, unsigned int port, 438 unsigned int strategy, 439 union tcp_addr md5_addr, uint8_t md5_prefix, 440 int md5_vrf, 441 union tcp_addr ao_addr, uint8_t ao_prefix, 442 int ao_vrf, uint8_t sndid, uint8_t rcvid, 443 int needs_tcp_md5, fault_t inj) 444 { 445 int sk, ret; 446 447 if (needs_tcp_md5 && should_skip_test(tst_name, KCONFIG_TCP_MD5)) 448 return; 449 450 sk = open_add(tst_name, port, strategy, md5_addr, md5_prefix, md5_vrf, 451 ao_addr, ao_prefix, ao_vrf, 0, sndid, rcvid, inj); 452 if (sk < 0) 453 return; 454 455 synchronize_threads(); /* preparations done */ 456 457 ret = test_skpair_connect_poll(sk, this_ip_dest, port, 0, &sk_pair); 458 459 synchronize_threads(); /* connect()/accept() timeouts */ 460 if (ret < 0) { 461 test_error("%s: connect() returned %d", tst_name, ret); 462 goto out; 463 } 464 465 if (strategy & POSTINSTALL_MD5) { 466 if (test_set_md5(sk, md5_addr, md5_prefix, md5_vrf, md5_password)) { 467 if (fault(POSTINSTALL)) { 468 test_ok("%s: postfailed as expected", tst_name); 469 goto out; 470 } else { 471 test_error("setsockopt(TCP_MD5SIG_EXT)"); 472 } 473 } else if (fault(POSTINSTALL)) { 474 test_fail("%s: post setsockopt() was expected to fail", tst_name); 475 goto out; 476 } 477 } 478 479 if (strategy & POSTINSTALL_AO) { 480 if (try_add_key_vrf(sk, ao_addr, ao_prefix, ao_vrf, 481 sndid, rcvid, 0)) { 482 if (fault(POSTINSTALL)) { 483 test_ok("%s: postfailed as expected", tst_name); 484 goto out; 485 } else { 486 test_error("setsockopt(TCP_AO_ADD_KEY)"); 487 } 488 } else if (fault(POSTINSTALL)) { 489 test_fail("%s: post setsockopt() was expected to fail", tst_name); 490 goto out; 491 } 492 } 493 494 out: 495 synchronize_threads(); /* test_kill_sk() */ 496 if (ret > 0) /* test_skpair_connect_poll() cleans up on failure */ 497 test_kill_sk(sk); 498 } 499 500 static void client_add_ip(union tcp_addr *client, const char *ip) 501 { 502 int err, family = TEST_FAMILY; 503 504 if (inet_pton(family, ip, client) != 1) 505 test_error("Can't convert ip address %s", ip); 506 507 err = ip_addr_add(veth_name, family, *client, TEST_PREFIX); 508 if (err) 509 test_error("Failed to add ip address: %d", err); 510 } 511 512 static void client_add_ips(void) 513 { 514 client_add_ip(&client2, __TEST_CLIENT_IP(2)); 515 client_add_ip(&client3, __TEST_CLIENT_IP(3)); 516 synchronize_threads(); /* server_add_routes() */ 517 } 518 519 static void client_add_fail_tests(unsigned int *port) 520 { 521 try_to_add("TCP-AO established: add TCP-MD5 key", 522 (*port)++, POSTINSTALL_MD5 | PREINSTALL_AO, 523 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0, 524 100, 100, 1, FAULT_POSTINSTALL); 525 try_to_add("TCP-MD5 established: add TCP-AO key", 526 (*port)++, PREINSTALL_MD5 | POSTINSTALL_AO, 527 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0, 528 100, 100, 1, FAULT_POSTINSTALL); 529 try_to_add("non-signed established: add TCP-AO key", 530 (*port)++, POSTINSTALL_AO, 531 this_ip_dest, TEST_PREFIX, -1, this_ip_dest, TEST_PREFIX, 0, 532 100, 100, 0, FAULT_POSTINSTALL); 533 534 try_to_add("TCP-AO key intersects with existing TCP-MD5 key", 535 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 536 this_ip_addr, TEST_PREFIX, -1, this_ip_addr, TEST_PREFIX, -1, 537 100, 100, 1, FAULT_PREINSTALL_AO); 538 try_to_add("TCP-MD5 key intersects with existing TCP-AO key", 539 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 540 this_ip_addr, TEST_PREFIX, -1, this_ip_addr, TEST_PREFIX, -1, 541 100, 100, 1, FAULT_PREINSTALL_MD5); 542 543 try_to_preadd("TCP-MD5 key + TCP-AO required", 544 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 545 this_ip_addr, TEST_PREFIX, -1, 546 this_ip_addr, TEST_PREFIX, -1, true, 547 100, 100, 1, 0, FAULT_PREINSTALL_AO); 548 try_to_preadd("TCP-AO required on socket + TCP-MD5 key", 549 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 550 this_ip_addr, TEST_PREFIX, -1, 551 this_ip_addr, TEST_PREFIX, -1, true, 552 100, 100, 1, 0, FAULT_PREINSTALL_MD5); 553 } 554 555 static void client_vrf_tests(unsigned int *port) 556 { 557 setup_vrfs(); 558 559 /* The following restrictions for setsockopt()s are expected: 560 * 561 * |--------------|-----------------|-------------|-------------| 562 * | | MD5 key without | MD5 key | MD5 key | 563 * | | l3index | l3index=0 | l3index=N | 564 * |--------------|-----------------|-------------|-------------| 565 * | TCP-AO key | | | | 566 * | without | reject | reject | reject | 567 * | l3index | | | | 568 * |--------------|-----------------|-------------|-------------| 569 * | TCP-AO key | | | | 570 * | l3index=0 | reject | reject | allow | 571 * |--------------|-----------------|-------------|-------------| 572 * | TCP-AO key | | | | 573 * | l3index=N | reject | allow | reject | 574 * |--------------|-----------------|-------------|-------------| 575 */ 576 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (no l3index)", 577 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 578 this_ip_addr, TEST_PREFIX, -1, 579 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 580 1, 1, FAULT_PREINSTALL_MD5); 581 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (no l3index)", 582 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 583 this_ip_addr, TEST_PREFIX, -1, 584 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 585 1, 1, FAULT_PREINSTALL_AO); 586 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (l3index=0)", 587 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 588 this_ip_addr, TEST_PREFIX, 0, 589 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 590 1, 1, FAULT_PREINSTALL_MD5); 591 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (no l3index)", 592 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 593 this_ip_addr, TEST_PREFIX, 0, 594 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 595 1, 1, FAULT_PREINSTALL_AO); 596 try_to_preadd("VRF: TCP-AO key (no l3index) + TCP-MD5 key (l3index=N)", 597 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 598 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 599 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 600 1, 1, FAULT_PREINSTALL_MD5); 601 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (no l3index)", 602 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 603 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 604 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 605 1, 1, FAULT_PREINSTALL_AO); 606 607 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (no l3index)", 608 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 609 this_ip_addr, TEST_PREFIX, -1, 610 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 611 1, 1, FAULT_PREINSTALL_MD5); 612 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (l3index=0)", 613 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 614 this_ip_addr, TEST_PREFIX, -1, 615 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 616 1, 1, FAULT_PREINSTALL_AO); 617 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (l3index=0)", 618 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 619 this_ip_addr, TEST_PREFIX, 0, 620 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 621 1, 1, FAULT_PREINSTALL_MD5); 622 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (l3index=0)", 623 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 624 this_ip_addr, TEST_PREFIX, 0, 625 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 626 1, 1, FAULT_PREINSTALL_AO); 627 try_to_preadd("VRF: TCP-AO key (l3index=0) + TCP-MD5 key (l3index=N)", 628 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 629 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 630 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 631 1, 1, 0); 632 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (l3index=0)", 633 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 634 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 635 this_ip_addr, TEST_PREFIX, 0, 0, 100, 100, 636 1, 1, 0); 637 638 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (no l3index)", 639 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 640 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 641 this_ip_addr, TEST_PREFIX, -1, 0, 100, 100, 642 1, 1, FAULT_PREINSTALL_MD5); 643 try_to_preadd("VRF: TCP-MD5 key (no l3index) + TCP-AO key (l3index=N)", 644 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 645 this_ip_addr, TEST_PREFIX, -1, 646 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100, 647 1, 1, FAULT_PREINSTALL_AO); 648 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (l3index=0)", 649 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 650 this_ip_addr, TEST_PREFIX, 0, 651 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100, 652 1, 1, 0); 653 try_to_preadd("VRF: TCP-MD5 key (l3index=0) + TCP-AO key (l3index=N)", 654 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 655 this_ip_addr, TEST_PREFIX, 0, 656 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100, 657 1, 1, 0); 658 try_to_preadd("VRF: TCP-AO key (l3index=N) + TCP-MD5 key (l3index=N)", 659 (*port)++, PREINSTALL_MD5 | PREINSTALL_AO, 660 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 661 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100, 662 1, 1, FAULT_PREINSTALL_MD5); 663 try_to_preadd("VRF: TCP-MD5 key (l3index=N) + TCP-AO key (l3index=N)", 664 (*port)++, PREINSTALL_MD5_FIRST | PREINSTALL_AO, 665 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 666 this_ip_addr, TEST_PREFIX, test_vrf_ifindex, 0, 100, 100, 667 1, 1, FAULT_PREINSTALL_AO); 668 } 669 670 static void *client_fn(void *arg) 671 { 672 unsigned int port = test_server_port; 673 union tcp_addr addr_any = {}; 674 675 client_add_ips(); 676 677 try_connect("AO server (INADDR_ANY): AO client", port++, NULL, 0, 678 &addr_any, 0, 100, 100, 0, 0, 0, &this_ip_addr); 679 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, this_ip_addr, 680 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 681 try_connect("AO server (INADDR_ANY): MD5 client", port++, &addr_any, 0, 682 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr); 683 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, this_ip_addr, 684 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 685 try_connect("AO server (INADDR_ANY): unsigned client", port++, NULL, 0, 686 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &this_ip_addr); 687 try_connect("AO server (AO_REQUIRED): AO client", port++, NULL, 0, 688 &addr_any, 0, 100, 100, 0, 0, 0, &this_ip_addr); 689 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, client2, 690 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 691 try_connect("AO server (AO_REQUIRED): unsigned client", port++, NULL, 0, 692 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &client2); 693 694 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest, 695 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1); 696 try_connect("MD5 server (INADDR_ANY): AO client", port++, NULL, 0, 697 &addr_any, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr); 698 try_connect("MD5 server (INADDR_ANY): MD5 client", port++, &addr_any, 0, 699 NULL, 0, 100, 100, 0, 0, 1, &this_ip_addr); 700 trace_hash_event_expect(TCP_HASH_MD5_REQUIRED, this_ip_addr, 701 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 702 try_connect("MD5 server (INADDR_ANY): no sign client", port++, NULL, 0, 703 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr); 704 705 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest, 706 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1); 707 try_connect("no sign server: AO client", port++, NULL, 0, 708 &addr_any, 0, 100, 100, 0, FAULT_TIMEOUT, 0, &this_ip_addr); 709 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, this_ip_addr, 710 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 711 try_connect("no sign server: MD5 client", port++, &addr_any, 0, 712 NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 1, &this_ip_addr); 713 try_connect("no sign server: no sign client", port++, NULL, 0, 714 NULL, 0, 100, 100, 0, 0, 0, &this_ip_addr); 715 716 try_connect("AO+MD5 server: AO client (matching)", port++, NULL, 0, 717 &addr_any, 0, 100, 100, 0, 0, 1, &client2); 718 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, this_ip_addr, this_ip_dest, 719 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1); 720 try_connect("AO+MD5 server: AO client (misconfig, matching MD5)", 721 port++, NULL, 0, &addr_any, 0, 100, 100, 0, 722 FAULT_TIMEOUT, 1, &this_ip_addr); 723 trace_ao_event_expect(TCP_AO_KEY_NOT_FOUND, client3, this_ip_dest, 724 -1, port, 0, 0, 1, 0, 0, 0, 100, 100, -1); 725 try_connect("AO+MD5 server: AO client (misconfig, non-matching)", 726 port++, NULL, 0, &addr_any, 0, 100, 100, 0, 727 FAULT_TIMEOUT, 1, &client3); 728 try_connect("AO+MD5 server: MD5 client (matching)", port++, &addr_any, 0, 729 NULL, 0, 100, 100, 0, 0, 1, &this_ip_addr); 730 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, client2, 731 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 732 try_connect("AO+MD5 server: MD5 client (misconfig, matching AO)", 733 port++, &addr_any, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 734 1, &client2); 735 trace_hash_event_expect(TCP_HASH_MD5_UNEXPECTED, client3, 736 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 737 try_connect("AO+MD5 server: MD5 client (misconfig, non-matching)", 738 port++, &addr_any, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 739 1, &client3); 740 try_connect("AO+MD5 server: no sign client (unmatched)", 741 port++, NULL, 0, NULL, 0, 100, 100, 0, 0, 1, &client3); 742 trace_hash_event_expect(TCP_HASH_AO_REQUIRED, client2, 743 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 744 try_connect("AO+MD5 server: no sign client (misconfig, matching AO)", 745 port++, NULL, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 746 1, &client2); 747 trace_hash_event_expect(TCP_HASH_MD5_REQUIRED, this_ip_addr, 748 this_ip_dest, -1, port, 0, 0, 1, 0, 0, 0); 749 try_connect("AO+MD5 server: no sign client (misconfig, matching MD5)", 750 port++, NULL, 0, NULL, 0, 100, 100, 0, FAULT_TIMEOUT, 751 1, &this_ip_addr); 752 753 try_connect("AO+MD5 server: client with both [TCP-MD5] and TCP-AO keys", 754 port++, &this_ip_addr, TEST_PREFIX, 755 &client2, TEST_PREFIX, 100, 100, 0, FAULT_KEYREJECT, 756 1, &this_ip_addr); 757 try_connect("AO+MD5 server: client with both TCP-MD5 and [TCP-AO] keys", 758 port++, &this_ip_addr, TEST_PREFIX, 759 &client2, TEST_PREFIX, 100, 100, 0, FAULT_KEYREJECT, 760 1, &client2); 761 762 client_add_fail_tests(&port); 763 client_vrf_tests(&port); 764 765 return NULL; 766 } 767 768 int main(int argc, char *argv[]) 769 { 770 test_init(73, server_fn, client_fn); 771 return 0; 772 } 773