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