]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/net/routing/test_rtsock_l3.c
libarchive: merge from vendor branch
[FreeBSD/FreeBSD.git] / tests / sys / net / routing / test_rtsock_l3.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019 Alexander V. Chernikov
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #include "rtsock_common.h"
31 #include "rtsock_config.h"
32 #include "sys/types.h"
33 #include <sys/time.h>
34 #include <sys/ioctl.h>
35
36 #include "net/bpf.h"
37
38 static void
39 jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
40 {
41         char vnet_name[512];
42
43         snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
44         RLOG("jumping to %s", vnet_name);
45
46         vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
47
48         /* Update ifindex cache */
49         c->ifindex = if_nametoindex(c->ifname);
50 }
51
52 static inline struct rtsock_test_config *
53 presetup_ipv6_iface(const atf_tc_t *tc)
54 {
55         struct rtsock_test_config *c;
56         int ret;
57
58         c = config_setup(tc, NULL);
59
60         jump_vnet(c, tc);
61
62         ret = iface_turn_up(c->ifname);
63         ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
64
65         ret = iface_enable_ipv6(c->ifname);
66         ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
67         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