2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2019 Alexander V. Chernikov
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
30 #include "rtsock_common.h"
31 #include "rtsock_config.h"
32 #include "sys/types.h"
34 #include <sys/ioctl.h>
39 jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
43 snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
44 RLOG("jumping to %s", vnet_name);
46 vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
48 /* Update ifindex cache */
49 c->ifindex = if_nametoindex(c->ifname);
52 static inline struct rtsock_test_config *
53 presetup_ipv6_iface(const atf_tc_t *tc)
55 struct rtsock_test_config *c;
58 c = config_setup(tc, NULL);
62 ret = iface_turn_up(c->ifname);
63 ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
65 ret = iface_enable_ipv6(c->ifname);
66 ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
71 static inline struct rtsock_test_config *
72 presetup_ipv6(const atf_tc_t *tc)
74 struct rtsock_test_config *c;
77 c = presetup_ipv6_iface(tc);
79 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
81 c->rtsock_fd = rtsock_setup_socket();
86 static inline struct rtsock_test_config *
87 presetup_ipv4_iface(const atf_tc_t *tc)
89 struct rtsock_test_config *c;
92 c = config_setup(tc, NULL);
96 ret = iface_turn_up(c->ifname);
97 ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
102 static inline struct rtsock_test_config *
103 presetup_ipv4(const atf_tc_t *tc)
105 struct rtsock_test_config *c;
108 c = presetup_ipv4_iface(tc);
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");
114 c->rtsock_fd = rtsock_setup_socket();
121 prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst,
122 struct sockaddr_in *mask, struct sockaddr_in *gw)
124 /* Create IPv4 subnetwork with smaller prefix */
125 sa_fill_mask4(mask, c->plen4 + 1);
127 /* Calculate GW as last-net-address - 1 */
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);
136 prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst,
137 struct sockaddr_in6 *mask, struct sockaddr_in6 *gw)
139 /* Create IPv6 subnetwork with smaller prefix */
140 sa_fill_mask6(mask, c->plen6 + 1);
142 /* Calculate GW as last-net-address - 1 */
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);
150 sa_print((struct sockaddr *)dst, 0);
151 sa_print((struct sockaddr *)mask, 0);
152 sa_print((struct sockaddr *)gw, 0);
156 prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
157 struct sockaddr *mask, struct sockaddr *gw)
160 rtsock_prepare_route_message(rtm, cmd, dst, mask, gw);
162 if (cmd == RTM_ADD || cmd == RTM_CHANGE)
163 rtm->rtm_flags |= RTF_STATIC;
167 verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
168 struct sockaddr *mask, struct sockaddr *gw)
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);
182 /* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */
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);
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));
195 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg);
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);
207 verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags)
209 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex,
210 "expected ifindex %d, got %d", ifindex, rtm->rtm_index);
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),
216 rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags),
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);
227 verify_link_gateway(struct rt_msghdr *rtm, int ifindex)
230 struct sockaddr_dl *sdl;
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);
241 #define DECLARE_TEST_VARS \
243 struct rtsock_test_config *c; \
244 struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \
245 struct sockaddr *sa; \
249 #define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)
250 #define CLEANUP_AFTER_TEST config_generic_cleanup(tc)
252 #define RTM_DECLARE_ROOT_TEST(_name, _descr) \
253 ATF_TC_WITH_CLEANUP(_name); \
254 ATF_TC_HEAD(_name, tc) \
256 DESCRIBE_ROOT_TEST(_descr); \
258 ATF_TC_CLEANUP(_name, tc) \
260 CLEANUP_AFTER_TEST; \
263 ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success);
264 ATF_TC_HEAD(rtm_get_v4_exact_success, tc)
266 DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix");
269 ATF_TC_BODY(rtm_get_v4_exact_success, tc)
273 c = presetup_ipv4(tc);
275 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
276 (struct sockaddr *)&c->mask4, NULL);
278 rtsock_send_rtm(c->rtsock_fd, rtm);
280 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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}}
290 verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
291 (struct sockaddr *)&c->mask4, NULL);
293 verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
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);
304 ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc)
309 ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success);
310 ATF_TC_HEAD(rtm_get_v4_lpm_success, tc)
312 DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix");
315 ATF_TC_BODY(rtm_get_v4_lpm_success, tc)
319 c = presetup_ipv4(tc);
321 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL);
323 rtsock_send_rtm(c->rtsock_fd, rtm);
325 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
328 * RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED>
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
334 verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
335 (struct sockaddr *)&c->mask4, NULL);
337 verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
340 ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc)
346 ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure);
347 ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)
350 DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr");
353 ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)
356 struct rtsock_config_options co;
358 bzero(&co, sizeof(co));
359 co.num_interfaces = 0;
361 c = config_setup(tc,&co);
362 c->rtsock_fd = rtsock_setup_socket();
364 rtsock_prepare_route_message(rtm, RTM_GET, NULL,
365 (struct sockaddr *)&c->mask4, NULL);
366 rtsock_update_rtm_len(rtm);
368 ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
371 ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc)
376 ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_failure);
377 ATF_TC_HEAD(rtm_get_v4_hostbits_failure, tc)
379 DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set");
382 ATF_TC_BODY(rtm_get_v4_hostbits_failure, tc)
386 if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
387 atf_tc_expect_fail("Needs https://reviews.freebsd.org/D28886");
389 c = presetup_ipv4(tc);
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);
396 ATF_CHECK_ERRNO(ESRCH, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
399 ATF_TC_CLEANUP(rtm_get_v4_hostbits_failure, tc)
404 ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);
405 ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)
407 DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");
410 ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)
414 c = presetup_ipv4(tc);
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);
422 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
423 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
425 rtsock_send_rtm(c->rtsock_fd, rtm);
426 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
429 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
431 * sockaddrs: <DST,GATEWAY,NETMASK>
432 * 192.0.2.0 192.0.2.254 255.255.255.128
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);
441 ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)
446 RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_failure,
447 "Tests failure with netmask sa and RTF_HOST inconsistency");
449 ATF_TC_BODY(rtm_add_v4_no_rtf_host_failure, tc)
453 if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
454 atf_tc_expect_fail("Needs https://reviews.freebsd.org/D28886");
456 c = presetup_ipv4(tc);
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);
464 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
465 NULL, (struct sockaddr *)&gw4);
466 rtsock_update_rtm_len(rtm);
468 /* RTF_HOST is NOT specified, while netmask is empty */
470 ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen));
473 ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);
474 ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)
476 DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");
479 ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)
483 c = presetup_ipv4(tc);
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);
491 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
492 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
494 rtsock_send_rtm(c->rtsock_fd, rtm);
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);
500 rtsock_send_rtm(c->rtsock_fd, rtm);
502 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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}}
511 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
512 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
514 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
517 ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
522 RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
523 "Tests IPv4 gateway change");
525 ATF_TC_BODY(rtm_change_v4_gw_success, tc)
528 struct rtsock_config_options co;
530 bzero(&co, sizeof(co));
531 co.num_interfaces = 2;
533 c = config_setup(tc, &co);
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]);
541 ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
542 ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
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");
548 c->rtsock_fd = rtsock_setup_socket();
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);
556 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
557 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
559 rtsock_send_rtm(c->rtsock_fd, rtm);
560 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
562 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
563 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
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);
571 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
573 verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
574 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
576 verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
577 RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
579 /* Verify the change has actually taken place */
580 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
581 (struct sockaddr *)&mask4, NULL);
583 rtsock_send_rtm(c->rtsock_fd, rtm);
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}}
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);
599 RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
600 "Tests IPv4 path mtu change");
602 ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
606 unsigned long test_mtu = 1442;
608 c = presetup_ipv4(tc);
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);
616 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
617 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
619 rtsock_send_rtm(c->rtsock_fd, rtm);
620 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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;
628 rtsock_send_rtm(c->rtsock_fd, rtm);
629 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
631 verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
632 (struct sockaddr *)&mask4, NULL);
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);
637 /* Verify the change has actually taken place */
638 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
639 (struct sockaddr *)&mask4, NULL);
641 rtsock_send_rtm(c->rtsock_fd, rtm);
642 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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);
648 RTM_DECLARE_ROOT_TEST(rtm_change_v4_flags_success,
649 "Tests IPv4 path flags change");
651 ATF_TC_BODY(rtm_change_v4_flags_success, tc)
655 uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
656 uint32_t desired_flags;
658 c = presetup_ipv4(tc);
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);
666 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
667 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
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);
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;
681 rtsock_send_rtm(c->rtsock_fd, rtm);
682 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
684 /* Verify updated flags */
685 verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
687 /* Verify the change has actually taken place */
688 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
689 (struct sockaddr *)&mask4, NULL);
691 rtsock_send_rtm(c->rtsock_fd, rtm);
692 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
694 verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
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)
701 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
704 ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)
708 c = presetup_ipv6(tc);
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);
716 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
717 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
719 rtsock_send_rtm(c->rtsock_fd, rtm);
720 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
723 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
725 * sockaddrs: <DST,GATEWAY,NETMASK>
726 * 192.0.2.0 192.0.2.254 255.255.255.128
729 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
730 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
732 verify_route_message_extra(rtm, c->ifindex,
733 RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
736 ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)
741 ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);
742 ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)
745 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");
748 ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)
752 c = presetup_ipv6(tc);
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);
760 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
761 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
763 rtsock_send_rtm(c->rtsock_fd, rtm);
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);
769 rtsock_send_rtm(c->rtsock_fd, rtm);
770 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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}}
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);
785 ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
790 RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
791 "Tests IPv6 gateway change");
793 ATF_TC_BODY(rtm_change_v6_gw_success, tc)
796 struct rtsock_config_options co;
798 bzero(&co, sizeof(co));
799 co.num_interfaces = 2;
801 c = config_setup(tc, &co);
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]);
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]);
814 ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
815 ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
817 ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
818 ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
820 c->rtsock_fd = rtsock_setup_socket();
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);
828 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
829 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
831 rtsock_send_rtm(c->rtsock_fd, rtm);
832 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
834 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
835 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
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);
843 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
845 verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
846 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
848 verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
849 RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
851 /* Verify the change has actually taken place */
852 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
853 (struct sockaddr *)&mask6, NULL);
855 rtsock_send_rtm(c->rtsock_fd, rtm);
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}}
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);
870 RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
871 "Tests IPv6 path mtu change");
873 ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
877 unsigned long test_mtu = 1442;
879 c = presetup_ipv6(tc);
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);
887 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
888 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
891 rtsock_send_rtm(c->rtsock_fd, rtm);
892 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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;
900 rtsock_send_rtm(c->rtsock_fd, rtm);
901 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
903 verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
904 (struct sockaddr *)&mask6, NULL);
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);
909 /* Verify the change has actually taken place */
910 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
911 (struct sockaddr *)&mask6, NULL);
913 rtsock_send_rtm(c->rtsock_fd, rtm);
914 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
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);
920 RTM_DECLARE_ROOT_TEST(rtm_change_v6_flags_success,
921 "Tests IPv6 path flags change");
923 ATF_TC_BODY(rtm_change_v6_flags_success, tc)
927 uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
928 uint32_t desired_flags;
930 c = presetup_ipv6(tc);
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);
938 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
939 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
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);
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;
953 rtsock_send_rtm(c->rtsock_fd, rtm);
954 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
956 /* Verify updated flags */
957 verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
959 /* Verify the change has actually taken place */
960 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
961 (struct sockaddr *)&mask6, NULL);
963 rtsock_send_rtm(c->rtsock_fd, rtm);
964 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
966 verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
969 ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
970 ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
972 DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");
975 ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)
979 c = presetup_ipv4(tc);
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);
987 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
988 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
990 /* Set expire time to now */
992 gettimeofday(&tv, NULL);
993 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
994 rtm->rtm_inits |= RTV_EXPIRE;
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");
1001 /* The next should be route deletion */
1002 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1004 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
1005 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
1007 verify_route_message_extra(rtm, c->ifindex,
1008 RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1011 ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)
1016 ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);
1017 ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)
1019 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
1022 ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)
1026 c = presetup_ipv6(tc);
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);
1034 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
1035 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1037 /* Set expire time to now */
1039 gettimeofday(&tv, NULL);
1040 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
1041 rtm->rtm_inits |= RTV_EXPIRE;
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");
1048 /* The next should be route deletion */
1049 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1051 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
1052 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1054 verify_route_message_extra(rtm, c->ifindex,
1055 RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1058 ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)
1063 /* Interface address messages tests */
1065 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,
1066 "Tests validness for /128 host route announce after ifaddr assignment");
1068 ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)
1072 c = presetup_ipv6_iface(tc);
1074 c->rtsock_fd = rtsock_setup_socket();
1076 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1079 * There will be multiple.
1080 * RTM_ADD without llinfo.
1084 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1085 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))
1088 /* This should be a message for the host route */
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");
1095 /* gateway should be link sdl with ifindex of an address interface */
1096 verify_link_gateway(rtm, c->ifindex);
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);
1102 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,
1103 "Tests validness for the prefix route announce after ifaddr assignment");
1105 ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)
1109 c = presetup_ipv6_iface(tc);
1111 c->rtsock_fd = rtsock_setup_socket();
1113 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1116 * Multiple RTM_ADD messages will be generated:
1117 * 1) lladdr mapping (RTF_LLDATA)
1118 * 2) host route (one w/o netmask)
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)))
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);
1133 /* gateway should be link sdl with ifindex of an address interface */
1134 verify_link_gateway(rtm, c->ifindex);
1136 int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1137 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1140 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,
1141 "Tests ordering of the messages for IPv6 global unicast ifaddr assignment");
1143 ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)
1147 c = presetup_ipv6_iface(tc);
1149 c->rtsock_fd = rtsock_setup_socket();
1151 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1153 int count = 0, tries = 0;
1162 int msg_array[MSG_MAX];
1164 bzero(msg_array, sizeof(msg_array));
1166 while (count < 3 && tries < 20) {
1167 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1170 if (rtm->rtm_type == RTM_NEWADDR) {
1171 RLOG("MSG_IFADDR: %d", count);
1172 msg_array[MSG_IFADDR] = count++;
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++;
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++;
1189 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
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");
1198 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,
1199 "Tests validness for /128 host route removal after ifaddr removal");
1201 ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)
1205 c = presetup_ipv6_iface(tc);
1207 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1209 c->rtsock_fd = rtsock_setup_socket();
1211 ret = iface_delete_addr(c->ifname, c->addr6_str);
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)
1220 /* This should be a message for the host route */
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");
1227 /* gateway should be link sdl with ifindex of an address interface */
1228 verify_link_gateway(rtm, c->ifindex);
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);
1236 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,
1237 "Tests validness for the prefix route removal after ifaddr assignment");
1239 ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)
1243 c = presetup_ipv6_iface(tc);
1245 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1247 c->rtsock_fd = rtsock_setup_socket();
1249 ret = iface_delete_addr(c->ifname, c->addr6_str);
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)))
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);
1262 /* gateway should be link sdl with ifindex of an address interface */
1263 verify_link_gateway(rtm, c->ifindex);
1265 int expected_rt_flags = RTF_DONE | RTF_PINNED;
1266 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1269 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,
1270 "Tests validness for the prefix route announce after ifaddr assignment");
1272 ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)
1276 c = presetup_ipv4_iface(tc);
1278 c->rtsock_fd = rtsock_setup_socket();
1280 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1283 * Multiple RTM_ADD messages will be generated:
1284 * 1) lladdr mapping (RTF_LLDATA)
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)))
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);
1299 /* gateway should be link sdl with ifindex of an address interface */
1300 verify_link_gateway(rtm, c->ifindex);
1302 int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1303 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1306 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,
1307 "Tests ordering of the messages for IPv4 unicast ifaddr assignment");
1309 ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)
1313 c = presetup_ipv4_iface(tc);
1315 c->rtsock_fd = rtsock_setup_socket();
1317 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1319 int count = 0, tries = 0;
1327 int msg_array[MSG_MAX];
1329 bzero(msg_array, sizeof(msg_array));
1331 while (count < 2 && tries < 20) {
1332 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1335 if (rtm->rtm_type == RTM_NEWADDR) {
1336 RLOG("MSG_IFADDR: %d", count);
1337 msg_array[MSG_IFADDR] = count++;
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++;
1348 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
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");
1357 RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,
1358 "Tests validness for the prefix route removal after ifaddr assignment");
1360 ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)
1364 c = presetup_ipv4_iface(tc);
1367 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1369 c->rtsock_fd = rtsock_setup_socket();
1371 ret = iface_delete_addr(c->ifname, c->addr4_str);
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)))
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);
1384 /* gateway should be link sdl with ifindex of an address interface */
1385 verify_link_gateway(rtm, c->ifindex);
1387 int expected_rt_flags = RTF_DONE | RTF_PINNED;
1388 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
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);
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);
1421 return (atf_no_error());