xref: /linux/tools/testing/selftests/net/tcp_ao/setsockopt-closed.c (revision 5a558f369ef89c6fd8170ee1137274fcc08517ae)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dmitry Safonov <dima@arista.com> */
3 #include <inttypes.h>
4 #include "../../../../include/linux/kernel.h"
5 #include "aolib.h"
6 
7 static union tcp_addr tcp_md5_client;
8 
9 static int test_port = 7788;
10 static void make_listen(int sk)
11 {
12 	sockaddr_af addr;
13 
14 	tcp_addr_to_sockaddr_in(&addr, &this_ip_addr, htons(test_port++));
15 	if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0)
16 		test_error("bind()");
17 	if (listen(sk, 1))
18 		test_error("listen()");
19 }
20 
21 static void test_vefify_ao_info(int sk, struct tcp_ao_info_opt *info,
22 				const char *tst)
23 {
24 	struct tcp_ao_info_opt tmp = {};
25 	socklen_t len = sizeof(tmp);
26 
27 	if (getsockopt(sk, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
28 		test_error("getsockopt(TCP_AO_INFO) failed");
29 
30 #define __cmp_ao(member)							\
31 do {										\
32 	if (info->member != tmp.member) {					\
33 		test_fail("%s: getsockopt(): " __stringify(member) " %zu != %zu",	\
34 			  tst, (size_t)info->member, (size_t)tmp.member);	\
35 		return;								\
36 	}									\
37 } while(0)
38 	if (info->set_current)
39 		__cmp_ao(current_key);
40 	if (info->set_rnext)
41 		__cmp_ao(rnext);
42 	if (info->set_counters) {
43 		__cmp_ao(pkt_good);
44 		__cmp_ao(pkt_bad);
45 		__cmp_ao(pkt_key_not_found);
46 		__cmp_ao(pkt_ao_required);
47 		__cmp_ao(pkt_dropped_icmp);
48 	}
49 	__cmp_ao(ao_required);
50 	__cmp_ao(accept_icmps);
51 
52 	test_ok("AO info get: %s", tst);
53 #undef __cmp_ao
54 }
55 
56 static void __setsockopt_checked(int sk, int optname, bool get,
57 				 void *optval, socklen_t *len,
58 				 int err, const char *tst, const char *tst2)
59 {
60 	int ret;
61 
62 	if (!tst)
63 		tst = "";
64 	if (!tst2)
65 		tst2 = "";
66 
67 	errno = 0;
68 	if (get)
69 		ret = getsockopt(sk, IPPROTO_TCP, optname, optval, len);
70 	else
71 		ret = setsockopt(sk, IPPROTO_TCP, optname, optval, *len);
72 	if (ret == -1) {
73 		if (errno == err)
74 			test_ok("%s%s", tst ?: "", tst2 ?: "");
75 		else
76 			test_fail("%s%s: %setsockopt() failed",
77 				  tst, tst2, get ? "g" : "s");
78 		close(sk);
79 		return;
80 	}
81 
82 	if (err) {
83 		test_fail("%s%s: %setsockopt() was expected to fail with %d",
84 			  tst, tst2, get ? "g" : "s", err);
85 	} else {
86 		test_ok("%s%s", tst ?: "", tst2 ?: "");
87 		if (optname == TCP_AO_ADD_KEY) {
88 			test_verify_socket_key(sk, optval);
89 		} else if (optname == TCP_AO_INFO && !get) {
90 			test_vefify_ao_info(sk, optval, tst2);
91 		} else if (optname == TCP_AO_GET_KEYS) {
92 			if (*len != sizeof(struct tcp_ao_getsockopt))
93 				test_fail("%s%s: get keys returned wrong tcp_ao_getsockopt size",
94 					  tst, tst2);
95 		}
96 	}
97 	close(sk);
98 }
99 
100 static void setsockopt_checked(int sk, int optname, void *optval,
101 			       int err, const char *tst)
102 {
103 	const char *cmd = NULL;
104 	socklen_t len;
105 
106 	switch (optname) {
107 	case TCP_AO_ADD_KEY:
108 		cmd = "key add: ";
109 		len = sizeof(struct tcp_ao_add);
110 		break;
111 	case TCP_AO_DEL_KEY:
112 		cmd = "key del: ";
113 		len = sizeof(struct tcp_ao_del);
114 		break;
115 	case TCP_AO_INFO:
116 		cmd = "AO info set: ";
117 		len = sizeof(struct tcp_ao_info_opt);
118 		break;
119 	default:
120 		break;
121 	}
122 
123 	__setsockopt_checked(sk, optname, false, optval, &len, err, cmd, tst);
124 }
125 
126 static int prepare_defs(int cmd, void *optval)
127 {
128 	int sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
129 
130 	if (sk < 0)
131 		test_error("socket()");
132 
133 	switch (cmd) {
134 	case TCP_AO_ADD_KEY: {
135 		struct tcp_ao_add *add = optval;
136 
137 		if (test_prepare_def_key(add, DEFAULT_TEST_PASSWORD, 0, this_ip_dest,
138 					-1, 0, 100, 100))
139 			test_error("prepare default tcp_ao_add");
140 		break;
141 		}
142 	case TCP_AO_DEL_KEY: {
143 		struct tcp_ao_del *del = optval;
144 
145 		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
146 				 DEFAULT_TEST_PREFIX, 100, 100))
147 			test_error("add default key");
148 		memset(del, 0, sizeof(struct tcp_ao_del));
149 		del->sndid = 100;
150 		del->rcvid = 100;
151 		del->prefix = DEFAULT_TEST_PREFIX;
152 		tcp_addr_to_sockaddr_in(&del->addr, &this_ip_dest, 0);
153 		break;
154 		}
155 	case TCP_AO_INFO: {
156 		struct tcp_ao_info_opt *info = optval;
157 
158 		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
159 				 DEFAULT_TEST_PREFIX, 100, 100))
160 			test_error("add default key");
161 		memset(info, 0, sizeof(struct tcp_ao_info_opt));
162 		break;
163 		}
164 	case TCP_AO_GET_KEYS: {
165 		struct tcp_ao_getsockopt *get = optval;
166 
167 		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
168 				 DEFAULT_TEST_PREFIX, 100, 100))
169 			test_error("add default key");
170 		memset(get, 0, sizeof(struct tcp_ao_getsockopt));
171 		get->nkeys = 1;
172 		get->get_all = 1;
173 		break;
174 		}
175 	default:
176 		test_error("unknown cmd");
177 	}
178 
179 	return sk;
180 }
181 
182 static void test_extend(int cmd, bool get, const char *tst, socklen_t under_size)
183 {
184 	struct {
185 		union {
186 			struct tcp_ao_add add;
187 			struct tcp_ao_del del;
188 			struct tcp_ao_getsockopt get;
189 			struct tcp_ao_info_opt info;
190 		};
191 		char *extend[100];
192 	} tmp_opt;
193 	socklen_t extended_size = sizeof(tmp_opt);
194 	int sk;
195 
196 	memset(&tmp_opt, 0, sizeof(tmp_opt));
197 	sk = prepare_defs(cmd, &tmp_opt);
198 	__setsockopt_checked(sk, cmd, get, &tmp_opt, &under_size,
199 			     EINVAL, tst, ": minimum size");
200 
201 	memset(&tmp_opt, 0, sizeof(tmp_opt));
202 	sk = prepare_defs(cmd, &tmp_opt);
203 	__setsockopt_checked(sk, cmd, get, &tmp_opt, &extended_size,
204 			     0, tst, ": extended size");
205 
206 	memset(&tmp_opt, 0, sizeof(tmp_opt));
207 	sk = prepare_defs(cmd, &tmp_opt);
208 	__setsockopt_checked(sk, cmd, get, NULL, &extended_size,
209 			     EFAULT, tst, ": null optval");
210 
211 	if (get) {
212 		memset(&tmp_opt, 0, sizeof(tmp_opt));
213 		sk = prepare_defs(cmd, &tmp_opt);
214 		__setsockopt_checked(sk, cmd, get, &tmp_opt, NULL,
215 				     EFAULT, tst, ": null optlen");
216 	}
217 }
218 
219 static void extend_tests(void)
220 {
221 	test_extend(TCP_AO_ADD_KEY, false, "AO add",
222 		    offsetof(struct tcp_ao_add, key));
223 	test_extend(TCP_AO_DEL_KEY, false, "AO del",
224 		    offsetof(struct tcp_ao_del, keyflags));
225 	test_extend(TCP_AO_INFO, false, "AO set info",
226 		    offsetof(struct tcp_ao_info_opt, pkt_dropped_icmp));
227 	test_extend(TCP_AO_INFO, true, "AO get info", -1);
228 	test_extend(TCP_AO_GET_KEYS, true, "AO get keys", -1);
229 }
230 
231 static void test_optmem_limit(void)
232 {
233 	size_t i, keys_limit, current_optmem = test_get_optmem();
234 	struct tcp_ao_add ao;
235 	union tcp_addr net = {};
236 	int sk;
237 
238 	if (inet_pton(TEST_FAMILY, TEST_NETWORK, &net) != 1)
239 		test_error("Can't convert ip address %s", TEST_NETWORK);
240 
241 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
242 	keys_limit = current_optmem / KERNEL_TCP_AO_KEY_SZ_ROUND_UP;
243 	for (i = 0;; i++) {
244 		union tcp_addr key_peer;
245 		int err;
246 
247 		key_peer = gen_tcp_addr(net, i + 1);
248 		tcp_addr_to_sockaddr_in(&ao.addr, &key_peer, 0);
249 		err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY,
250 				 &ao, sizeof(ao));
251 		if (!err) {
252 			/*
253 			 * TCP_AO_ADD_KEY should be the same order as the real
254 			 * sizeof(struct tcp_ao_key) in kernel.
255 			 */
256 			if (i <= keys_limit * 10)
257 				continue;
258 			test_fail("optmem limit test failed: added %zu key", i);
259 			break;
260 		}
261 		if (i < keys_limit) {
262 			test_fail("optmem limit test failed: couldn't add %zu key", i);
263 			break;
264 		}
265 		test_ok("optmem limit was hit on adding %zu key", i);
266 		break;
267 	}
268 	close(sk);
269 }
270 
271 static void test_einval_add_key(void)
272 {
273 	struct tcp_ao_add ao;
274 	int sk;
275 
276 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
277 	ao.keylen = TCP_AO_MAXKEYLEN + 1;
278 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big keylen");
279 
280 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
281 	ao.reserved = 1;
282 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved padding");
283 
284 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
285 	ao.reserved2 = 1;
286 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved2 padding");
287 
288 	/* tcp_ao_verify_ipv{4,6}() checks */
289 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
290 	ao.addr.ss_family = AF_UNIX;
291 	memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
292 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "wrong address family");
293 
294 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
295 	tcp_addr_to_sockaddr_in(&ao.addr, &this_ip_dest, 1234);
296 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "port (unsupported)");
297 
298 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
299 	ao.prefix = 0;
300 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "no prefix, addr");
301 
302 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
303 	ao.prefix = 0;
304 	memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
305 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "no prefix, any addr");
306 
307 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
308 	ao.prefix = 32;
309 	memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
310 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "prefix, any addr");
311 
312 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
313 	ao.prefix = 129;
314 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big prefix");
315 
316 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
317 	ao.prefix = 2;
318 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too short prefix");
319 
320 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
321 	ao.keyflags = (uint8_t)(-1);
322 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "bad key flags");
323 
324 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
325 	make_listen(sk);
326 	ao.set_current = 1;
327 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current key on a listen socket");
328 
329 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
330 	make_listen(sk);
331 	ao.set_rnext = 1;
332 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add rnext key on a listen socket");
333 
334 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
335 	make_listen(sk);
336 	ao.set_current = 1;
337 	ao.set_rnext = 1;
338 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current+rnext key on a listen socket");
339 
340 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
341 	ao.set_current = 1;
342 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current");
343 
344 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
345 	ao.set_rnext = 1;
346 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as rnext");
347 
348 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
349 	ao.set_current = 1;
350 	ao.set_rnext = 1;
351 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current+rnext");
352 
353 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
354 	ao.ifindex = 42;
355 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL,
356 			   "ifindex without TCP_AO_KEYF_IFNINDEX");
357 
358 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
359 	ao.keyflags |= TCP_AO_KEYF_IFINDEX;
360 	ao.ifindex = 42;
361 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "non-existent VRF");
362 	/*
363 	 * tcp_md5_do_lookup{,_any_l3index}() are checked in unsigned-md5
364 	 * see client_vrf_tests().
365 	 */
366 
367 	test_optmem_limit();
368 
369 	/* tcp_ao_parse_crypto() */
370 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
371 	ao.maclen = 100;
372 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EMSGSIZE, "maclen bigger than TCP hdr");
373 
374 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
375 	strcpy(ao.alg_name, "imaginary hash algo");
376 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, ENOENT, "bad algo");
377 }
378 
379 static void test_einval_del_key(void)
380 {
381 	struct tcp_ao_del del;
382 	int sk;
383 
384 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
385 	del.reserved = 1;
386 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved padding");
387 
388 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
389 	del.reserved2 = 1;
390 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved2 padding");
391 
392 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
393 	make_listen(sk);
394 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
395 		test_error("add key");
396 	del.set_current = 1;
397 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current key on a listen socket");
398 
399 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
400 	make_listen(sk);
401 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
402 		test_error("add key");
403 	del.set_rnext = 1;
404 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set rnext key on a listen socket");
405 
406 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
407 	make_listen(sk);
408 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
409 		test_error("add key");
410 	del.set_current = 1;
411 	del.set_rnext = 1;
412 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current+rnext key on a listen socket");
413 
414 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
415 	del.keyflags = (uint8_t)(-1);
416 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "bad key flags");
417 
418 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
419 	del.ifindex = 42;
420 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL,
421 			   "ifindex without TCP_AO_KEYF_IFNINDEX");
422 
423 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
424 	del.keyflags |= TCP_AO_KEYF_IFINDEX;
425 	del.ifindex = 42;
426 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existent VRF");
427 
428 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
429 	del.set_current = 1;
430 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current key");
431 
432 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
433 	del.set_rnext = 1;
434 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing rnext key");
435 
436 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
437 	del.set_current = 1;
438 	del.set_rnext = 1;
439 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current+rnext key");
440 
441 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
442 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
443 		test_error("add key");
444 	del.set_current = 1;
445 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current key");
446 
447 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
448 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
449 		test_error("add key");
450 	del.set_rnext = 1;
451 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set rnext key");
452 
453 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
454 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
455 		test_error("add key");
456 	del.set_current = 1;
457 	del.set_rnext = 1;
458 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current+rnext key");
459 
460 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
461 	del.set_current = 1;
462 	del.current_key = 100;
463 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current key to be removed");
464 
465 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
466 	del.set_rnext = 1;
467 	del.rnext = 100;
468 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as rnext key to be removed");
469 
470 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
471 	del.set_current = 1;
472 	del.current_key = 100;
473 	del.set_rnext = 1;
474 	del.rnext = 100;
475 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current+rnext key to be removed");
476 
477 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
478 	del.del_async = 1;
479 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "async on non-listen");
480 
481 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
482 	del.sndid = 101;
483 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing sndid");
484 
485 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
486 	del.rcvid = 101;
487 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing rcvid");
488 
489 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
490 	tcp_addr_to_sockaddr_in(&del.addr, &this_ip_addr, 0);
491 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "incorrect addr");
492 
493 	sk = prepare_defs(TCP_AO_DEL_KEY, &del);
494 	setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "correct key delete");
495 }
496 
497 static void test_einval_ao_info(void)
498 {
499 	struct tcp_ao_info_opt info;
500 	int sk;
501 
502 	sk = prepare_defs(TCP_AO_INFO, &info);
503 	make_listen(sk);
504 	info.set_current = 1;
505 	setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current key on a listen socket");
506 
507 	sk = prepare_defs(TCP_AO_INFO, &info);
508 	make_listen(sk);
509 	info.set_rnext = 1;
510 	setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set rnext key on a listen socket");
511 
512 	sk = prepare_defs(TCP_AO_INFO, &info);
513 	make_listen(sk);
514 	info.set_current = 1;
515 	info.set_rnext = 1;
516 	setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current+rnext key on a listen socket");
517 
518 	sk = prepare_defs(TCP_AO_INFO, &info);
519 	info.reserved = 1;
520 	setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved padding");
521 
522 	sk = prepare_defs(TCP_AO_INFO, &info);
523 	info.reserved2 = 1;
524 	setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved2 padding");
525 
526 	sk = prepare_defs(TCP_AO_INFO, &info);
527 	info.accept_icmps = 1;
528 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "accept_icmps");
529 
530 	sk = prepare_defs(TCP_AO_INFO, &info);
531 	info.ao_required = 1;
532 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "ao required");
533 
534 	if (!should_skip_test("ao required with MD5 key", KCONFIG_TCP_MD5)) {
535 		sk = prepare_defs(TCP_AO_INFO, &info);
536 		info.ao_required = 1;
537 		if (test_set_md5(sk, tcp_md5_client, TEST_PREFIX, -1,
538 				 "long long secret")) {
539 			test_error("setsockopt(TCP_MD5SIG_EXT)");
540 			close(sk);
541 		} else {
542 			setsockopt_checked(sk, TCP_AO_INFO, &info, EKEYREJECTED,
543 					   "ao required with MD5 key");
544 		}
545 	}
546 
547 	sk = prepare_defs(TCP_AO_INFO, &info);
548 	info.set_current = 1;
549 	setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current key");
550 
551 	sk = prepare_defs(TCP_AO_INFO, &info);
552 	info.set_rnext = 1;
553 	setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing rnext key");
554 
555 	sk = prepare_defs(TCP_AO_INFO, &info);
556 	info.set_current = 1;
557 	info.set_rnext = 1;
558 	setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current+rnext key");
559 
560 	sk = prepare_defs(TCP_AO_INFO, &info);
561 	info.set_current = 1;
562 	info.current_key = 100;
563 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current key");
564 
565 	sk = prepare_defs(TCP_AO_INFO, &info);
566 	info.set_rnext = 1;
567 	info.rnext = 100;
568 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set rnext key");
569 
570 	sk = prepare_defs(TCP_AO_INFO, &info);
571 	info.set_current = 1;
572 	info.set_rnext = 1;
573 	info.current_key = 100;
574 	info.rnext = 100;
575 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current+rnext key");
576 
577 	sk = prepare_defs(TCP_AO_INFO, &info);
578 	info.set_counters = 1;
579 	info.pkt_good = 321;
580 	info.pkt_bad = 888;
581 	info.pkt_key_not_found = 654;
582 	info.pkt_ao_required = 987654;
583 	info.pkt_dropped_icmp = 10000;
584 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set counters");
585 
586 	sk = prepare_defs(TCP_AO_INFO, &info);
587 	setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "no-op");
588 }
589 
590 static void getsockopt_checked(int sk, struct tcp_ao_getsockopt *optval,
591 			       int err, const char *tst)
592 {
593 	socklen_t len = sizeof(struct tcp_ao_getsockopt);
594 
595 	__setsockopt_checked(sk, TCP_AO_GET_KEYS, true, optval, &len, err,
596 			     "get keys: ", tst);
597 }
598 
599 static void test_einval_get_keys(void)
600 {
601 	struct tcp_ao_getsockopt out;
602 	int sk;
603 
604 	sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
605 	if (sk < 0)
606 		test_error("socket()");
607 	getsockopt_checked(sk, &out, ENOENT, "no ao_info");
608 
609 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
610 	getsockopt_checked(sk, &out, 0, "proper tcp_ao_get_mkts()");
611 
612 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
613 	out.pkt_good = 643;
614 	getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_good counter");
615 
616 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
617 	out.pkt_bad = 94;
618 	getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_bad counter");
619 
620 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
621 	out.keyflags = (uint8_t)(-1);
622 	getsockopt_checked(sk, &out, EINVAL, "bad keyflags");
623 
624 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
625 	out.ifindex = 42;
626 	getsockopt_checked(sk, &out, EINVAL,
627 			   "ifindex without TCP_AO_KEYF_IFNINDEX");
628 
629 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
630 	out.reserved = 1;
631 	getsockopt_checked(sk, &out, EINVAL, "using reserved field");
632 
633 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
634 	out.get_all = 0;
635 	out.prefix = 0;
636 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
637 	getsockopt_checked(sk, &out, EINVAL, "no prefix, addr");
638 
639 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
640 	out.get_all = 0;
641 	out.prefix = 0;
642 	memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
643 	getsockopt_checked(sk, &out, 0, "no prefix, any addr");
644 
645 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
646 	out.get_all = 0;
647 	out.prefix = 32;
648 	memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
649 	getsockopt_checked(sk, &out, EINVAL, "prefix, any addr");
650 
651 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
652 	out.get_all = 0;
653 	out.prefix = 129;
654 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
655 	getsockopt_checked(sk, &out, EINVAL, "too big prefix");
656 
657 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
658 	out.get_all = 0;
659 	out.prefix = 2;
660 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
661 	getsockopt_checked(sk, &out, EINVAL, "too short prefix");
662 
663 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
664 	out.get_all = 0;
665 	out.prefix = DEFAULT_TEST_PREFIX;
666 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
667 	getsockopt_checked(sk, &out, 0, "prefix + addr");
668 
669 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
670 	out.get_all = 1;
671 	out.prefix = DEFAULT_TEST_PREFIX;
672 	getsockopt_checked(sk, &out, EINVAL, "get_all + prefix");
673 
674 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
675 	out.get_all = 1;
676 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
677 	getsockopt_checked(sk, &out, EINVAL, "get_all + addr");
678 
679 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
680 	out.get_all = 1;
681 	out.sndid = 1;
682 	getsockopt_checked(sk, &out, EINVAL, "get_all + sndid");
683 
684 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
685 	out.get_all = 1;
686 	out.rcvid = 1;
687 	getsockopt_checked(sk, &out, EINVAL, "get_all + rcvid");
688 
689 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
690 	out.get_all = 0;
691 	out.is_current = 1;
692 	out.prefix = DEFAULT_TEST_PREFIX;
693 	getsockopt_checked(sk, &out, EINVAL, "current + prefix");
694 
695 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
696 	out.get_all = 0;
697 	out.is_current = 1;
698 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
699 	getsockopt_checked(sk, &out, EINVAL, "current + addr");
700 
701 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
702 	out.get_all = 0;
703 	out.is_current = 1;
704 	out.sndid = 1;
705 	getsockopt_checked(sk, &out, EINVAL, "current + sndid");
706 
707 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
708 	out.get_all = 0;
709 	out.is_current = 1;
710 	out.rcvid = 1;
711 	getsockopt_checked(sk, &out, EINVAL, "current + rcvid");
712 
713 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
714 	out.get_all = 0;
715 	out.is_rnext = 1;
716 	out.prefix = DEFAULT_TEST_PREFIX;
717 	getsockopt_checked(sk, &out, EINVAL, "rnext + prefix");
718 
719 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
720 	out.get_all = 0;
721 	out.is_rnext = 1;
722 	tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
723 	getsockopt_checked(sk, &out, EINVAL, "rnext + addr");
724 
725 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
726 	out.get_all = 0;
727 	out.is_rnext = 1;
728 	out.sndid = 1;
729 	getsockopt_checked(sk, &out, EINVAL, "rnext + sndid");
730 
731 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
732 	out.get_all = 0;
733 	out.is_rnext = 1;
734 	out.rcvid = 1;
735 	getsockopt_checked(sk, &out, EINVAL, "rnext + rcvid");
736 
737 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
738 	out.get_all = 1;
739 	out.is_current = 1;
740 	getsockopt_checked(sk, &out, EINVAL, "get_all + current");
741 
742 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
743 	out.get_all = 1;
744 	out.is_rnext = 1;
745 	getsockopt_checked(sk, &out, EINVAL, "get_all + rnext");
746 
747 	sk = prepare_defs(TCP_AO_GET_KEYS, &out);
748 	out.get_all = 0;
749 	out.is_current = 1;
750 	out.is_rnext = 1;
751 	getsockopt_checked(sk, &out, 0, "current + rnext");
752 }
753 
754 static void einval_tests(void)
755 {
756 	test_einval_add_key();
757 	test_einval_del_key();
758 	test_einval_ao_info();
759 	test_einval_get_keys();
760 }
761 
762 static void duplicate_tests(void)
763 {
764 	union tcp_addr network_dup;
765 	struct tcp_ao_add ao, ao2;
766 	int sk;
767 
768 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
769 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
770 		test_error("setsockopt()");
771 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy");
772 
773 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
774 	ao2 = ao;
775 	memcpy(&ao2.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
776 	ao2.prefix = 0;
777 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao2, sizeof(ao)))
778 		test_error("setsockopt()");
779 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: any addr key on the socket");
780 
781 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
782 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
783 		test_error("setsockopt()");
784 	memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
785 	ao.prefix = 0;
786 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr key");
787 
788 	if (inet_pton(TEST_FAMILY, TEST_NETWORK, &network_dup) != 1)
789 		test_error("Can't convert ip address %s", TEST_NETWORK);
790 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
791 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
792 		test_error("setsockopt()");
793 	if (test_prepare_def_key(&ao, "password", 0, network_dup,
794 				 16, 0, 100, 100))
795 		test_error("prepare default tcp_ao_add");
796 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr for the same subnet");
797 
798 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
799 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
800 		test_error("setsockopt()");
801 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy of a key");
802 
803 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
804 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
805 		test_error("setsockopt()");
806 	ao.rcvid = 101;
807 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: RecvID differs");
808 
809 	sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
810 	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
811 		test_error("setsockopt()");
812 	ao.sndid = 101;
813 	setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: SendID differs");
814 }
815 
816 static void *client_fn(void *arg)
817 {
818 	if (inet_pton(TEST_FAMILY, __TEST_CLIENT_IP(2), &tcp_md5_client) != 1)
819 		test_error("Can't convert ip address");
820 	extend_tests();
821 	einval_tests();
822 	duplicate_tests();
823 	/*
824 	 * TODO: check getsockopt(TCP_AO_GET_KEYS) with different filters
825 	 * returning proper nr & keys;
826 	 */
827 
828 	return NULL;
829 }
830 
831 int main(int argc, char *argv[])
832 {
833 	test_init(120, client_fn, NULL);
834 	return 0;
835 }
836