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 1424