File Index
Files and directories
Sign in
FILE

unsigned-md5.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/tcp_ao/unsigned-md5.c C
  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)
  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;
  9static volatile int sk_pair;
 10
 11static union tcp_addr client2;
 12static union tcp_addr client3;
 13
 14static const int test_vrf_ifindex = 200;
 15static const uint8_t test_vrf_tabid = 42;
 16static 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
 37static 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
117out:
118	synchronize_threads(); /* test_kill_sk() */
119	if (sk >= 0)
120		test_kill_sk(sk);
121}
122
123static 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
135static 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
148static void server_vrf_tests(unsigned int *port)
149{
150	setup_vrfs();
151}
152
153static 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
246static 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
264static 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
312out:
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
324static 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
344static 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
367static 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
411static 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
437static 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
494out:
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
500static 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
512static 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
519static 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
555static 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
670static 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
768int main(int argc, char *argv[])
769{
770	test_init(73, server_fn, client_fn);
771	return 0;
772}
~/ Read-only file preview.