brintos

brintos / linux-shallow public Read only

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