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