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