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