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