Merge tag 'driver-core-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / tools / testing / selftests / net / tcp_ao / setsockopt-closed.c
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 }