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->ifname); 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); 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); 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 357 c = config_setup_base(tc); 358 c->rtsock_fd = rtsock_setup_socket(); 359 360 rtsock_prepare_route_message(rtm, RTM_GET, NULL, 361 (struct sockaddr *)&c->mask4, NULL); 362 rtsock_update_rtm_len(rtm); 363 364 write(c->rtsock_fd, rtm, rtm->rtm_msglen); 365 ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen)); 366 } 367 368 ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc) 369 { 370 CLEANUP_AFTER_TEST; 371 } 372 373 ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_failure); 374 ATF_TC_HEAD(rtm_get_v4_hostbits_failure, tc) 375 { 376 DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set"); 377 } 378 379 ATF_TC_BODY(rtm_get_v4_hostbits_failure, tc) 380 { 381 DECLARE_TEST_VARS; 382 383 c = presetup_ipv4(tc); 384 385 /* Q the same prefix */ 386 rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4, 387 (struct sockaddr *)&c->mask4, NULL); 388 rtsock_update_rtm_len(rtm); 389 390 ATF_CHECK_ERRNO(ESRCH, write(c->rtsock_fd, rtm, rtm->rtm_msglen)); 391 } 392 393 ATF_TC_CLEANUP(rtm_get_v4_hostbits_failure, tc) 394 { 395 CLEANUP_AFTER_TEST; 396 } 397 398 ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success); 399 ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc) 400 { 401 DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP"); 402 } 403 404 ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc) 405 { 406 DECLARE_TEST_VARS; 407 408 c = presetup_ipv4(tc); 409 410 /* Create IPv4 subnetwork with smaller prefix */ 411 struct sockaddr_in mask4; 412 struct sockaddr_in net4; 413 struct sockaddr_in gw4; 414 prepare_v4_network(c, &net4, &mask4, &gw4); 415 416 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 417 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 418 419 rtsock_send_rtm(c->rtsock_fd, rtm); 420 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 421 422 /* 423 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC> 424 * locks: inits: 425 * sockaddrs: <DST,GATEWAY,NETMASK> 426 * 192.0.2.0 192.0.2.254 255.255.255.128 427 */ 428 429 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 430 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 431 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 432 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 433 } 434 435 ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc) 436 { 437 CLEANUP_AFTER_TEST; 438 } 439 440 ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success); 441 ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc) 442 { 443 DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway"); 444 } 445 446 ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, 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 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 460 461 rtsock_send_rtm(c->rtsock_fd, rtm); 462 463 /* Route has been added successfully, try to delete it */ 464 prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 465 (struct sockaddr *)&mask4, NULL); 466 467 rtsock_send_rtm(c->rtsock_fd, rtm); 468 469 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 470 471 /* 472 * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC> 473 * sockaddrs: 0x7 <DST,GATEWAY,NETMASK> 474 * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}} 475 * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}} 476 * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}} 477 */ 478 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 479 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 480 481 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 482 } 483 484 ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc) 485 { 486 CLEANUP_AFTER_TEST; 487 } 488 489 ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success); 490 ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc) 491 { 492 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW"); 493 } 494 495 ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc) 496 { 497 DECLARE_TEST_VARS; 498 499 c = presetup_ipv6(tc); 500 501 /* Create IPv6 subnetwork with smaller prefix */ 502 struct sockaddr_in6 mask6; 503 struct sockaddr_in6 net6; 504 struct sockaddr_in6 gw6; 505 prepare_v6_network(c, &net6, &mask6, &gw6); 506 507 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 508 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 509 510 rtsock_send_rtm(c->rtsock_fd, rtm); 511 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 512 513 /* 514 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC> 515 * locks: inits: 516 * sockaddrs: <DST,GATEWAY,NETMASK> 517 * 192.0.2.0 192.0.2.254 255.255.255.128 518 */ 519 520 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 521 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 522 523 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 524 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 525 } 526 527 ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc) 528 { 529 CLEANUP_AFTER_TEST; 530 } 531 532 ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success); 533 ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc) 534 { 535 536 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway"); 537 } 538 539 ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc) 540 { 541 DECLARE_TEST_VARS; 542 543 c = presetup_ipv6(tc); 544 545 /* Create IPv6 subnetwork with smaller prefix */ 546 struct sockaddr_in6 mask6; 547 struct sockaddr_in6 net6; 548 struct sockaddr_in6 gw6; 549 prepare_v6_network(c, &net6, &mask6, &gw6); 550 551 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 552 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 553 554 rtsock_send_rtm(c->rtsock_fd, rtm); 555 556 /* Route has been added successfully, try to delete it */ 557 prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 558 (struct sockaddr *)&mask6, NULL); 559 560 rtsock_send_rtm(c->rtsock_fd, rtm); 561 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 562 563 /* 564 * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC> 565 * sockaddrs: 0x7 <DST,GATEWAY,NETMASK> 566 * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}} 567 * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}} 568 * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}} 569 */ 570 571 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 572 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 573 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 574 } 575 576 ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc) 577 { 578 CLEANUP_AFTER_TEST; 579 } 580 581 ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success); 582 ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc) 583 { 584 DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set"); 585 } 586 587 ATF_TC_BODY(rtm_add_v4_temporal1_success, tc) 588 { 589 DECLARE_TEST_VARS; 590 591 c = presetup_ipv4(tc); 592 593 /* Create IPv4 subnetwork with smaller prefix */ 594 struct sockaddr_in mask4; 595 struct sockaddr_in net4; 596 struct sockaddr_in gw4; 597 prepare_v4_network(c, &net4, &mask4, &gw4); 598 599 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 600 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 601 602 /* Set expire time to now */ 603 struct timeval tv; 604 gettimeofday(&tv, NULL); 605 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; 606 rtm->rtm_inits |= RTV_EXPIRE; 607 608 rtsock_send_rtm(c->rtsock_fd, rtm); 609 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 610 ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); 611 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); 612 613 /* The next should be route deletion */ 614 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 615 616 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 617 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 618 619 verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_DONE | RTF_STATIC); 620 } 621 622 ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc) 623 { 624 CLEANUP_AFTER_TEST; 625 } 626 627 ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success); 628 ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc) 629 { 630 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW"); 631 } 632 633 ATF_TC_BODY(rtm_add_v6_temporal1_success, tc) 634 { 635 DECLARE_TEST_VARS; 636 637 c = presetup_ipv6(tc); 638 639 /* Create IPv6 subnetwork with smaller prefix */ 640 struct sockaddr_in6 mask6; 641 struct sockaddr_in6 net6; 642 struct sockaddr_in6 gw6; 643 prepare_v6_network(c, &net6, &mask6, &gw6); 644 645 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 646 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 647 648 /* Set expire time to now */ 649 struct timeval tv; 650 gettimeofday(&tv, NULL); 651 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; 652 rtm->rtm_inits |= RTV_EXPIRE; 653 654 rtsock_send_rtm(c->rtsock_fd, rtm); 655 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 656 ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); 657 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); 658 659 /* The next should be route deletion */ 660 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 661 662 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 663 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 664 665 666 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 667 verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_DONE | RTF_STATIC); 668 } 669 670 ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc) 671 { 672 CLEANUP_AFTER_TEST; 673 } 674 675 /* Interface address messages tests */ 676 677 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success, 678 "Tests validness for /128 host route announce after ifaddr assignment"); 679 680 ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc) 681 { 682 DECLARE_TEST_VARS; 683 684 c = presetup_ipv6_iface(tc); 685 686 c->rtsock_fd = rtsock_setup_socket(); 687 688 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 689 690 /* 691 * There will be multiple. 692 * RTM_ADD without llinfo. 693 */ 694 695 while (true) { 696 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 697 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0)) 698 break; 699 } 700 /* This should be a message for the host route */ 701 702 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL); 703 rtsock_validate_pid_kernel(rtm); 704 /* No netmask should be set */ 705 RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set"); 706 707 /* gateway should be link sdl with ifindex of an address interface */ 708 verify_link_gateway(rtm, c->ifindex); 709 710 int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED; 711 verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags); 712 } 713 714 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success, 715 "Tests validness for the prefix route announce after ifaddr assignment"); 716 717 ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc) 718 { 719 DECLARE_TEST_VARS; 720 721 c = presetup_ipv6_iface(tc); 722 723 c->rtsock_fd = rtsock_setup_socket(); 724 725 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 726 727 /* 728 * Multiple RTM_ADD messages will be generated: 729 * 1) lladdr mapping (RTF_LLDATA) 730 * 2) host route (one w/o netmask) 731 * 3) prefix route 732 */ 733 734 while (true) { 735 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 736 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 737 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 738 break; 739 } 740 741 /* This should be a message for the prefix route */ 742 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6, 743 (struct sockaddr *)&c->mask6, NULL); 744 745 /* gateway should be link sdl with ifindex of an address interface */ 746 verify_link_gateway(rtm, c->ifindex); 747 748 /* TODO: PINNED? */ 749 int expected_rt_flags = RTF_UP | RTF_DONE; 750 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 751 } 752 753 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success, 754 "Tests ordering of the messages for IPv6 global unicast ifaddr assignment"); 755 756 ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc) 757 { 758 DECLARE_TEST_VARS; 759 760 c = presetup_ipv6_iface(tc); 761 762 c->rtsock_fd = rtsock_setup_socket(); 763 764 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 765 766 int count = 0, tries = 0; 767 768 enum msgtype { 769 MSG_IFADDR, 770 MSG_HOSTROUTE, 771 MSG_PREFIXROUTE, 772 MSG_MAX, 773 }; 774 775 int msg_array[MSG_MAX]; 776 777 bzero(msg_array, sizeof(msg_array)); 778 779 while (count < 3 && tries < 20) { 780 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 781 tries++; 782 /* Classify */ 783 if (rtm->rtm_type == RTM_NEWADDR) { 784 RLOG("MSG_IFADDR: %d", count); 785 msg_array[MSG_IFADDR] = count++; 786 continue; 787 } 788 789 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 790 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) { 791 RLOG("MSG_PREFIXROUTE: %d", count); 792 msg_array[MSG_PREFIXROUTE] = count++; 793 continue; 794 } 795 796 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) { 797 RLOG("MSG_HOSTROUTE: %d", count); 798 msg_array[MSG_HOSTROUTE] = count++; 799 continue; 800 } 801 802 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type), 803 tries); 804 } 805 806 /* TODO: verify multicast */ 807 ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count); 808 ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first"); 809 } 810 811 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success, 812 "Tests validness for /128 host route removal after ifaddr removal"); 813 814 ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc) 815 { 816 DECLARE_TEST_VARS; 817 818 c = presetup_ipv6_iface(tc); 819 820 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 821 822 c->rtsock_fd = rtsock_setup_socket(); 823 824 ret = iface_delete_addr(c->ifname, c->addr6_str); 825 826 while (true) { 827 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 828 if ((rtm->rtm_type == RTM_DELETE) && 829 ((rtm->rtm_flags & RTF_LLINFO) == 0) && 830 rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL) 831 break; 832 } 833 /* This should be a message for the host route */ 834 835 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL); 836 rtsock_validate_pid_kernel(rtm); 837 /* No netmask should be set */ 838 RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set"); 839 840 /* gateway should be link sdl with ifindex of an address interface */ 841 verify_link_gateway(rtm, c->ifindex); 842 843 /* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */ 844 int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED; 845 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags, 846 "expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags); 847 } 848 849 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success, 850 "Tests validness for the prefix route removal after ifaddr assignment"); 851 852 ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc) 853 { 854 DECLARE_TEST_VARS; 855 856 c = presetup_ipv6_iface(tc); 857 858 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 859 860 c->rtsock_fd = rtsock_setup_socket(); 861 862 ret = iface_delete_addr(c->ifname, c->addr6_str); 863 864 while (true) { 865 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 866 /* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */ 867 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 868 break; 869 } 870 871 /* This should be a message for the prefix route */ 872 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6, 873 (struct sockaddr *)&c->mask6, NULL); 874 875 /* gateway should be link sdl with ifindex of an address interface */ 876 verify_link_gateway(rtm, c->ifindex); 877 878 int expected_rt_flags = RTF_DONE; 879 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 880 } 881 882 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success, 883 "Tests validness for the prefix route announce after ifaddr assignment"); 884 885 ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc) 886 { 887 DECLARE_TEST_VARS; 888 889 c = presetup_ipv4_iface(tc); 890 891 c->rtsock_fd = rtsock_setup_socket(); 892 893 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 894 895 /* 896 * Multiple RTM_ADD messages will be generated: 897 * 1) lladdr mapping (RTF_LLDATA) 898 * 3) prefix route 899 */ 900 901 while (true) { 902 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 903 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 904 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 905 break; 906 } 907 908 /* This should be a message for the prefix route */ 909 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4, 910 (struct sockaddr *)&c->mask4, NULL); 911 912 /* gateway should be link sdl with ifindex of an address interface */ 913 verify_link_gateway(rtm, c->ifindex); 914 915 int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED; 916 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 917 } 918 919 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success, 920 "Tests ordering of the messages for IPv4 unicast ifaddr assignment"); 921 922 ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc) 923 { 924 DECLARE_TEST_VARS; 925 926 c = presetup_ipv4_iface(tc); 927 928 c->rtsock_fd = rtsock_setup_socket(); 929 930 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4); 931 932 int count = 0, tries = 0; 933 934 enum msgtype { 935 MSG_IFADDR, 936 MSG_PREFIXROUTE, 937 MSG_MAX, 938 }; 939 940 int msg_array[MSG_MAX]; 941 942 bzero(msg_array, sizeof(msg_array)); 943 944 while (count < 2 && tries < 20) { 945 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 946 tries++; 947 /* Classify */ 948 if (rtm->rtm_type == RTM_NEWADDR) { 949 RLOG("MSG_IFADDR: %d", count); 950 msg_array[MSG_IFADDR] = count++; 951 continue; 952 } 953 954 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 955 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) { 956 RLOG("MSG_PREFIXROUTE: %d", count); 957 msg_array[MSG_PREFIXROUTE] = count++; 958 continue; 959 } 960 961 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type), 962 tries); 963 } 964 965 /* TODO: verify multicast */ 966 ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count); 967 ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first"); 968 } 969 970 RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success, 971 "Tests validness for the prefix route removal after ifaddr assignment"); 972 973 ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc) 974 { 975 DECLARE_TEST_VARS; 976 977 c = presetup_ipv4_iface(tc); 978 979 980 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4); 981 982 c->rtsock_fd = rtsock_setup_socket(); 983 984 ret = iface_delete_addr(c->ifname, c->addr4_str); 985 986 while (true) { 987 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 988 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 989 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 990 break; 991 } 992 993 /* This should be a message for the prefix route */ 994 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4, 995 (struct sockaddr *)&c->mask4, NULL); 996 997 /* gateway should be link sdl with ifindex of an address interface */ 998 verify_link_gateway(rtm, c->ifindex); 999 1000 int expected_rt_flags = RTF_DONE | RTF_PINNED; 1001 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 1002 } 1003 1004 1005 ATF_TP_ADD_TCS(tp) 1006 { 1007 ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success); 1008 ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success); 1009 ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure); 1010 ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure); 1011 ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success); 1012 ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success); 1013 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success); 1014 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success); 1015 /* ifaddr tests */ 1016 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success); 1017 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success); 1018 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success); 1019 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success); 1020 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success); 1021 ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success); 1022 ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success); 1023 /* temporal routes */ 1024 ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success); 1025 ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success); 1026 1027 return (atf_no_error()); 1028 } 1029 1030