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 inline struct rtsock_test_config * 39 presetup_ipv6_iface(const atf_tc_t *tc) 40 { 41 struct rtsock_test_config *c; 42 int ret; 43 44 c = config_setup(tc); 45 46 ret = iface_turn_up(c->ifname); 47 ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname); 48 49 ret = iface_enable_ipv6(c->ifname); 50 ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname); 51 52 return (c); 53 } 54 55 static inline struct rtsock_test_config * 56 presetup_ipv6(const atf_tc_t *tc) 57 { 58 struct rtsock_test_config *c; 59 int ret; 60 61 c = presetup_ipv6_iface(tc); 62 63 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 64 65 c->rtsock_fd = rtsock_setup_socket(); 66 67 return (c); 68 } 69 70 static inline struct rtsock_test_config * 71 presetup_ipv4_iface(const atf_tc_t *tc) 72 { 73 struct rtsock_test_config *c; 74 int ret; 75 76 c = config_setup(tc); 77 78 ret = iface_turn_up(c->ifname); 79 ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname); 80 81 /* Actually open interface, so kernel writes won't fail */ 82 if (c->autocreated_interface) { 83 ret = iface_open(c->ifname); 84 ATF_REQUIRE_MSG(ret >= 0, "unable to open interface %s", c->ifname); 85 } 86 87 return (c); 88 } 89 90 static inline struct rtsock_test_config * 91 presetup_ipv4(const atf_tc_t *tc) 92 { 93 struct rtsock_test_config *c; 94 int ret; 95 96 c = presetup_ipv4_iface(tc); 97 98 /* assumes ifconfig doing IFF_UP */ 99 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4); 100 ATF_REQUIRE_MSG(ret == 0, "ifconfig failed"); 101 102 c->rtsock_fd = rtsock_setup_socket(); 103 104 return (c); 105 } 106 107 108 static void 109 prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst, 110 struct sockaddr_in *mask, struct sockaddr_in *gw) 111 { 112 /* Create IPv4 subnetwork with smaller prefix */ 113 sa_fill_mask4(mask, c->plen4 + 1); 114 *dst = c->net4; 115 /* Calculate GW as last-net-address - 1 */ 116 *gw = c->net4; 117 gw->sin_addr.s_addr = htonl((ntohl(c->net4.sin_addr.s_addr) | ~ntohl(c->mask4.sin_addr.s_addr)) - 1); 118 sa_print((struct sockaddr *)dst, 0); 119 sa_print((struct sockaddr *)mask, 0); 120 sa_print((struct sockaddr *)gw, 0); 121 } 122 123 static void 124 prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst, 125 struct sockaddr_in6 *mask, struct sockaddr_in6 *gw) 126 { 127 /* Create IPv6 subnetwork with smaller prefix */ 128 sa_fill_mask6(mask, c->plen6 + 1); 129 *dst = c->net6; 130 /* Calculate GW as last-net-address - 1 */ 131 *gw = c->net6; 132 #define _s6_addr32 __u6_addr.__u6_addr32 133 gw->sin6_addr._s6_addr32[0] = htonl((ntohl(gw->sin6_addr._s6_addr32[0]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[0]))); 134 gw->sin6_addr._s6_addr32[1] = htonl((ntohl(gw->sin6_addr._s6_addr32[1]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[1]))); 135 gw->sin6_addr._s6_addr32[2] = htonl((ntohl(gw->sin6_addr._s6_addr32[2]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[2]))); 136 gw->sin6_addr._s6_addr32[3] = htonl((ntohl(gw->sin6_addr._s6_addr32[3]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[3])) - 1); 137 #undef _s6_addr32 138 sa_print((struct sockaddr *)dst, 0); 139 sa_print((struct sockaddr *)mask, 0); 140 sa_print((struct sockaddr *)gw, 0); 141 } 142 143 static void 144 prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst, 145 struct sockaddr *mask, struct sockaddr *gw) 146 { 147 148 rtsock_prepare_route_message(rtm, cmd, dst, mask, gw); 149 150 if (cmd == RTM_ADD || cmd == RTM_CHANGE) 151 rtm->rtm_flags |= RTF_STATIC; 152 } 153 154 static void 155 verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst, 156 struct sockaddr *mask, struct sockaddr *gw) 157 { 158 char msg[512]; 159 struct sockaddr *sa; 160 int ret; 161 162 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == cmd, 163 "expected %s message, got %d (%s)", rtsock_print_cmdtype(cmd), 164 rtm->rtm_type, rtsock_print_cmdtype(rtm->rtm_type)); 165 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_errno == 0, 166 "got got errno %d as message reply", rtm->rtm_errno); 167 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->_rtm_spare1 == 0, 168 "expected rtm_spare==0, got %d", rtm->_rtm_spare1); 169 170 /* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */ 171 if (dst != NULL) { 172 sa = rtsock_find_rtm_sa(rtm, RTA_DST); 173 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "DST is not set"); 174 ret = sa_equal_msg(sa, dst, msg, sizeof(msg)); 175 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg); 176 } 177 178 if (mask != NULL) { 179 sa = rtsock_find_rtm_sa(rtm, RTA_NETMASK); 180 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "NETMASK is not set"); 181 ret = sa_equal_msg(sa, mask, msg, sizeof(msg)); 182 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg); 183 } 184 185 if (gw != NULL) { 186 sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY); 187 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set"); 188 ret = sa_equal_msg(sa, gw, msg, sizeof(msg)); 189 RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg); 190 } 191 } 192 193 static void 194 verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags) 195 { 196 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex, 197 "expected ifindex %d, got %d", ifindex, rtm->rtm_index); 198 199 if (rtm->rtm_flags != rtm_flags) { 200 char got_flags[64], expected_flags[64]; 201 rtsock_print_rtm_flags(got_flags, sizeof(got_flags), 202 rtm->rtm_flags); 203 rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags), 204 rtm_flags); 205 206 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == rtm_flags, 207 "expected flags: 0x%X %s, got 0x%X %s", 208 rtm_flags, expected_flags, 209 rtm->rtm_flags, got_flags); 210 } 211 } 212 213 static void 214 verify_link_gateway(struct rt_msghdr *rtm, int ifindex) 215 { 216 struct sockaddr *sa; 217 struct sockaddr_dl *sdl; 218 219 sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY); 220 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set"); 221 RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family); 222 sdl = (struct sockaddr_dl *)sa; 223 RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == ifindex, "GW ifindex is %d", sdl->sdl_index); 224 } 225 226 /* TESTS */ 227 228 #define DECLARE_TEST_VARS \ 229 char buffer[2048]; \ 230 struct rtsock_test_config *c; \ 231 struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \ 232 struct sockaddr *sa; \ 233 int ret; \ 234 \ 235 236 #define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg) 237 #define CLEANUP_AFTER_TEST config_generic_cleanup(config_setup(tc)) 238 239 #define RTM_DECLARE_ROOT_TEST(_name, _descr) \ 240 ATF_TC_WITH_CLEANUP(_name); \ 241 ATF_TC_HEAD(_name, tc) \ 242 { \ 243 DESCRIBE_ROOT_TEST(_descr); \ 244 } \ 245 ATF_TC_CLEANUP(_name, tc) \ 246 { \ 247 CLEANUP_AFTER_TEST; \ 248 } 249 250 ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success); 251 ATF_TC_HEAD(rtm_get_v4_exact_success, tc) 252 { 253 DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix"); 254 } 255 256 ATF_TC_BODY(rtm_get_v4_exact_success, tc) 257 { 258 DECLARE_TEST_VARS; 259 260 c = presetup_ipv4(tc); 261 262 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, 263 (struct sockaddr *)&c->mask4, NULL); 264 265 rtsock_send_rtm(c->rtsock_fd, rtm); 266 267 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 268 269 /* 270 * RTM_GET: Report Metrics: len 240, pid: 45072, seq 42, errno 0, flags: <UP,DONE,PINNED> 271 * sockaddrs: 0x7 <DST,GATEWAY,NETMASK> 272 * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}} 273 * af=link len=54 sdl_index=3 if_name=tap4242 hd={36, 12, 03, 00, 06, 00{49}} 274 * af=inet len=16 addr=255.255.255.0 hd={10, 02, FF{5}, 00{9}} 275 */ 276 277 verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, 278 (struct sockaddr *)&c->mask4, NULL); 279 280 verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED); 281 282 /* Explicitly verify gateway for the interface route */ 283 verify_link_gateway(rtm, c->ifindex); 284 sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY); 285 RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set"); 286 RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family); 287 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; 288 RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == c->ifindex, "GW ifindex is %d", sdl->sdl_index); 289 } 290 291 ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc) 292 { 293 CLEANUP_AFTER_TEST; 294 } 295 296 ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success); 297 ATF_TC_HEAD(rtm_get_v4_lpm_success, tc) 298 { 299 DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix"); 300 } 301 302 ATF_TC_BODY(rtm_get_v4_lpm_success, tc) 303 { 304 DECLARE_TEST_VARS; 305 306 c = presetup_ipv4(tc); 307 308 prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL); 309 310 rtsock_send_rtm(c->rtsock_fd, rtm); 311 312 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 313 314 /* 315 * RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED> 316 * locks: inits: 317 * sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA> 318 * 10.0.0.0 link#1 255.255.255.0 vtnet0:52.54.0.42.f.ef 10.0.0.157 319 */ 320 321 verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, 322 (struct sockaddr *)&c->mask4, NULL); 323 324 verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED); 325 } 326 327 ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc) 328 { 329 CLEANUP_AFTER_TEST; 330 } 331 332 333 ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure); 334 ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc) 335 { 336 337 DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr"); 338 } 339 340 ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc) 341 { 342 DECLARE_TEST_VARS; 343 344 c = config_setup_base(tc); 345 c->rtsock_fd = rtsock_setup_socket(); 346 347 rtsock_prepare_route_message(rtm, RTM_GET, NULL, 348 (struct sockaddr *)&c->mask4, NULL); 349 rtsock_update_rtm_len(rtm); 350 351 write(c->rtsock_fd, rtm, rtm->rtm_msglen); 352 ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen)); 353 } 354 355 ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc) 356 { 357 CLEANUP_AFTER_TEST; 358 } 359 360 ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_failure); 361 ATF_TC_HEAD(rtm_get_v4_hostbits_failure, tc) 362 { 363 DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set"); 364 } 365 366 ATF_TC_BODY(rtm_get_v4_hostbits_failure, tc) 367 { 368 DECLARE_TEST_VARS; 369 370 c = presetup_ipv4(tc); 371 372 /* Q the same prefix */ 373 rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4, 374 (struct sockaddr *)&c->mask4, NULL); 375 rtsock_update_rtm_len(rtm); 376 377 ATF_CHECK_ERRNO(ESRCH, write(c->rtsock_fd, rtm, rtm->rtm_msglen)); 378 } 379 380 ATF_TC_CLEANUP(rtm_get_v4_hostbits_failure, tc) 381 { 382 CLEANUP_AFTER_TEST; 383 } 384 385 ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success); 386 ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc) 387 { 388 DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP"); 389 } 390 391 ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc) 392 { 393 DECLARE_TEST_VARS; 394 395 c = presetup_ipv4(tc); 396 397 /* Create IPv4 subnetwork with smaller prefix */ 398 struct sockaddr_in mask4; 399 struct sockaddr_in net4; 400 struct sockaddr_in gw4; 401 prepare_v4_network(c, &net4, &mask4, &gw4); 402 403 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 404 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 405 406 rtsock_send_rtm(c->rtsock_fd, rtm); 407 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 408 409 /* 410 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC> 411 * locks: inits: 412 * sockaddrs: <DST,GATEWAY,NETMASK> 413 * 192.0.2.0 192.0.2.254 255.255.255.128 414 */ 415 416 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 417 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 418 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 419 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 420 } 421 422 ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc) 423 { 424 CLEANUP_AFTER_TEST; 425 } 426 427 ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success); 428 ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc) 429 { 430 DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway"); 431 } 432 433 ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc) 434 { 435 DECLARE_TEST_VARS; 436 437 c = presetup_ipv4(tc); 438 439 /* Create IPv4 subnetwork with smaller prefix */ 440 struct sockaddr_in mask4; 441 struct sockaddr_in net4; 442 struct sockaddr_in gw4; 443 prepare_v4_network(c, &net4, &mask4, &gw4); 444 445 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 446 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 447 448 rtsock_send_rtm(c->rtsock_fd, rtm); 449 450 /* Route has been added successfully, try to delete it */ 451 prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 452 (struct sockaddr *)&mask4, NULL); 453 454 rtsock_send_rtm(c->rtsock_fd, rtm); 455 456 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 457 458 /* 459 * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC> 460 * sockaddrs: 0x7 <DST,GATEWAY,NETMASK> 461 * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}} 462 * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}} 463 * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}} 464 */ 465 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 466 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 467 468 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 469 } 470 471 ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc) 472 { 473 CLEANUP_AFTER_TEST; 474 } 475 476 ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success); 477 ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc) 478 { 479 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW"); 480 } 481 482 ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc) 483 { 484 DECLARE_TEST_VARS; 485 486 c = presetup_ipv6(tc); 487 488 /* Create IPv6 subnetwork with smaller prefix */ 489 struct sockaddr_in6 mask6; 490 struct sockaddr_in6 net6; 491 struct sockaddr_in6 gw6; 492 prepare_v6_network(c, &net6, &mask6, &gw6); 493 494 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 495 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 496 497 rtsock_send_rtm(c->rtsock_fd, rtm); 498 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 499 500 /* 501 * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC> 502 * locks: inits: 503 * sockaddrs: <DST,GATEWAY,NETMASK> 504 * 192.0.2.0 192.0.2.254 255.255.255.128 505 */ 506 507 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 508 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 509 510 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 511 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 512 } 513 514 ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc) 515 { 516 CLEANUP_AFTER_TEST; 517 } 518 519 ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success); 520 ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc) 521 { 522 523 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway"); 524 } 525 526 ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc) 527 { 528 DECLARE_TEST_VARS; 529 530 c = presetup_ipv6(tc); 531 532 /* Create IPv6 subnetwork with smaller prefix */ 533 struct sockaddr_in6 mask6; 534 struct sockaddr_in6 net6; 535 struct sockaddr_in6 gw6; 536 prepare_v6_network(c, &net6, &mask6, &gw6); 537 538 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 539 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 540 541 rtsock_send_rtm(c->rtsock_fd, rtm); 542 543 /* Route has been added successfully, try to delete it */ 544 prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 545 (struct sockaddr *)&mask6, NULL); 546 547 rtsock_send_rtm(c->rtsock_fd, rtm); 548 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 549 550 /* 551 * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC> 552 * sockaddrs: 0x7 <DST,GATEWAY,NETMASK> 553 * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}} 554 * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}} 555 * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}} 556 */ 557 558 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 559 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 560 verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); 561 } 562 563 ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc) 564 { 565 CLEANUP_AFTER_TEST; 566 } 567 568 ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success); 569 ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc) 570 { 571 DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set"); 572 } 573 574 ATF_TC_BODY(rtm_add_v4_temporal1_success, tc) 575 { 576 DECLARE_TEST_VARS; 577 578 c = presetup_ipv4(tc); 579 580 /* Create IPv4 subnetwork with smaller prefix */ 581 struct sockaddr_in mask4; 582 struct sockaddr_in net4; 583 struct sockaddr_in gw4; 584 prepare_v4_network(c, &net4, &mask4, &gw4); 585 586 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, 587 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 588 589 /* Set expire time to now */ 590 struct timeval tv; 591 gettimeofday(&tv, NULL); 592 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; 593 rtm->rtm_inits |= RTV_EXPIRE; 594 595 rtsock_send_rtm(c->rtsock_fd, rtm); 596 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 597 ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); 598 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); 599 600 /* The next should be route deletion */ 601 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 602 603 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, 604 (struct sockaddr *)&mask4, (struct sockaddr *)&gw4); 605 606 /* TODO: add RTF_DONE */ 607 verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_STATIC); 608 } 609 610 ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc) 611 { 612 CLEANUP_AFTER_TEST; 613 } 614 615 ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success); 616 ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc) 617 { 618 DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW"); 619 } 620 621 ATF_TC_BODY(rtm_add_v6_temporal1_success, tc) 622 { 623 DECLARE_TEST_VARS; 624 625 c = presetup_ipv6(tc); 626 627 /* Create IPv6 subnetwork with smaller prefix */ 628 struct sockaddr_in6 mask6; 629 struct sockaddr_in6 net6; 630 struct sockaddr_in6 gw6; 631 prepare_v6_network(c, &net6, &mask6, &gw6); 632 633 prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, 634 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 635 636 /* Set expire time to now */ 637 struct timeval tv; 638 gettimeofday(&tv, NULL); 639 rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; 640 rtm->rtm_inits |= RTV_EXPIRE; 641 642 rtsock_send_rtm(c->rtsock_fd, rtm); 643 rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); 644 ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); 645 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); 646 647 /* The next should be route deletion */ 648 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 649 650 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, 651 (struct sockaddr *)&mask6, (struct sockaddr *)&gw6); 652 653 654 /* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ 655 /* TODO: add RTF_DONE */ 656 verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_STATIC); 657 } 658 659 ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc) 660 { 661 CLEANUP_AFTER_TEST; 662 } 663 664 /* Interface address messages tests */ 665 666 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success, 667 "Tests validness for /128 host route announce after ifaddr assignment"); 668 669 ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc) 670 { 671 DECLARE_TEST_VARS; 672 673 c = presetup_ipv6_iface(tc); 674 675 c->rtsock_fd = rtsock_setup_socket(); 676 677 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 678 679 /* 680 * There will be multiple. 681 * RTM_ADD without llinfo. 682 */ 683 684 while (true) { 685 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 686 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0)) 687 break; 688 } 689 /* This should be a message for the host route */ 690 691 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL); 692 rtsock_validate_pid_kernel(rtm); 693 /* No netmask should be set */ 694 RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set"); 695 696 /* gateway should be link sdl with ifindex of an address interface */ 697 verify_link_gateway(rtm, c->ifindex); 698 699 int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED; 700 verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags); 701 } 702 703 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success, 704 "Tests validness for the prefix route announce after ifaddr assignment"); 705 706 ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc) 707 { 708 DECLARE_TEST_VARS; 709 710 c = presetup_ipv6_iface(tc); 711 712 c->rtsock_fd = rtsock_setup_socket(); 713 714 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 715 716 /* 717 * Multiple RTM_ADD messages will be generated: 718 * 1) lladdr mapping (RTF_LLDATA) 719 * 2) host route (one w/o netmask) 720 * 3) prefix route 721 */ 722 723 while (true) { 724 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 725 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 726 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 727 break; 728 } 729 730 /* This should be a message for the prefix route */ 731 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6, 732 (struct sockaddr *)&c->mask6, NULL); 733 734 /* gateway should be link sdl with ifindex of an address interface */ 735 verify_link_gateway(rtm, c->ifindex); 736 737 /* TODO: PINNED? */ 738 int expected_rt_flags = RTF_UP | RTF_DONE; 739 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 740 } 741 742 RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success, 743 "Tests ordering of the messages for IPv6 global unicast ifaddr assignment"); 744 745 ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc) 746 { 747 DECLARE_TEST_VARS; 748 749 c = presetup_ipv6_iface(tc); 750 751 c->rtsock_fd = rtsock_setup_socket(); 752 753 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 754 755 int count = 0, tries = 0; 756 757 enum msgtype { 758 MSG_IFADDR, 759 MSG_HOSTROUTE, 760 MSG_PREFIXROUTE, 761 MSG_MAX, 762 }; 763 764 int msg_array[MSG_MAX]; 765 766 bzero(msg_array, sizeof(msg_array)); 767 768 while (count < 3 && tries < 20) { 769 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 770 tries++; 771 /* Classify */ 772 if (rtm->rtm_type == RTM_NEWADDR) { 773 RLOG("MSG_IFADDR: %d", count); 774 msg_array[MSG_IFADDR] = count++; 775 continue; 776 } 777 778 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 779 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) { 780 RLOG("MSG_PREFIXROUTE: %d", count); 781 msg_array[MSG_PREFIXROUTE] = count++; 782 continue; 783 } 784 785 if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) { 786 RLOG("MSG_HOSTROUTE: %d", count); 787 msg_array[MSG_HOSTROUTE] = count++; 788 continue; 789 } 790 791 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type), 792 tries); 793 } 794 795 /* TODO: verify multicast */ 796 ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count); 797 ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first"); 798 } 799 800 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success, 801 "Tests validness for /128 host route removal after ifaddr removal"); 802 803 ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc) 804 { 805 DECLARE_TEST_VARS; 806 807 c = presetup_ipv6_iface(tc); 808 809 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 810 811 c->rtsock_fd = rtsock_setup_socket(); 812 813 ret = iface_delete_addr(c->ifname, c->addr6_str); 814 815 while (true) { 816 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 817 if ((rtm->rtm_type == RTM_DELETE) && 818 ((rtm->rtm_flags & RTF_LLINFO) == 0) && 819 rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL) 820 break; 821 } 822 /* This should be a message for the host route */ 823 824 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL); 825 rtsock_validate_pid_kernel(rtm); 826 /* No netmask should be set */ 827 RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set"); 828 829 /* gateway should be link sdl with ifindex of an address interface */ 830 verify_link_gateway(rtm, c->ifindex); 831 832 /* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */ 833 int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED; 834 RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags, 835 "expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags); 836 } 837 838 RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success, 839 "Tests validness for the prefix route removal after ifaddr assignment"); 840 841 ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc) 842 { 843 DECLARE_TEST_VARS; 844 845 c = presetup_ipv6_iface(tc); 846 847 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 848 849 c->rtsock_fd = rtsock_setup_socket(); 850 851 ret = iface_delete_addr(c->ifname, c->addr6_str); 852 853 while (true) { 854 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 855 /* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */ 856 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 857 break; 858 } 859 860 /* This should be a message for the prefix route */ 861 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6, 862 (struct sockaddr *)&c->mask6, NULL); 863 864 /* gateway should be link sdl with ifindex of an address interface */ 865 verify_link_gateway(rtm, c->ifindex); 866 867 int expected_rt_flags = RTF_DONE; 868 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 869 } 870 871 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success, 872 "Tests validness for the prefix route announce after ifaddr assignment"); 873 874 ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc) 875 { 876 DECLARE_TEST_VARS; 877 878 c = presetup_ipv4_iface(tc); 879 880 c->rtsock_fd = rtsock_setup_socket(); 881 882 ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6); 883 884 /* 885 * Multiple RTM_ADD messages will be generated: 886 * 1) lladdr mapping (RTF_LLDATA) 887 * 3) prefix route 888 */ 889 890 while (true) { 891 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 892 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 893 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 894 break; 895 } 896 897 /* This should be a message for the prefix route */ 898 verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4, 899 (struct sockaddr *)&c->mask4, NULL); 900 901 /* gateway should be link sdl with ifindex of an address interface */ 902 verify_link_gateway(rtm, c->ifindex); 903 904 int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED; 905 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 906 } 907 908 RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success, 909 "Tests ordering of the messages for IPv4 unicast ifaddr assignment"); 910 911 ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc) 912 { 913 DECLARE_TEST_VARS; 914 915 c = presetup_ipv4_iface(tc); 916 917 c->rtsock_fd = rtsock_setup_socket(); 918 919 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4); 920 921 int count = 0, tries = 0; 922 923 enum msgtype { 924 MSG_IFADDR, 925 MSG_PREFIXROUTE, 926 MSG_MAX, 927 }; 928 929 int msg_array[MSG_MAX]; 930 931 bzero(msg_array, sizeof(msg_array)); 932 933 while (count < 2 && tries < 20) { 934 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 935 tries++; 936 /* Classify */ 937 if (rtm->rtm_type == RTM_NEWADDR) { 938 RLOG("MSG_IFADDR: %d", count); 939 msg_array[MSG_IFADDR] = count++; 940 continue; 941 } 942 943 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 944 if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) { 945 RLOG("MSG_PREFIXROUTE: %d", count); 946 msg_array[MSG_PREFIXROUTE] = count++; 947 continue; 948 } 949 950 RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type), 951 tries); 952 } 953 954 /* TODO: verify multicast */ 955 ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count); 956 ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first"); 957 } 958 959 RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success, 960 "Tests validness for the prefix route removal after ifaddr assignment"); 961 962 ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc) 963 { 964 DECLARE_TEST_VARS; 965 966 c = presetup_ipv4_iface(tc); 967 968 969 ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4); 970 971 c->rtsock_fd = rtsock_setup_socket(); 972 973 ret = iface_delete_addr(c->ifname, c->addr4_str); 974 975 while (true) { 976 rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); 977 /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */ 978 if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) 979 break; 980 } 981 982 /* This should be a message for the prefix route */ 983 verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4, 984 (struct sockaddr *)&c->mask4, NULL); 985 986 /* gateway should be link sdl with ifindex of an address interface */ 987 verify_link_gateway(rtm, c->ifindex); 988 989 int expected_rt_flags = RTF_DONE | RTF_PINNED; 990 verify_route_message_extra(rtm, c->ifindex, expected_rt_flags); 991 } 992 993 994 ATF_TP_ADD_TCS(tp) 995 { 996 ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success); 997 ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success); 998 ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure); 999 ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure); 1000 ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success); 1001 ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success); 1002 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success); 1003 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success); 1004 /* ifaddr tests */ 1005 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success); 1006 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success); 1007 ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success); 1008 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success); 1009 ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success); 1010 ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success); 1011 ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success); 1012 1013 return (atf_no_error()); 1014 } 1015 1016