]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/net/routing/test_rtsock_l3.c
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / tests / sys / net / routing / test_rtsock_l3.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019 Alexander V. Chernikov
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #include "rtsock_common.h"
31 #include "rtsock_config.h"
32 #include "sys/types.h"
33 #include <sys/time.h>
34 #include <sys/ioctl.h>
35
36 #include "net/bpf.h"
37
38 static void
39 jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
40 {
41         char vnet_name[512];
42
43         snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
44         RLOG("jumping to %s", vnet_name);
45
46         vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
47
48         /* Update ifindex cache */
49         c->ifindex = if_nametoindex(c->ifname);
50 }
51
52 static inline struct rtsock_test_config *
53 presetup_ipv6_iface(const atf_tc_t *tc)
54 {
55         struct rtsock_test_config *c;
56         int ret;
57
58         c = config_setup(tc, NULL);
59
60         jump_vnet(c, tc);
61
62         ret = iface_turn_up(c->ifname);
63         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
64
65         ret = iface_enable_ipv6(c->ifname);
66         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
67
68         return (c);
69 }
70
71 static inline struct rtsock_test_config *
72 presetup_ipv6(const atf_tc_t *tc)
73 {
74         struct rtsock_test_config *c;
75         int ret;
76
77         c = presetup_ipv6_iface(tc);
78
79         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
80
81         c->rtsock_fd = rtsock_setup_socket();
82
83         return (c);
84 }
85
86 static inline struct rtsock_test_config *
87 presetup_ipv4_iface(const atf_tc_t *tc)
88 {
89         struct rtsock_test_config *c;
90         int ret;
91
92         c = config_setup(tc, NULL);
93
94         jump_vnet(c, tc);
95
96         ret = iface_turn_up(c->ifname);
97         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
98
99         return (c);
100 }
101
102 static inline struct rtsock_test_config *
103 presetup_ipv4(const atf_tc_t *tc)
104 {
105         struct rtsock_test_config *c;
106         int ret;
107
108         c = presetup_ipv4_iface(tc);
109
110         /* assumes ifconfig doing IFF_UP */
111         ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
112         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
113
114         c->rtsock_fd = rtsock_setup_socket();
115
116         return (c);
117 }
118
119
120 static void
121 prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst,
122   struct sockaddr_in *mask, struct sockaddr_in *gw)
123 {
124         /* Create IPv4 subnetwork with smaller prefix */
125         sa_fill_mask4(mask, c->plen4 + 1);
126         *dst = c->net4;
127         /* Calculate GW as last-net-address - 1 */
128         *gw = c->net4;
129         gw->sin_addr.s_addr = htonl((ntohl(c->net4.sin_addr.s_addr) | ~ntohl(c->mask4.sin_addr.s_addr)) - 1);
130         sa_print((struct sockaddr *)dst, 0);
131         sa_print((struct sockaddr *)mask, 0);
132         sa_print((struct sockaddr *)gw, 0);
133 }
134
135 static void
136 prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst,
137   struct sockaddr_in6 *mask, struct sockaddr_in6 *gw)
138 {
139         /* Create IPv6 subnetwork with smaller prefix */
140         sa_fill_mask6(mask, c->plen6 + 1);
141         *dst = c->net6;
142         /* Calculate GW as last-net-address - 1 */
143         *gw = c->net6;
144 #define _s6_addr32 __u6_addr.__u6_addr32
145         gw->sin6_addr._s6_addr32[0] = htonl((ntohl(gw->sin6_addr._s6_addr32[0]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[0])));
146         gw->sin6_addr._s6_addr32[1] = htonl((ntohl(gw->sin6_addr._s6_addr32[1]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[1])));
147         gw->sin6_addr._s6_addr32[2] = htonl((ntohl(gw->sin6_addr._s6_addr32[2]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[2])));
148         gw->sin6_addr._s6_addr32[3] = htonl((ntohl(gw->sin6_addr._s6_addr32[3]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[3])) - 1);
149 #undef _s6_addr32
150         sa_print((struct sockaddr *)dst, 0);
151         sa_print((struct sockaddr *)mask, 0);
152         sa_print((struct sockaddr *)gw, 0);
153 }
154
155 static void
156 prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
157   struct sockaddr *mask, struct sockaddr *gw)
158 {
159
160         rtsock_prepare_route_message(rtm, cmd, dst, mask, gw);
161
162         if (cmd == RTM_ADD || cmd == RTM_CHANGE)
163                 rtm->rtm_flags |= RTF_STATIC;
164 }
165
166 static void
167 verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
168   struct sockaddr *mask, struct sockaddr *gw)
169 {
170         char msg[512];
171         struct sockaddr *sa;
172         int ret;
173
174         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == cmd,
175             "expected %s message, got %d (%s)", rtsock_print_cmdtype(cmd),
176             rtm->rtm_type, rtsock_print_cmdtype(rtm->rtm_type));
177         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_errno == 0,
178             "got got errno %d as message reply", rtm->rtm_errno);
179         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->_rtm_spare1 == 0,
180             "expected rtm_spare==0, got %d", rtm->_rtm_spare1);
181
182         /* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */
183         if (dst != NULL) {
184                 sa = rtsock_find_rtm_sa(rtm, RTA_DST);
185                 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "DST is not set");
186                 ret = sa_equal_msg(sa, dst, msg, sizeof(msg));
187                 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
188         }
189
190         if (mask != NULL) {
191                 sa = rtsock_find_rtm_sa(rtm, RTA_NETMASK);
192                 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "NETMASK is not set");
193                 ret = sa_equal_msg(sa, mask, msg, sizeof(msg));
194                 ret = 1;
195                 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg);
196         }
197
198         if (gw != NULL) {
199                 sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
200                 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
201                 ret = sa_equal_msg(sa, gw, msg, sizeof(msg));
202                 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
203         }
204 }
205
206 static void
207 verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags)
208 {
209         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex,
210             "expected ifindex %d, got %d", ifindex, rtm->rtm_index);
211
212         if (rtm->rtm_flags != rtm_flags) {
213                 char got_flags[64], expected_flags[64];
214                 rtsock_print_rtm_flags(got_flags, sizeof(got_flags),
215                     rtm->rtm_flags);
216                 rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags),
217                     rtm_flags);
218
219                 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == rtm_flags,
220                     "expected flags: 0x%X %s, got 0x%X %s",
221                     rtm_flags, expected_flags,
222                     rtm->rtm_flags, got_flags);
223         }
224 }
225
226 static void
227 verify_link_gateway(struct rt_msghdr *rtm, int ifindex)
228 {
229         struct sockaddr *sa;
230         struct sockaddr_dl *sdl;
231
232         sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
233         RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
234         RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
235         sdl = (struct sockaddr_dl *)sa;
236         RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == ifindex, "GW ifindex is %d", sdl->sdl_index);
237 }
238
239 /* TESTS */
240
241 #define DECLARE_TEST_VARS                                       \
242         char buffer[2048];                                      \
243         struct rtsock_test_config *c;                           \
244         struct rt_msghdr *rtm = (struct rt_msghdr *)buffer;     \
245         struct sockaddr *sa;                                    \
246         int ret;                                                \
247                                                                 \
248
249 #define DESCRIBE_ROOT_TEST(_msg)        config_describe_root_test(tc, _msg)
250 #define CLEANUP_AFTER_TEST      config_generic_cleanup(tc)
251
252 #define RTM_DECLARE_ROOT_TEST(_name, _descr)                    \
253 ATF_TC_WITH_CLEANUP(_name);                                     \
254 ATF_TC_HEAD(_name, tc)                                          \
255 {                                                               \
256         DESCRIBE_ROOT_TEST(_descr);                             \
257 }                                                               \
258 ATF_TC_CLEANUP(_name, tc)                                       \
259 {                                                               \
260         CLEANUP_AFTER_TEST;                                     \
261 }
262
263 ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success);
264 ATF_TC_HEAD(rtm_get_v4_exact_success, tc)
265 {
266         DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix");
267 }
268
269 ATF_TC_BODY(rtm_get_v4_exact_success, tc)
270 {
271         DECLARE_TEST_VARS;
272
273         c = presetup_ipv4(tc);
274
275         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
276             (struct sockaddr *)&c->mask4, NULL);
277
278         rtsock_send_rtm(c->rtsock_fd, rtm);
279
280         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
281
282         /*
283          * RTM_GET: Report Metrics: len 240, pid: 45072, seq 42, errno 0, flags: <UP,DONE,PINNED>
284          * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
285          *  af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
286          *  af=link len=54 sdl_index=3 if_name=tap4242 hd={36, 12, 03, 00, 06, 00{49}}
287          *  af=inet len=16 addr=255.255.255.0 hd={10, 02, FF{5}, 00{9}}
288          */
289
290         verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
291             (struct sockaddr *)&c->mask4, NULL);
292
293         verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
294
295         /* Explicitly verify gateway for the interface route */
296         verify_link_gateway(rtm, c->ifindex);
297         sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
298         RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
299         RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
300         struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
301         RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == c->ifindex, "GW ifindex is %d", sdl->sdl_index);
302 }
303
304 ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc)
305 {
306         CLEANUP_AFTER_TEST;
307 }
308
309 ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success);
310 ATF_TC_HEAD(rtm_get_v4_lpm_success, tc)
311 {
312         DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix");
313 }
314
315 ATF_TC_BODY(rtm_get_v4_lpm_success, tc)
316 {
317         DECLARE_TEST_VARS;
318
319         c = presetup_ipv4(tc);
320
321         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL);
322
323         rtsock_send_rtm(c->rtsock_fd, rtm);
324
325         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
326
327         /*
328          * RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED>
329          * locks:  inits:
330          * sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
331          * 10.0.0.0 link#1 255.255.255.0 vtnet0:52.54.0.42.f.ef 10.0.0.157
332          */
333
334         verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
335             (struct sockaddr *)&c->mask4, NULL);
336
337         verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
338 }
339
340 ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc)
341 {
342         CLEANUP_AFTER_TEST;
343 }
344
345
346 ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure);
347 ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)
348 {
349
350         DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr");
351 }
352
353 ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)
354 {
355         DECLARE_TEST_VARS;
356         struct rtsock_config_options co;
357
358         bzero(&co, sizeof(co));
359         co.num_interfaces = 0;
360         
361         c = config_setup(tc,&co);
362         c->rtsock_fd = rtsock_setup_socket();
363
364         rtsock_prepare_route_message(rtm, RTM_GET, NULL,
365             (struct sockaddr *)&c->mask4, NULL);
366         rtsock_update_rtm_len(rtm);
367
368         ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
369 }
370
371 ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc)
372 {
373         CLEANUP_AFTER_TEST;
374 }
375
376 ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_failure);
377 ATF_TC_HEAD(rtm_get_v4_hostbits_failure, tc)
378 {
379         DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set");
380 }
381
382 ATF_TC_BODY(rtm_get_v4_hostbits_failure, tc)
383 {
384         DECLARE_TEST_VARS;
385
386         c = presetup_ipv4(tc);
387
388         /* Q the same prefix */
389         rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4,
390             (struct sockaddr *)&c->mask4, NULL);
391         rtsock_update_rtm_len(rtm);
392
393         ATF_CHECK_ERRNO(ESRCH, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
394 }
395
396 ATF_TC_CLEANUP(rtm_get_v4_hostbits_failure, tc)
397 {
398         CLEANUP_AFTER_TEST;
399 }
400
401 ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);
402 ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)
403 {
404         DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");
405 }
406
407 ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)
408 {
409         DECLARE_TEST_VARS;
410
411         c = presetup_ipv4(tc);
412
413         /* Create IPv4 subnetwork with smaller prefix */
414         struct sockaddr_in mask4;
415         struct sockaddr_in net4;
416         struct sockaddr_in gw4;
417         prepare_v4_network(c, &net4, &mask4, &gw4);
418
419         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
420             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
421
422         rtsock_send_rtm(c->rtsock_fd, rtm);
423         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
424
425         /*
426          * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
427          * locks:  inits:
428          * sockaddrs: <DST,GATEWAY,NETMASK>
429          *  192.0.2.0 192.0.2.254 255.255.255.128
430          */
431
432         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
433             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
434         /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */
435         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
436 }
437
438 ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)
439 {
440         CLEANUP_AFTER_TEST;
441 }
442
443 RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_failure,
444     "Tests failure with netmask sa and RTF_HOST inconsistency");
445
446 ATF_TC_BODY(rtm_add_v4_no_rtf_host_failure, tc)
447 {
448         DECLARE_TEST_VARS;
449
450         c = presetup_ipv4(tc);
451
452         /* Create IPv4 subnetwork with smaller prefix */
453         struct sockaddr_in mask4;
454         struct sockaddr_in net4;
455         struct sockaddr_in gw4;
456         prepare_v4_network(c, &net4, &mask4, &gw4);
457
458         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
459             NULL, (struct sockaddr *)&gw4);
460         rtsock_update_rtm_len(rtm);
461
462         /* RTF_HOST is NOT specified, while netmask is empty */
463
464         ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
465 }
466
467 ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);
468 ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)
469 {
470         DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");
471 }
472
473 ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)
474 {
475         DECLARE_TEST_VARS;
476
477         c = presetup_ipv4(tc);
478
479         /* Create IPv4 subnetwork with smaller prefix */
480         struct sockaddr_in mask4;
481         struct sockaddr_in net4;
482         struct sockaddr_in gw4;
483         prepare_v4_network(c, &net4, &mask4, &gw4);
484
485         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
486             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
487
488         rtsock_send_rtm(c->rtsock_fd, rtm);
489
490         /* Route has been added successfully, try to delete it */
491         prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
492             (struct sockaddr *)&mask4, NULL);
493
494         rtsock_send_rtm(c->rtsock_fd, rtm);
495
496         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
497
498         /*
499          * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
500          * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
501          *  af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
502          *  af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
503          *  af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
504          */
505         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
506             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
507
508         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
509 }
510
511 ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
512 {
513         CLEANUP_AFTER_TEST;
514 }
515
516 RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
517     "Tests IPv4 gateway change");
518
519 ATF_TC_BODY(rtm_change_v4_gw_success, tc)
520 {
521         DECLARE_TEST_VARS;
522         struct rtsock_config_options co;
523
524         bzero(&co, sizeof(co));
525         co.num_interfaces = 2;
526
527         c = config_setup(tc, &co);
528         jump_vnet(c, tc);
529
530         ret = iface_turn_up(c->ifnames[0]);
531         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
532         ret = iface_turn_up(c->ifnames[1]);
533         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
534
535         ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
536         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
537
538         /* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */
539         ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);
540         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
541
542         c->rtsock_fd = rtsock_setup_socket();
543
544         /* Create IPv4 subnetwork with smaller prefix */
545         struct sockaddr_in mask4;
546         struct sockaddr_in net4;
547         struct sockaddr_in gw4;
548         prepare_v4_network(c, &net4, &mask4, &gw4);
549
550         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
551             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
552
553         rtsock_send_rtm(c->rtsock_fd, rtm);
554         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
555
556         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
557             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
558
559         /* Change gateway to the one on desiding on the other interface */
560         inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);
561         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
562             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
563         rtsock_send_rtm(c->rtsock_fd, rtm);
564
565         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
566
567         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
568             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
569
570         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
571             RTF_DONE | RTF_GATEWAY | RTF_STATIC);
572
573         /* Verify the change has actually taken place */
574         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
575             (struct sockaddr *)&mask4, NULL);
576
577         rtsock_send_rtm(c->rtsock_fd, rtm);
578
579         /*
580          * RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
581          *  sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
582          *  af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}
583          *  af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}
584          *  af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}
585          */
586
587         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
588         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
589             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
590
591 }
592
593 RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
594     "Tests IPv4 path  mtu change");
595
596 ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
597 {
598         DECLARE_TEST_VARS;
599
600         unsigned long test_mtu = 1442;
601
602         c = presetup_ipv4(tc);
603
604         /* Create IPv4 subnetwork with smaller prefix */
605         struct sockaddr_in mask4;
606         struct sockaddr_in net4;
607         struct sockaddr_in gw4;
608         prepare_v4_network(c, &net4, &mask4, &gw4);
609
610         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
611             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
612
613         rtsock_send_rtm(c->rtsock_fd, rtm);
614         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
615
616         /* Change MTU */
617         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
618             (struct sockaddr *)&mask4, NULL);
619         rtm->rtm_inits |= RTV_MTU;
620         rtm->rtm_rmx.rmx_mtu = test_mtu;
621
622         rtsock_send_rtm(c->rtsock_fd, rtm);
623         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
624
625         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
626             (struct sockaddr *)&mask4, NULL);
627
628         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
629             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
630
631         /* Verify the change has actually taken place */
632         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
633             (struct sockaddr *)&mask4, NULL);
634
635         rtsock_send_rtm(c->rtsock_fd, rtm);
636         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
637
638         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
639             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
640 }
641
642
643 ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);
644 ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)
645 {
646         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
647 }
648
649 ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)
650 {
651         DECLARE_TEST_VARS;
652
653         c = presetup_ipv6(tc);
654
655         /* Create IPv6 subnetwork with smaller prefix */
656         struct sockaddr_in6 mask6;
657         struct sockaddr_in6 net6;
658         struct sockaddr_in6 gw6;
659         prepare_v6_network(c, &net6, &mask6, &gw6);
660
661         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
662             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
663
664         rtsock_send_rtm(c->rtsock_fd, rtm);
665         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
666
667         /*
668          * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
669          * locks:  inits:
670          * sockaddrs: <DST,GATEWAY,NETMASK>
671          *  192.0.2.0 192.0.2.254 255.255.255.128
672          */
673
674         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
675             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
676
677         /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */
678         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
679 }
680
681 ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)
682 {
683         CLEANUP_AFTER_TEST;
684 }
685
686 ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);
687 ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)
688 {
689
690         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");
691 }
692
693 ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)
694 {
695         DECLARE_TEST_VARS;
696
697         c = presetup_ipv6(tc);
698
699         /* Create IPv6 subnetwork with smaller prefix */
700         struct sockaddr_in6 mask6;
701         struct sockaddr_in6 net6;
702         struct sockaddr_in6 gw6;
703         prepare_v6_network(c, &net6, &mask6, &gw6);
704
705         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
706             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
707
708         rtsock_send_rtm(c->rtsock_fd, rtm);
709
710         /* Route has been added successfully, try to delete it */
711         prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
712             (struct sockaddr *)&mask6, NULL);
713
714         rtsock_send_rtm(c->rtsock_fd, rtm);
715         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
716
717         /*
718          * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
719          * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
720          *  af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
721          *  af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
722          *  af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
723          */
724
725         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
726             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
727         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
728 }
729
730 ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
731 {
732         CLEANUP_AFTER_TEST;
733 }
734
735 RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
736     "Tests IPv6 gateway change");
737
738 ATF_TC_BODY(rtm_change_v6_gw_success, tc)
739 {
740         DECLARE_TEST_VARS;
741         struct rtsock_config_options co;
742
743         bzero(&co, sizeof(co));
744         co.num_interfaces = 2;
745
746         c = config_setup(tc, &co);
747         jump_vnet(c, tc);
748
749         ret = iface_turn_up(c->ifnames[0]);
750         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
751         ret = iface_turn_up(c->ifnames[1]);
752         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
753
754         ret = iface_enable_ipv6(c->ifnames[0]);
755         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);
756         ret = iface_enable_ipv6(c->ifnames[1]);
757         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);
758
759         ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
760         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
761
762         ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
763         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
764
765         c->rtsock_fd = rtsock_setup_socket();
766
767         /* Create IPv6 subnetwork with smaller prefix */
768         struct sockaddr_in6 mask6;
769         struct sockaddr_in6 net6;
770         struct sockaddr_in6 gw6;
771         prepare_v6_network(c, &net6, &mask6, &gw6);
772
773         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
774             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
775
776         rtsock_send_rtm(c->rtsock_fd, rtm);
777         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
778
779         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
780             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
781
782         /* Change gateway to the one on residing on the other interface */
783         inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);
784         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
785             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
786         rtsock_send_rtm(c->rtsock_fd, rtm);
787
788         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
789
790         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
791             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
792
793         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
794             RTF_DONE | RTF_GATEWAY | RTF_STATIC);
795
796         /* Verify the change has actually taken place */
797         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
798             (struct sockaddr *)&mask6, NULL);
799
800         rtsock_send_rtm(c->rtsock_fd, rtm);
801
802         /*
803          * RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
804          *  sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
805          *  af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}
806          *  af=inet6 len=28 addr=2001:db8:4242::4242 hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x42, x42, x00{8}, x42, x42, x00{4}}
807          *  af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}
808          */
809
810         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
811         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
812             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
813 }
814
815 RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
816     "Tests IPv6 path mtu change");
817
818 ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
819 {
820         DECLARE_TEST_VARS;
821
822         unsigned long test_mtu = 1442;
823
824         c = presetup_ipv6(tc);
825
826         /* Create IPv6 subnetwork with smaller prefix */
827         struct sockaddr_in6 mask6;
828         struct sockaddr_in6 net6;
829         struct sockaddr_in6 gw6;
830         prepare_v6_network(c, &net6, &mask6, &gw6);
831
832         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
833             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
834
835         /* Send route add */
836         rtsock_send_rtm(c->rtsock_fd, rtm);
837         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
838
839         /* Change MTU */
840         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
841             (struct sockaddr *)&mask6, NULL);
842         rtm->rtm_inits |= RTV_MTU;
843         rtm->rtm_rmx.rmx_mtu = test_mtu;
844
845         rtsock_send_rtm(c->rtsock_fd, rtm);
846         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
847
848         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
849             (struct sockaddr *)&mask6, NULL);
850
851         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
852             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
853
854         /* Verify the change has actually taken place */
855         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
856             (struct sockaddr *)&mask6, NULL);
857
858         rtsock_send_rtm(c->rtsock_fd, rtm);
859         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
860
861         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
862             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
863 }
864
865 ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
866 ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
867 {
868         DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");
869 }
870
871 ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)
872 {
873         DECLARE_TEST_VARS;
874
875         c = presetup_ipv4(tc);
876
877         /* Create IPv4 subnetwork with smaller prefix */
878         struct sockaddr_in mask4;
879         struct sockaddr_in net4;
880         struct sockaddr_in gw4;
881         prepare_v4_network(c, &net4, &mask4, &gw4);
882
883         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
884             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
885
886         /* Set expire time to now */
887         struct timeval tv;
888         gettimeofday(&tv, NULL);
889         rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
890         rtm->rtm_inits |= RTV_EXPIRE;
891
892         rtsock_send_rtm(c->rtsock_fd, rtm);
893         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
894         ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
895         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
896
897         /* The next should be route deletion */
898         rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
899
900         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
901             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
902
903         verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_DONE | RTF_STATIC);
904 }
905
906 ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)
907 {
908         CLEANUP_AFTER_TEST;
909 }
910
911 ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);
912 ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)
913 {
914         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
915 }
916
917 ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)
918 {
919         DECLARE_TEST_VARS;
920
921         c = presetup_ipv6(tc);
922
923         /* Create IPv6 subnetwork with smaller prefix */
924         struct sockaddr_in6 mask6;
925         struct sockaddr_in6 net6;
926         struct sockaddr_in6 gw6;
927         prepare_v6_network(c, &net6, &mask6, &gw6);
928
929         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
930             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
931
932         /* Set expire time to now */
933         struct timeval tv;
934         gettimeofday(&tv, NULL);
935         rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
936         rtm->rtm_inits |= RTV_EXPIRE;
937
938         rtsock_send_rtm(c->rtsock_fd, rtm);
939         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
940         ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
941         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
942
943         /* The next should be route deletion */
944         rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
945
946         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
947             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
948
949
950         /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */
951         verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_DONE | RTF_STATIC);
952 }
953
954 ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)
955 {
956         CLEANUP_AFTER_TEST;
957 }
958
959 /* Interface address messages tests */
960
961 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,
962     "Tests validness for /128 host route announce after ifaddr assignment");
963
964 ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)
965 {
966         DECLARE_TEST_VARS;
967
968         c = presetup_ipv6_iface(tc);
969
970         c->rtsock_fd = rtsock_setup_socket();
971
972         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
973
974         /*
975          * There will be multiple.
976          * RTM_ADD without llinfo.
977          */
978
979         while (true) {
980                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
981                 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))
982                         break;
983         }
984         /* This should be a message for the host route */
985
986         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL);
987         rtsock_validate_pid_kernel(rtm);
988         /* No netmask should be set */
989         RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
990
991         /* gateway should be link sdl with ifindex of an address interface */
992         verify_link_gateway(rtm, c->ifindex);
993
994         int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
995         verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags);
996 }
997
998 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,
999     "Tests validness for the prefix route announce after ifaddr assignment");
1000
1001 ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)
1002 {
1003         DECLARE_TEST_VARS;
1004
1005         c = presetup_ipv6_iface(tc);
1006
1007         c->rtsock_fd = rtsock_setup_socket();
1008
1009         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1010
1011         /*
1012          * Multiple RTM_ADD messages will be generated:
1013          * 1) lladdr mapping (RTF_LLDATA)
1014          * 2) host route (one w/o netmask)
1015          * 3) prefix route
1016          */
1017
1018         while (true) {
1019                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1020                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1021                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1022                         break;
1023         }
1024
1025         /* This should be a message for the prefix route */
1026         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6,
1027             (struct sockaddr *)&c->mask6, NULL);
1028
1029         /* gateway should be link sdl with ifindex of an address interface */
1030         verify_link_gateway(rtm, c->ifindex);
1031
1032         /* TODO: PINNED? */
1033         int expected_rt_flags = RTF_UP | RTF_DONE;
1034         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1035 }
1036
1037 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,
1038     "Tests ordering of the messages for IPv6 global unicast ifaddr assignment");
1039
1040 ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)
1041 {
1042         DECLARE_TEST_VARS;
1043
1044         c = presetup_ipv6_iface(tc);
1045
1046         c->rtsock_fd = rtsock_setup_socket();
1047
1048         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1049
1050         int count = 0, tries = 0;
1051
1052         enum msgtype {
1053                 MSG_IFADDR,
1054                 MSG_HOSTROUTE,
1055                 MSG_PREFIXROUTE,
1056                 MSG_MAX,
1057         };
1058
1059         int msg_array[MSG_MAX];
1060
1061         bzero(msg_array, sizeof(msg_array));
1062
1063         while (count < 3 && tries < 20) {
1064                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1065                 tries++;
1066                 /* Classify */
1067                 if (rtm->rtm_type == RTM_NEWADDR) {
1068                         RLOG("MSG_IFADDR: %d", count);
1069                         msg_array[MSG_IFADDR] = count++;
1070                         continue;
1071                 }
1072
1073                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1074                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1075                         RLOG("MSG_PREFIXROUTE: %d", count);
1076                         msg_array[MSG_PREFIXROUTE] = count++;
1077                         continue;
1078                 }
1079
1080                 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) {
1081                         RLOG("MSG_HOSTROUTE: %d", count);
1082                         msg_array[MSG_HOSTROUTE] = count++;
1083                         continue;
1084                 }
1085
1086                 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1087                     tries);
1088         }
1089
1090         /* TODO: verify multicast */
1091         ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count);
1092         ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1093 }
1094
1095 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,
1096     "Tests validness for /128 host route removal after ifaddr removal");
1097
1098 ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)
1099 {
1100         DECLARE_TEST_VARS;
1101
1102         c = presetup_ipv6_iface(tc);
1103
1104         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1105
1106         c->rtsock_fd = rtsock_setup_socket();
1107
1108         ret = iface_delete_addr(c->ifname, c->addr6_str);
1109
1110         while (true) {
1111                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1112                 if ((rtm->rtm_type == RTM_DELETE) &&
1113                     ((rtm->rtm_flags & RTF_LLINFO) == 0) &&
1114                     rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL)
1115                         break;
1116         }
1117         /* This should be a message for the host route */
1118
1119         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL);
1120         rtsock_validate_pid_kernel(rtm);
1121         /* No netmask should be set */
1122         RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1123
1124         /* gateway should be link sdl with ifindex of an address interface */
1125         verify_link_gateway(rtm, c->ifindex);
1126
1127         /* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */
1128         int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1129         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags,
1130             "expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags);
1131 }
1132
1133 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,
1134     "Tests validness for the prefix route removal after ifaddr assignment");
1135
1136 ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)
1137 {
1138         DECLARE_TEST_VARS;
1139
1140         c = presetup_ipv6_iface(tc);
1141
1142         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1143
1144         c->rtsock_fd = rtsock_setup_socket();
1145
1146         ret = iface_delete_addr(c->ifname, c->addr6_str);
1147
1148         while (true) {
1149                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1150                 /* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */
1151                 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1152                         break;
1153         }
1154
1155         /* This should be a message for the prefix route */
1156         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6,
1157             (struct sockaddr *)&c->mask6, NULL);
1158
1159         /* gateway should be link sdl with ifindex of an address interface */
1160         verify_link_gateway(rtm, c->ifindex);
1161
1162         int expected_rt_flags = RTF_DONE;
1163         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1164 }
1165
1166 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,
1167     "Tests validness for the prefix route announce after ifaddr assignment");
1168
1169 ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)
1170 {
1171         DECLARE_TEST_VARS;
1172
1173         c = presetup_ipv4_iface(tc);
1174
1175         c->rtsock_fd = rtsock_setup_socket();
1176
1177         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1178
1179         /*
1180          * Multiple RTM_ADD messages will be generated:
1181          * 1) lladdr mapping (RTF_LLDATA)
1182          * 3) prefix route
1183          */
1184
1185         while (true) {
1186                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1187                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1188                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1189                         break;
1190         }
1191
1192         /* This should be a message for the prefix route */
1193         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4,
1194             (struct sockaddr *)&c->mask4, NULL);
1195
1196         /* gateway should be link sdl with ifindex of an address interface */
1197         verify_link_gateway(rtm, c->ifindex);
1198
1199         int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1200         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1201 }
1202
1203 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,
1204     "Tests ordering of the messages for IPv4 unicast ifaddr assignment");
1205
1206 ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)
1207 {
1208         DECLARE_TEST_VARS;
1209
1210         c = presetup_ipv4_iface(tc);
1211
1212         c->rtsock_fd = rtsock_setup_socket();
1213
1214         ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1215
1216         int count = 0, tries = 0;
1217
1218         enum msgtype {
1219                 MSG_IFADDR,
1220                 MSG_PREFIXROUTE,
1221                 MSG_MAX,
1222         };
1223
1224         int msg_array[MSG_MAX];
1225
1226         bzero(msg_array, sizeof(msg_array));
1227
1228         while (count < 2 && tries < 20) {
1229                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1230                 tries++;
1231                 /* Classify */
1232                 if (rtm->rtm_type == RTM_NEWADDR) {
1233                         RLOG("MSG_IFADDR: %d", count);
1234                         msg_array[MSG_IFADDR] = count++;
1235                         continue;
1236                 }
1237
1238                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1239                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1240                         RLOG("MSG_PREFIXROUTE: %d", count);
1241                         msg_array[MSG_PREFIXROUTE] = count++;
1242                         continue;
1243                 }
1244
1245                 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1246                     tries);
1247         }
1248
1249         /* TODO: verify multicast */
1250         ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count);
1251         ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1252 }
1253
1254 RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,
1255     "Tests validness for the prefix route removal after ifaddr assignment");
1256
1257 ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)
1258 {
1259         DECLARE_TEST_VARS;
1260
1261         c = presetup_ipv4_iface(tc);
1262
1263
1264         ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1265
1266         c->rtsock_fd = rtsock_setup_socket();
1267
1268         ret = iface_delete_addr(c->ifname, c->addr4_str);
1269
1270         while (true) {
1271                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1272                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1273                 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1274                         break;
1275         }
1276
1277         /* This should be a message for the prefix route */
1278         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4,
1279             (struct sockaddr *)&c->mask4, NULL);
1280
1281         /* gateway should be link sdl with ifindex of an address interface */
1282         verify_link_gateway(rtm, c->ifindex);
1283
1284         int expected_rt_flags = RTF_DONE | RTF_PINNED;
1285         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1286 }
1287
1288
1289 ATF_TP_ADD_TCS(tp)
1290 {
1291         ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success);
1292         ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success);
1293         ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure);
1294         ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure);
1295         ATF_TP_ADD_TC(tp, rtm_add_v4_no_rtf_host_failure);
1296         ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success);
1297         ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success);
1298         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success);
1299         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success);
1300         ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);
1301         ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);
1302         ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);
1303         ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);
1304         /* ifaddr tests */
1305         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);
1306         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);
1307         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success);
1308         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success);
1309         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success);
1310         ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success);
1311         ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success);
1312         /* temporal routes */
1313         ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success);
1314         ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success);
1315
1316         return (atf_no_error());
1317 }
1318