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