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