~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/tcp_ao/setsockopt-closed.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php