]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/net/routing/test_rtsock_l3.c
zfs: merge openzfs/zfs@ef83e07db (zfs-2.1-release) into stable/13
[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         if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
387                 atf_tc_expect_fail("Needs https://reviews.freebsd.org/D28886");
388
389         c = presetup_ipv4(tc);
390
391         /* Q the same prefix */
392         rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4,
393             (struct sockaddr *)&c->mask4, NULL);
394         rtsock_update_rtm_len(rtm);
395
396         ATF_CHECK_ERRNO(ESRCH, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
397 }
398
399 ATF_TC_CLEANUP(rtm_get_v4_hostbits_failure, tc)
400 {
401         CLEANUP_AFTER_TEST;
402 }
403
404 ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);
405 ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)
406 {
407         DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");
408 }
409
410 ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)
411 {
412         DECLARE_TEST_VARS;
413
414         c = presetup_ipv4(tc);
415
416         /* Create IPv4 subnetwork with smaller prefix */
417         struct sockaddr_in mask4;
418         struct sockaddr_in net4;
419         struct sockaddr_in gw4;
420         prepare_v4_network(c, &net4, &mask4, &gw4);
421
422         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
423             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
424
425         rtsock_send_rtm(c->rtsock_fd, rtm);
426         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
427
428         /*
429          * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
430          * locks:  inits:
431          * sockaddrs: <DST,GATEWAY,NETMASK>
432          *  192.0.2.0 192.0.2.254 255.255.255.128
433          */
434
435         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
436             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
437         verify_route_message_extra(rtm, c->ifindex,
438             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
439 }
440
441 ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)
442 {
443         CLEANUP_AFTER_TEST;
444 }
445
446 RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_failure,
447     "Tests failure with netmask sa and RTF_HOST inconsistency");
448
449 ATF_TC_BODY(rtm_add_v4_no_rtf_host_failure, tc)
450 {
451         DECLARE_TEST_VARS;
452
453         if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
454                 atf_tc_expect_fail("Needs https://reviews.freebsd.org/D28886");
455
456         c = presetup_ipv4(tc);
457
458         /* Create IPv4 subnetwork with smaller prefix */
459         struct sockaddr_in mask4;
460         struct sockaddr_in net4;
461         struct sockaddr_in gw4;
462         prepare_v4_network(c, &net4, &mask4, &gw4);
463
464         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
465             NULL, (struct sockaddr *)&gw4);
466         rtsock_update_rtm_len(rtm);
467
468         /* RTF_HOST is NOT specified, while netmask is empty */
469
470         ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
471 }
472
473 ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);
474 ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)
475 {
476         DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");
477 }
478
479 ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)
480 {
481         DECLARE_TEST_VARS;
482
483         c = presetup_ipv4(tc);
484
485         /* Create IPv4 subnetwork with smaller prefix */
486         struct sockaddr_in mask4;
487         struct sockaddr_in net4;
488         struct sockaddr_in gw4;
489         prepare_v4_network(c, &net4, &mask4, &gw4);
490
491         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
492             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
493
494         rtsock_send_rtm(c->rtsock_fd, rtm);
495
496         /* Route has been added successfully, try to delete it */
497         prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
498             (struct sockaddr *)&mask4, NULL);
499
500         rtsock_send_rtm(c->rtsock_fd, rtm);
501
502         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
503
504         /*
505          * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
506          * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
507          *  af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
508          *  af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
509          *  af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
510          */
511         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
512             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
513
514         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
515 }
516
517 ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
518 {
519         CLEANUP_AFTER_TEST;
520 }
521
522 RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
523     "Tests IPv4 gateway change");
524
525 ATF_TC_BODY(rtm_change_v4_gw_success, tc)
526 {
527         DECLARE_TEST_VARS;
528         struct rtsock_config_options co;
529
530         bzero(&co, sizeof(co));
531         co.num_interfaces = 2;
532
533         c = config_setup(tc, &co);
534         jump_vnet(c, tc);
535
536         ret = iface_turn_up(c->ifnames[0]);
537         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
538         ret = iface_turn_up(c->ifnames[1]);
539         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
540
541         ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
542         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
543
544         /* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */
545         ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);
546         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
547
548         c->rtsock_fd = rtsock_setup_socket();
549
550         /* Create IPv4 subnetwork with smaller prefix */
551         struct sockaddr_in mask4;
552         struct sockaddr_in net4;
553         struct sockaddr_in gw4;
554         prepare_v4_network(c, &net4, &mask4, &gw4);
555
556         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
557             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
558
559         rtsock_send_rtm(c->rtsock_fd, rtm);
560         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
561
562         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
563             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
564
565         /* Change gateway to the one on desiding on the other interface */
566         inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);
567         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
568             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
569         rtsock_send_rtm(c->rtsock_fd, rtm);
570
571         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
572
573         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
574             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
575
576         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
577             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
578
579         /* Verify the change has actually taken place */
580         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
581             (struct sockaddr *)&mask4, NULL);
582
583         rtsock_send_rtm(c->rtsock_fd, rtm);
584
585         /*
586          * RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
587          *  sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
588          *  af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}
589          *  af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}
590          *  af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}
591          */
592
593         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
594         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
595             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
596
597 }
598
599 RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
600     "Tests IPv4 path mtu change");
601
602 ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
603 {
604         DECLARE_TEST_VARS;
605
606         unsigned long test_mtu = 1442;
607
608         c = presetup_ipv4(tc);
609
610         /* Create IPv4 subnetwork with smaller prefix */
611         struct sockaddr_in mask4;
612         struct sockaddr_in net4;
613         struct sockaddr_in gw4;
614         prepare_v4_network(c, &net4, &mask4, &gw4);
615
616         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
617             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
618
619         rtsock_send_rtm(c->rtsock_fd, rtm);
620         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
621
622         /* Change MTU */
623         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
624             (struct sockaddr *)&mask4, NULL);
625         rtm->rtm_inits |= RTV_MTU;
626         rtm->rtm_rmx.rmx_mtu = test_mtu;
627
628         rtsock_send_rtm(c->rtsock_fd, rtm);
629         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
630
631         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
632             (struct sockaddr *)&mask4, NULL);
633
634         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
635             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
636
637         /* Verify the change has actually taken place */
638         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
639             (struct sockaddr *)&mask4, NULL);
640
641         rtsock_send_rtm(c->rtsock_fd, rtm);
642         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
643
644         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
645             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
646 }
647
648 RTM_DECLARE_ROOT_TEST(rtm_change_v4_flags_success,
649     "Tests IPv4 path flags change");
650
651 ATF_TC_BODY(rtm_change_v4_flags_success, tc)
652 {
653         DECLARE_TEST_VARS;
654
655         uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
656         uint32_t desired_flags;
657
658         c = presetup_ipv4(tc);
659
660         /* Create IPv4 subnetwork with smaller prefix */
661         struct sockaddr_in mask4;
662         struct sockaddr_in net4;
663         struct sockaddr_in gw4;
664         prepare_v4_network(c, &net4, &mask4, &gw4);
665
666         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
667             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
668
669         /* Set test flags during route addition */
670         desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
671         rtm->rtm_flags |= test_flags;
672         rtsock_send_rtm(c->rtsock_fd, rtm);
673         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
674
675         /* Change flags */
676         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
677             (struct sockaddr *)&mask4, NULL);
678         rtm->rtm_flags &= ~test_flags;
679         desired_flags &= ~test_flags;
680
681         rtsock_send_rtm(c->rtsock_fd, rtm);
682         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
683
684         /* Verify updated flags */
685         verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
686
687         /* Verify the change has actually taken place */
688         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
689             (struct sockaddr *)&mask4, NULL);
690
691         rtsock_send_rtm(c->rtsock_fd, rtm);
692         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
693
694         verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
695 }
696
697
698 ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);
699 ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)
700 {
701         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
702 }
703
704 ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)
705 {
706         DECLARE_TEST_VARS;
707
708         c = presetup_ipv6(tc);
709
710         /* Create IPv6 subnetwork with smaller prefix */
711         struct sockaddr_in6 mask6;
712         struct sockaddr_in6 net6;
713         struct sockaddr_in6 gw6;
714         prepare_v6_network(c, &net6, &mask6, &gw6);
715
716         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
717             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
718
719         rtsock_send_rtm(c->rtsock_fd, rtm);
720         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
721
722         /*
723          * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
724          * locks:  inits:
725          * sockaddrs: <DST,GATEWAY,NETMASK>
726          *  192.0.2.0 192.0.2.254 255.255.255.128
727          */
728
729         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
730             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
731
732         verify_route_message_extra(rtm, c->ifindex,
733             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
734 }
735
736 ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)
737 {
738         CLEANUP_AFTER_TEST;
739 }
740
741 ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);
742 ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)
743 {
744
745         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");
746 }
747
748 ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)
749 {
750         DECLARE_TEST_VARS;
751
752         c = presetup_ipv6(tc);
753
754         /* Create IPv6 subnetwork with smaller prefix */
755         struct sockaddr_in6 mask6;
756         struct sockaddr_in6 net6;
757         struct sockaddr_in6 gw6;
758         prepare_v6_network(c, &net6, &mask6, &gw6);
759
760         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
761             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
762
763         rtsock_send_rtm(c->rtsock_fd, rtm);
764
765         /* Route has been added successfully, try to delete it */
766         prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
767             (struct sockaddr *)&mask6, NULL);
768
769         rtsock_send_rtm(c->rtsock_fd, rtm);
770         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
771
772         /*
773          * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
774          * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
775          *  af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
776          *  af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
777          *  af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
778          */
779
780         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
781             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
782         verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
783 }
784
785 ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
786 {
787         CLEANUP_AFTER_TEST;
788 }
789
790 RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
791     "Tests IPv6 gateway change");
792
793 ATF_TC_BODY(rtm_change_v6_gw_success, tc)
794 {
795         DECLARE_TEST_VARS;
796         struct rtsock_config_options co;
797
798         bzero(&co, sizeof(co));
799         co.num_interfaces = 2;
800
801         c = config_setup(tc, &co);
802         jump_vnet(c, tc);
803
804         ret = iface_turn_up(c->ifnames[0]);
805         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
806         ret = iface_turn_up(c->ifnames[1]);
807         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
808
809         ret = iface_enable_ipv6(c->ifnames[0]);
810         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);
811         ret = iface_enable_ipv6(c->ifnames[1]);
812         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);
813
814         ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
815         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
816
817         ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
818         ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
819
820         c->rtsock_fd = rtsock_setup_socket();
821
822         /* Create IPv6 subnetwork with smaller prefix */
823         struct sockaddr_in6 mask6;
824         struct sockaddr_in6 net6;
825         struct sockaddr_in6 gw6;
826         prepare_v6_network(c, &net6, &mask6, &gw6);
827
828         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
829             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
830
831         rtsock_send_rtm(c->rtsock_fd, rtm);
832         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
833
834         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
835             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
836
837         /* Change gateway to the one on residing on the other interface */
838         inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);
839         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
840             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
841         rtsock_send_rtm(c->rtsock_fd, rtm);
842
843         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
844
845         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
846             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
847
848         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
849             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
850
851         /* Verify the change has actually taken place */
852         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
853             (struct sockaddr *)&mask6, NULL);
854
855         rtsock_send_rtm(c->rtsock_fd, rtm);
856
857         /*
858          * RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
859          *  sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
860          *  af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}
861          *  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}}
862          *  af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}
863          */
864
865         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
866         verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
867             RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
868 }
869
870 RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
871     "Tests IPv6 path mtu change");
872
873 ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
874 {
875         DECLARE_TEST_VARS;
876
877         unsigned long test_mtu = 1442;
878
879         c = presetup_ipv6(tc);
880
881         /* Create IPv6 subnetwork with smaller prefix */
882         struct sockaddr_in6 mask6;
883         struct sockaddr_in6 net6;
884         struct sockaddr_in6 gw6;
885         prepare_v6_network(c, &net6, &mask6, &gw6);
886
887         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
888             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
889
890         /* Send route add */
891         rtsock_send_rtm(c->rtsock_fd, rtm);
892         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
893
894         /* Change MTU */
895         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
896             (struct sockaddr *)&mask6, NULL);
897         rtm->rtm_inits |= RTV_MTU;
898         rtm->rtm_rmx.rmx_mtu = test_mtu;
899
900         rtsock_send_rtm(c->rtsock_fd, rtm);
901         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
902
903         verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
904             (struct sockaddr *)&mask6, NULL);
905
906         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
907             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
908
909         /* Verify the change has actually taken place */
910         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
911             (struct sockaddr *)&mask6, NULL);
912
913         rtsock_send_rtm(c->rtsock_fd, rtm);
914         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
915
916         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
917             "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
918 }
919
920 RTM_DECLARE_ROOT_TEST(rtm_change_v6_flags_success,
921     "Tests IPv6 path flags change");
922
923 ATF_TC_BODY(rtm_change_v6_flags_success, tc)
924 {
925         DECLARE_TEST_VARS;
926
927         uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
928         uint32_t desired_flags;
929
930         c = presetup_ipv6(tc);
931
932         /* Create IPv6 subnetwork with smaller prefix */
933         struct sockaddr_in6 mask6;
934         struct sockaddr_in6 net6;
935         struct sockaddr_in6 gw6;
936         prepare_v6_network(c, &net6, &mask6, &gw6);
937
938         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
939             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
940
941         /* Set test flags during route addition */
942         desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
943         rtm->rtm_flags |= test_flags;
944         rtsock_send_rtm(c->rtsock_fd, rtm);
945         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
946
947         /* Change flags */
948         prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
949             (struct sockaddr *)&mask6, NULL);
950         rtm->rtm_flags &= ~test_flags;
951         desired_flags &= ~test_flags;
952
953         rtsock_send_rtm(c->rtsock_fd, rtm);
954         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
955
956         /* Verify updated flags */
957         verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
958
959         /* Verify the change has actually taken place */
960         prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
961             (struct sockaddr *)&mask6, NULL);
962
963         rtsock_send_rtm(c->rtsock_fd, rtm);
964         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
965
966         verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
967 }
968
969 ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
970 ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
971 {
972         DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");
973 }
974
975 ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)
976 {
977         DECLARE_TEST_VARS;
978
979         c = presetup_ipv4(tc);
980
981         /* Create IPv4 subnetwork with smaller prefix */
982         struct sockaddr_in mask4;
983         struct sockaddr_in net4;
984         struct sockaddr_in gw4;
985         prepare_v4_network(c, &net4, &mask4, &gw4);
986
987         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
988             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
989
990         /* Set expire time to now */
991         struct timeval tv;
992         gettimeofday(&tv, NULL);
993         rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
994         rtm->rtm_inits |= RTV_EXPIRE;
995
996         rtsock_send_rtm(c->rtsock_fd, rtm);
997         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
998         ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
999         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
1000
1001         /* The next should be route deletion */
1002         rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1003
1004         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
1005             (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
1006
1007         verify_route_message_extra(rtm, c->ifindex,
1008             RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1009 }
1010
1011 ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)
1012 {
1013         CLEANUP_AFTER_TEST;
1014 }
1015
1016 ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);
1017 ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)
1018 {
1019         DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
1020 }
1021
1022 ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)
1023 {
1024         DECLARE_TEST_VARS;
1025
1026         c = presetup_ipv6(tc);
1027
1028         /* Create IPv6 subnetwork with smaller prefix */
1029         struct sockaddr_in6 mask6;
1030         struct sockaddr_in6 net6;
1031         struct sockaddr_in6 gw6;
1032         prepare_v6_network(c, &net6, &mask6, &gw6);
1033
1034         prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
1035             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1036
1037         /* Set expire time to now */
1038         struct timeval tv;
1039         gettimeofday(&tv, NULL);
1040         rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
1041         rtm->rtm_inits |= RTV_EXPIRE;
1042
1043         rtsock_send_rtm(c->rtsock_fd, rtm);
1044         rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
1045         ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
1046         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
1047
1048         /* The next should be route deletion */
1049         rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1050
1051         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
1052             (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1053
1054         verify_route_message_extra(rtm, c->ifindex,
1055             RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1056 }
1057
1058 ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)
1059 {
1060         CLEANUP_AFTER_TEST;
1061 }
1062
1063 /* Interface address messages tests */
1064
1065 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,
1066     "Tests validness for /128 host route announce after ifaddr assignment");
1067
1068 ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)
1069 {
1070         DECLARE_TEST_VARS;
1071
1072         c = presetup_ipv6_iface(tc);
1073
1074         c->rtsock_fd = rtsock_setup_socket();
1075
1076         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1077
1078         /*
1079          * There will be multiple.
1080          * RTM_ADD without llinfo.
1081          */
1082
1083         while (true) {
1084                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1085                 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))
1086                         break;
1087         }
1088         /* This should be a message for the host route */
1089
1090         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL);
1091         rtsock_validate_pid_kernel(rtm);
1092         /* No netmask should be set */
1093         RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1094
1095         /* gateway should be link sdl with ifindex of an address interface */
1096         verify_link_gateway(rtm, c->ifindex);
1097
1098         int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1099         verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags);
1100 }
1101
1102 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,
1103     "Tests validness for the prefix route announce after ifaddr assignment");
1104
1105 ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)
1106 {
1107         DECLARE_TEST_VARS;
1108
1109         c = presetup_ipv6_iface(tc);
1110
1111         c->rtsock_fd = rtsock_setup_socket();
1112
1113         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1114
1115         /*
1116          * Multiple RTM_ADD messages will be generated:
1117          * 1) lladdr mapping (RTF_LLDATA)
1118          * 2) host route (one w/o netmask)
1119          * 3) prefix route
1120          */
1121
1122         while (true) {
1123                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1124                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1125                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1126                         break;
1127         }
1128
1129         /* This should be a message for the prefix route */
1130         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6,
1131             (struct sockaddr *)&c->mask6, NULL);
1132
1133         /* gateway should be link sdl with ifindex of an address interface */
1134         verify_link_gateway(rtm, c->ifindex);
1135
1136         int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1137         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1138 }
1139
1140 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,
1141     "Tests ordering of the messages for IPv6 global unicast ifaddr assignment");
1142
1143 ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)
1144 {
1145         DECLARE_TEST_VARS;
1146
1147         c = presetup_ipv6_iface(tc);
1148
1149         c->rtsock_fd = rtsock_setup_socket();
1150
1151         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1152
1153         int count = 0, tries = 0;
1154
1155         enum msgtype {
1156                 MSG_IFADDR,
1157                 MSG_HOSTROUTE,
1158                 MSG_PREFIXROUTE,
1159                 MSG_MAX,
1160         };
1161
1162         int msg_array[MSG_MAX];
1163
1164         bzero(msg_array, sizeof(msg_array));
1165
1166         while (count < 3 && tries < 20) {
1167                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1168                 tries++;
1169                 /* Classify */
1170                 if (rtm->rtm_type == RTM_NEWADDR) {
1171                         RLOG("MSG_IFADDR: %d", count);
1172                         msg_array[MSG_IFADDR] = count++;
1173                         continue;
1174                 }
1175
1176                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1177                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1178                         RLOG("MSG_PREFIXROUTE: %d", count);
1179                         msg_array[MSG_PREFIXROUTE] = count++;
1180                         continue;
1181                 }
1182
1183                 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) {
1184                         RLOG("MSG_HOSTROUTE: %d", count);
1185                         msg_array[MSG_HOSTROUTE] = count++;
1186                         continue;
1187                 }
1188
1189                 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1190                     tries);
1191         }
1192
1193         /* TODO: verify multicast */
1194         ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count);
1195         ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1196 }
1197
1198 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,
1199     "Tests validness for /128 host route removal after ifaddr removal");
1200
1201 ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)
1202 {
1203         DECLARE_TEST_VARS;
1204
1205         c = presetup_ipv6_iface(tc);
1206
1207         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1208
1209         c->rtsock_fd = rtsock_setup_socket();
1210
1211         ret = iface_delete_addr(c->ifname, c->addr6_str);
1212
1213         while (true) {
1214                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1215                 if ((rtm->rtm_type == RTM_DELETE) &&
1216                     ((rtm->rtm_flags & RTF_LLINFO) == 0) &&
1217                     rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL)
1218                         break;
1219         }
1220         /* This should be a message for the host route */
1221
1222         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL);
1223         rtsock_validate_pid_kernel(rtm);
1224         /* No netmask should be set */
1225         RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1226
1227         /* gateway should be link sdl with ifindex of an address interface */
1228         verify_link_gateway(rtm, c->ifindex);
1229
1230         /* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */
1231         int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1232         RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags,
1233             "expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags);
1234 }
1235
1236 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,
1237     "Tests validness for the prefix route removal after ifaddr assignment");
1238
1239 ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)
1240 {
1241         DECLARE_TEST_VARS;
1242
1243         c = presetup_ipv6_iface(tc);
1244
1245         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1246
1247         c->rtsock_fd = rtsock_setup_socket();
1248
1249         ret = iface_delete_addr(c->ifname, c->addr6_str);
1250
1251         while (true) {
1252                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1253                 /* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */
1254                 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1255                         break;
1256         }
1257
1258         /* This should be a message for the prefix route */
1259         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6,
1260             (struct sockaddr *)&c->mask6, NULL);
1261
1262         /* gateway should be link sdl with ifindex of an address interface */
1263         verify_link_gateway(rtm, c->ifindex);
1264
1265         int expected_rt_flags = RTF_DONE | RTF_PINNED;
1266         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1267 }
1268
1269 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,
1270     "Tests validness for the prefix route announce after ifaddr assignment");
1271
1272 ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)
1273 {
1274         DECLARE_TEST_VARS;
1275
1276         c = presetup_ipv4_iface(tc);
1277
1278         c->rtsock_fd = rtsock_setup_socket();
1279
1280         ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1281
1282         /*
1283          * Multiple RTM_ADD messages will be generated:
1284          * 1) lladdr mapping (RTF_LLDATA)
1285          * 3) prefix route
1286          */
1287
1288         while (true) {
1289                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1290                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1291                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1292                         break;
1293         }
1294
1295         /* This should be a message for the prefix route */
1296         verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4,
1297             (struct sockaddr *)&c->mask4, NULL);
1298
1299         /* gateway should be link sdl with ifindex of an address interface */
1300         verify_link_gateway(rtm, c->ifindex);
1301
1302         int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1303         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1304 }
1305
1306 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,
1307     "Tests ordering of the messages for IPv4 unicast ifaddr assignment");
1308
1309 ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)
1310 {
1311         DECLARE_TEST_VARS;
1312
1313         c = presetup_ipv4_iface(tc);
1314
1315         c->rtsock_fd = rtsock_setup_socket();
1316
1317         ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1318
1319         int count = 0, tries = 0;
1320
1321         enum msgtype {
1322                 MSG_IFADDR,
1323                 MSG_PREFIXROUTE,
1324                 MSG_MAX,
1325         };
1326
1327         int msg_array[MSG_MAX];
1328
1329         bzero(msg_array, sizeof(msg_array));
1330
1331         while (count < 2 && tries < 20) {
1332                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1333                 tries++;
1334                 /* Classify */
1335                 if (rtm->rtm_type == RTM_NEWADDR) {
1336                         RLOG("MSG_IFADDR: %d", count);
1337                         msg_array[MSG_IFADDR] = count++;
1338                         continue;
1339                 }
1340
1341                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1342                 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1343                         RLOG("MSG_PREFIXROUTE: %d", count);
1344                         msg_array[MSG_PREFIXROUTE] = count++;
1345                         continue;
1346                 }
1347
1348                 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1349                     tries);
1350         }
1351
1352         /* TODO: verify multicast */
1353         ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count);
1354         ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1355 }
1356
1357 RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,
1358     "Tests validness for the prefix route removal after ifaddr assignment");
1359
1360 ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)
1361 {
1362         DECLARE_TEST_VARS;
1363
1364         c = presetup_ipv4_iface(tc);
1365
1366
1367         ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1368
1369         c->rtsock_fd = rtsock_setup_socket();
1370
1371         ret = iface_delete_addr(c->ifname, c->addr4_str);
1372
1373         while (true) {
1374                 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1375                 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1376                 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1377                         break;
1378         }
1379
1380         /* This should be a message for the prefix route */
1381         verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4,
1382             (struct sockaddr *)&c->mask4, NULL);
1383
1384         /* gateway should be link sdl with ifindex of an address interface */
1385         verify_link_gateway(rtm, c->ifindex);
1386
1387         int expected_rt_flags = RTF_DONE | RTF_PINNED;
1388         verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1389 }
1390
1391
1392 ATF_TP_ADD_TCS(tp)
1393 {
1394         ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success);
1395         ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success);
1396         ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure);
1397         ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure);
1398         ATF_TP_ADD_TC(tp, rtm_add_v4_no_rtf_host_failure);
1399         ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success);
1400         ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success);
1401         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success);
1402         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success);
1403         ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);
1404         ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);
1405         ATF_TP_ADD_TC(tp, rtm_change_v4_flags_success);
1406         ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);
1407         ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);
1408         ATF_TP_ADD_TC(tp, rtm_change_v6_flags_success);
1409         /* ifaddr tests */
1410         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);
1411         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);
1412         ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success);
1413         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success);
1414         ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success);
1415         ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success);
1416         ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success);
1417         /* temporal routes */
1418         ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success);
1419         ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success);
1420
1421         return (atf_no_error());
1422 }
1423