1# 2# Copyright (c) 2014 Spectra Logic Corporation 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions, and the following disclaimer, 10# without modification. 11# 2. Redistributions in binary form must reproduce at minimum a disclaimer 12# substantially similar to the "NO WARRANTY" disclaimer below 13# ("Disclaimer") and any redistribution must be conditioned upon 14# including a substantially similar Disclaimer requirement for further 15# binary redistribution. 16# 17# NO WARRANTY 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28# POSSIBILITY OF SUCH DAMAGES. 29# 30# Authors: Alan Somers (Spectra Logic Corporation) 31# 32 33# All of the tests in this file requires the test-suite config variable "fibs" 34# to be defined to a space-delimited list of FIBs that may be used for testing. 35 36# arpresolve should check the interface fib for routes to a target when 37# creating an ARP table entry. This is a regression for kern/167947, where 38# arpresolve only checked the default route. 39# 40# Outline: 41# Create two connected epair(4) interfaces 42# Use nping (from security/nmap) to send an ICMP echo request from one 43# interface to the other, spoofing the source IP. The source IP must be 44# spoofed, or else it will already have an entry in the arp table. 45# Check whether an arp entry exists for the spoofed IP 46atf_test_case arpresolve_checks_interface_fib cleanup 47arpresolve_checks_interface_fib_head() 48{ 49 atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes" 50 atf_set "require.user" "root" 51 atf_set "require.config" "fibs" 52 atf_set "require.progs" "nping" 53} 54arpresolve_checks_interface_fib_body() 55{ 56 # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 57 # and a non-default fib 58 ADDR0="192.0.2.2" 59 ADDR1="192.0.2.3" 60 SUBNET="192.0.2.0" 61 # Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need 62 # diffferent subnet masks, or FIB1 won't have a subnet route. 63 MASK0="24" 64 MASK1="25" 65 # Spoof a MAC that is reserved per RFC7042 66 SPOOF_ADDR="192.0.2.4" 67 SPOOF_MAC="00:00:5E:00:53:00" 68 69 # Check system configuration 70 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 71 atf_skip "This test requires net.add_addr_allfibs=0" 72 fi 73 get_fibs 2 74 75 # Configure epair interfaces 76 get_epair 77 setup_iface "$EPAIRA" "$FIB0" inet ${ADDR0} ${MASK0} 78 setup_iface "$EPAIRB" "$FIB1" inet ${ADDR1} ${MASK1} 79 80 # Send an ICMP echo request with a spoofed source IP 81 setfib "$FIB0" nping -c 1 -e ${EPAIRA} -S ${SPOOF_ADDR} \ 82 --source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \ 83 --icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \ 84 ${ADDR1} 85 # For informational and debugging purposes only, look for the 86 # characteristic error message 87 dmesg | grep "llinfo.*${SPOOF_ADDR}" 88 # Check that the ARP entry exists 89 atf_check -o match:"${SPOOF_ADDR}.*expires" setfib "$FIB1" arp ${SPOOF_ADDR} 90} 91arpresolve_checks_interface_fib_cleanup() 92{ 93 cleanup_ifaces 94} 95 96 97# Regression test for kern/187549 98atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup 99loopback_and_network_routes_on_nondefault_fib_head() 100{ 101 atf_set "descr" "When creating and deleting loopback IPv4 routes, use the interface's fib" 102 atf_set "require.user" "root" 103 atf_set "require.config" "fibs" 104} 105 106loopback_and_network_routes_on_nondefault_fib_body() 107{ 108 # Configure the TAP interface to use an RFC5737 nonrouteable address 109 # and a non-default fib 110 ADDR="192.0.2.2" 111 SUBNET="192.0.2.0" 112 MASK="24" 113 114 # Check system configuration 115 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 116 atf_skip "This test requires net.add_addr_allfibs=0" 117 fi 118 get_fibs 1 119 120 # Configure a TAP interface 121 setup_tap ${FIB0} inet ${ADDR} ${MASK} 122 123 # Check whether the host route exists in only the correct FIB 124 setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 125 if [ 0 -ne $? ]; then 126 setfib ${FIB0} netstat -rn -f inet 127 atf_fail "Host route did not appear in the correct FIB" 128 fi 129 setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 130 if [ 0 -eq $? ]; then 131 setfib 0 netstat -rn -f inet 132 atf_fail "Host route appeared in the wrong FIB" 133 fi 134 135 # Check whether the network route exists in only the correct FIB 136 setfib ${FIB0} netstat -rn -f inet | \ 137 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 138 if [ 0 -ne $? ]; then 139 setfib ${FIB0} netstat -rn -f inet 140 atf_fail "Network route did not appear in the correct FIB" 141 fi 142 setfib 0 netstat -rn -f inet | \ 143 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 144 if [ 0 -eq $? ]; then 145 setfib 0 netstat -rn -f inet 146 atf_fail "Network route appeared in the wrong FIB" 147 fi 148} 149 150loopback_and_network_routes_on_nondefault_fib_cleanup() 151{ 152 cleanup_ifaces 153} 154 155atf_test_case loopback_and_network_routes_on_nondefault_fib_inet6 cleanup 156loopback_and_network_routes_on_nondefault_fib_inet6_head() 157{ 158 atf_set "descr" "When creating and deleting loopback IPv6 routes, use the interface's fib" 159 atf_set "require.user" "root" 160 atf_set "require.config" "fibs" 161} 162 163loopback_and_network_routes_on_nondefault_fib_inet6_body() 164{ 165 # Configure the TAP interface to use a nonrouteable RFC3849 166 # address and a non-default fib 167 ADDR="2001:db8::2" 168 SUBNET="2001:db8::" 169 MASK="64" 170 171 # Check system configuration 172 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 173 atf_skip "This test requires net.add_addr_allfibs=0" 174 fi 175 get_fibs 1 176 177 # Configure a TAP interface 178 setup_tap ${FIB0} inet6 ${ADDR} ${MASK} 179 180 # Check whether the host route exists in only the correct FIB 181 setfib ${FIB0} netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0" 182 if [ 0 -ne $? ]; then 183 setfib ${FIB0} netstat -rn -f inet6 184 atf_fail "Host route did not appear in the correct FIB" 185 fi 186 setfib 0 netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0" 187 if [ 0 -eq $? ]; then 188 setfib 0 netstat -rn -f inet6 189 atf_fail "Host route appeared in the wrong FIB" 190 fi 191 192 # Check whether the network route exists in only the correct FIB 193 setfib ${FIB0} netstat -rn -f inet6 | \ 194 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 195 if [ 0 -ne $? ]; then 196 setfib ${FIB0} netstat -rn -f inet6 197 atf_fail "Network route did not appear in the correct FIB" 198 fi 199 setfib 0 netstat -rn -f inet6 | \ 200 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 201 if [ 0 -eq $? ]; then 202 setfib 0 netstat -rn -f inet6 203 atf_fail "Network route appeared in the wrong FIB" 204 fi 205} 206 207loopback_and_network_routes_on_nondefault_fib_inet6_cleanup() 208{ 209 cleanup_ifaces 210} 211 212 213# Regression test for kern/187552 214atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup 215default_route_with_multiple_fibs_on_same_subnet_head() 216{ 217 atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv4 routes" 218 atf_set "require.user" "root" 219 atf_set "require.config" "fibs" 220} 221 222default_route_with_multiple_fibs_on_same_subnet_body() 223{ 224 # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 225 # and a non-default fib 226 ADDR0="192.0.2.2" 227 ADDR1="192.0.2.3" 228 GATEWAY="192.0.2.1" 229 SUBNET="192.0.2.0" 230 MASK="24" 231 232 # Check system configuration 233 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 234 atf_skip "This test requires net.add_addr_allfibs=0" 235 fi 236 get_fibs 2 237 238 # Configure TAP interfaces 239 setup_tap "$FIB0" inet ${ADDR0} ${MASK} 240 TAP0=$TAP 241 setup_tap "$FIB1" inet ${ADDR1} ${MASK} 242 TAP1=$TAP 243 244 # Attempt to add default routes 245 setfib ${FIB0} route add default ${GATEWAY} 246 setfib ${FIB1} route add default ${GATEWAY} 247 248 # Verify that the default route exists for both fibs, with their 249 # respective interfaces. 250 atf_check -o match:"^default.*${TAP0}$" \ 251 setfib ${FIB0} netstat -rn -f inet 252 atf_check -o match:"^default.*${TAP1}$" \ 253 setfib ${FIB1} netstat -rn -f inet 254} 255 256default_route_with_multiple_fibs_on_same_subnet_cleanup() 257{ 258 cleanup_ifaces 259} 260 261atf_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 cleanup 262default_route_with_multiple_fibs_on_same_subnet_inet6_head() 263{ 264 atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv6 routes" 265 atf_set "require.user" "root" 266 atf_set "require.config" "fibs" 267} 268 269default_route_with_multiple_fibs_on_same_subnet_inet6_body() 270{ 271 # Configure the TAP interfaces to use nonrouteable RFC3849 272 # addresses and non-default FIBs 273 ADDR0="2001:db8::2" 274 ADDR1="2001:db8::3" 275 GATEWAY="2001:db8::1" 276 SUBNET="2001:db8::" 277 MASK="64" 278 279 # Check system configuration 280 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 281 atf_skip "This test requires net.add_addr_allfibs=0" 282 fi 283 get_fibs 2 284 285 # Configure TAP interfaces 286 setup_tap "$FIB0" inet6 ${ADDR0} ${MASK} 287 TAP0=$TAP 288 setup_tap "$FIB1" inet6 ${ADDR1} ${MASK} 289 TAP1=$TAP 290 291 # Attempt to add default routes 292 setfib ${FIB0} route -6 add default ${GATEWAY} 293 setfib ${FIB1} route -6 add default ${GATEWAY} 294 295 # Verify that the default route exists for both fibs, with their 296 # respective interfaces. 297 atf_check -o match:"^default.*${TAP0}$" \ 298 setfib ${FIB0} netstat -rn -f inet6 299 atf_check -o match:"^default.*${TAP1}$" \ 300 setfib ${FIB1} netstat -rn -f inet6 301} 302 303default_route_with_multiple_fibs_on_same_subnet_inet6_cleanup() 304{ 305 cleanup_ifaces 306} 307 308 309# Regression test for PR kern/189089 310# Create two tap interfaces and assign them both the same IP address but with 311# different netmasks, and both on the default FIB. Then remove one's IP 312# address. Hopefully the machine won't panic. 313atf_test_case same_ip_multiple_ifaces_fib0 cleanup 314same_ip_multiple_ifaces_fib0_head() 315{ 316 atf_set "descr" "Can remove an IPv4 alias from an interface when the same IPv4 is also assigned to another interface." 317 atf_set "require.user" "root" 318 atf_set "require.config" "fibs" 319} 320same_ip_multiple_ifaces_fib0_body() 321{ 322 ADDR="192.0.2.2" 323 MASK0="24" 324 MASK1="32" 325 326 # Unlike most of the tests in this file, this is applicable regardless 327 # of net.add_addr_allfibs 328 329 # Setup the interfaces, then remove one alias. It should not panic. 330 setup_tap 0 inet ${ADDR} ${MASK0} 331 TAP0=${TAP} 332 setup_tap 0 inet ${ADDR} ${MASK1} 333 TAP1=${TAP} 334 ifconfig ${TAP1} -alias ${ADDR} 335 336 # Do it again, in the opposite order. It should not panic. 337 setup_tap 0 inet ${ADDR} ${MASK0} 338 TAP0=${TAP} 339 setup_tap 0 inet ${ADDR} ${MASK1} 340 TAP1=${TAP} 341 ifconfig ${TAP0} -alias ${ADDR} 342} 343same_ip_multiple_ifaces_fib0_cleanup() 344{ 345 cleanup_ifaces 346} 347 348# Regression test for PR kern/189088 349# Test that removing an IP address works even if the same IP is assigned to a 350# different interface, on a different FIB. Tests the same code that whose 351# panic was regressed by same_ip_multiple_ifaces_fib0. 352# Create two tap interfaces and assign them both the same IP address but with 353# different netmasks, and on different FIBs. Then remove one's IP 354# address. Hopefully the machine won't panic. Also, the IP's hostroute should 355# dissappear from the correct fib. 356atf_test_case same_ip_multiple_ifaces cleanup 357same_ip_multiple_ifaces_head() 358{ 359 atf_set "descr" "Can remove an IPv4 alias from an interface when the same address is also assigned to another interface, on non-default FIBs." 360 atf_set "require.user" "root" 361 atf_set "require.config" "fibs" 362} 363same_ip_multiple_ifaces_body() 364{ 365 atf_expect_fail "kern/189088 Assigning the same IP to multiple interfaces in different FIBs creates a host route for only one" 366 ADDR="192.0.2.2" 367 MASK0="24" 368 MASK1="32" 369 370 # Unlike most of the tests in this file, this is applicable regardless 371 # of net.add_addr_allfibs 372 get_fibs 2 373 374 # Setup the interfaces, then remove one alias. It should not panic. 375 setup_tap ${FIB0} inet ${ADDR} ${MASK0} 376 TAP0=${TAP} 377 setup_tap ${FIB1} inet ${ADDR} ${MASK1} 378 TAP1=${TAP} 379 ifconfig ${TAP1} -alias ${ADDR} 380 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 381 setfib ${FIB1} netstat -rn -f inet 382 383 # Do it again, in the opposite order. It should not panic. 384 setup_tap ${FIB0} inet ${ADDR} ${MASK0} 385 TAP0=${TAP} 386 setup_tap ${FIB1} inet ${ADDR} ${MASK1} 387 TAP1=${TAP} 388 ifconfig ${TAP0} -alias ${ADDR} 389 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 390 setfib ${FIB0} netstat -rn -f inet 391} 392same_ip_multiple_ifaces_cleanup() 393{ 394 # Due to PR kern/189088, we must destroy the interfaces in LIFO order 395 # in order for the routes to be correctly cleaned up. 396 for TAPD in `tail -r "ifaces_to_cleanup"`; do 397 echo ifconfig ${TAPD} destroy 398 ifconfig ${TAPD} destroy 399 done 400} 401 402atf_test_case same_ip_multiple_ifaces_inet6 cleanup 403same_ip_multiple_ifaces_inet6_head() 404{ 405 atf_set "descr" "Can remove an IPv6 alias from an interface when the same address is also assigned to another interface, on non-default FIBs." 406 atf_set "require.user" "root" 407 atf_set "require.config" "fibs" 408} 409same_ip_multiple_ifaces_inet6_body() 410{ 411 ADDR="2001:db8::2" 412 MASK0="64" 413 MASK1="128" 414 415 # Unlike most of the tests in this file, this is applicable regardless 416 # of net.add_addr_allfibs 417 get_fibs 2 418 419 # Setup the interfaces, then remove one alias. It should not panic. 420 setup_tap ${FIB0} inet6 ${ADDR} ${MASK0} 421 TAP0=${TAP} 422 setup_tap ${FIB1} inet6 ${ADDR} ${MASK1} 423 TAP1=${TAP} 424 atf_check -s exit:0 ifconfig ${TAP1} inet6 ${ADDR} -alias 425 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 426 setfib ${FIB1} netstat -rn -f inet6 427 ifconfig ${TAP1} destroy 428 ifconfig ${TAP0} destroy 429 430 # Do it again, in the opposite order. It should not panic. 431 setup_tap ${FIB0} inet6 ${ADDR} ${MASK0} 432 TAP0=${TAP} 433 setup_tap ${FIB1} inet6 ${ADDR} ${MASK1} 434 TAP1=${TAP} 435 atf_check -s exit:0 ifconfig ${TAP0} inet6 ${ADDR} -alias 436 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 437 setfib ${FIB0} netstat -rn -f inet6 438} 439same_ip_multiple_ifaces_inet6_cleanup() 440{ 441 cleanup_ifaces 442} 443 444atf_test_case slaac_on_nondefault_fib6 cleanup 445slaac_on_nondefault_fib6_head() 446{ 447 atf_set "descr" "SLAAC correctly installs routes on non-default FIBs" 448 atf_set "require.user" "root" 449 atf_set "require.config" "fibs" "allow_sysctl_side_effects" 450} 451slaac_on_nondefault_fib6_body() 452{ 453 # Configure the epair interfaces to use nonrouteable RFC3849 454 # addresses and non-default FIBs 455 PREFIX="2001:db8:$(printf "%x" `jot -r 1 0 65535`):$(printf "%x" `jot -r 1 0 65535`)" 456 ADDR="$PREFIX::2" 457 GATEWAY="$PREFIX::1" 458 SUBNET="$PREFIX:" 459 MASK="64" 460 461 # Check system configuration 462 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 463 atf_skip "This test requires net.add_addr_allfibs=0" 464 fi 465 get_fibs 2 466 467 sysctl -n "net.inet6.ip6.rfc6204w3" >> "rfc6204w3.state" 468 sysctl -n "net.inet6.ip6.forwarding" >> "forwarding.state" 469 # Enable forwarding so the kernel will send RAs 470 sysctl net.inet6.ip6.forwarding=1 471 # Enable RFC6204W3 mode so the kernel will enable default router 472 # selection while also forwarding packets 473 sysctl net.inet6.ip6.rfc6204w3=1 474 475 # Configure epair interfaces 476 get_epair 477 setup_iface "$EPAIRA" "$FIB0" inet6 ${ADDR} ${MASK} 478 echo setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up 479 setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up 480 rtadvd -p rtadvd.pid -C rtadvd.sock -c /dev/null "$EPAIRA" 481 rtsol "$EPAIRB" 482 483 # Check SLAAC address 484 atf_check -o match:"inet6 ${SUBNET}.*prefixlen ${MASK}.*autoconf" \ 485 ifconfig "$EPAIRB" 486 # Check local route 487 atf_check -o match:"${SUBNET}.*\<UHS\>.*lo0" \ 488 netstat -rnf inet6 -F $FIB1 489 # Check subnet route 490 atf_check -o match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \ 491 netstat -rnf inet6 -F $FIB1 492 # Check default route 493 atf_check -o match:"default.*\<UG\>.*$EPAIRB" \ 494 netstat -rnf inet6 -F $FIB1 495 496 # Check that none of the above routes appeared on other routes 497 for fib in $( seq 0 $(($(sysctl -n net.fibs) - 1))); do 498 if [ "$fib" = "$FIB1" -o "$fib" = "$FIB0" ]; then 499 continue 500 fi 501 atf_check -o not-match:"${SUBNET}.*\<UHS\>.*lo0" \ 502 netstat -rnf inet6 -F $fib 503 atf_check -o not-match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \ 504 netstat -rnf inet6 -F $fib 505 atf_check -o not-match:"default.*\<UG\>.*$EPAIRB" \ 506 netstat -rnf inet6 -F $fib 507 done 508} 509slaac_on_nondefault_fib6_cleanup() 510{ 511 if [ -f "rtadvd.pid" ]; then 512 # rtadvd can take a long time to shutdown. Use SIGKILL to kill 513 # it right away. The downside to using SIGKILL is that it 514 # won't send final RAs to all interfaces, but we don't care 515 # because we're about to destroy its interface anyway. 516 pkill -kill -F rtadvd.pid 517 rm -f rtadvd.pid 518 fi 519 cleanup_ifaces 520 if [ -f "forwarding.state" ] ; then 521 sysctl "net.inet6.ip6.forwarding"=`cat "forwarding.state"` 522 rm "forwarding.state" 523 fi 524 if [ -f "rfc6204w3.state" ] ; then 525 sysctl "net.inet6.ip6.rfc6204w3"=`cat "rfc6204w3.state"` 526 rm "rfc6204w3.state" 527 fi 528} 529 530# Regression test for kern/187550 531atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup 532subnet_route_with_multiple_fibs_on_same_subnet_head() 533{ 534 atf_set "descr" "Multiple FIBs can have IPv4 subnet routes for the same subnet" 535 atf_set "require.user" "root" 536 atf_set "require.config" "fibs" 537} 538 539subnet_route_with_multiple_fibs_on_same_subnet_body() 540{ 541 # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 542 # and a non-default fib 543 ADDR0="192.0.2.2" 544 ADDR1="192.0.2.3" 545 SUBNET="192.0.2.0" 546 MASK="24" 547 548 # Check system configuration 549 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 550 atf_skip "This test requires net.add_addr_allfibs=0" 551 fi 552 get_fibs 2 553 554 # Configure TAP interfaces 555 setup_tap "$FIB0" inet ${ADDR0} ${MASK} 556 setup_tap "$FIB1" inet ${ADDR1} ${MASK} 557 558 # Check that a subnet route exists on both fibs 559 atf_check -o ignore setfib "$FIB0" route get $ADDR1 560 atf_check -o ignore setfib "$FIB1" route get $ADDR0 561} 562 563subnet_route_with_multiple_fibs_on_same_subnet_cleanup() 564{ 565 cleanup_ifaces 566} 567 568atf_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 cleanup 569subnet_route_with_multiple_fibs_on_same_subnet_inet6_head() 570{ 571 atf_set "descr" "Multiple FIBs can have IPv6 subnet routes for the same subnet" 572 atf_set "require.user" "root" 573 atf_set "require.config" "fibs" 574} 575 576subnet_route_with_multiple_fibs_on_same_subnet_inet6_body() 577{ 578 # Configure the TAP interfaces to use a RFC3849 nonrouteable addresses 579 # and a non-default fib 580 ADDR0="2001:db8::2" 581 ADDR1="2001:db8::3" 582 SUBNET="2001:db8::" 583 MASK="64" 584 585 # Check system configuration 586 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 587 atf_skip "This test requires net.add_addr_allfibs=0" 588 fi 589 get_fibs 2 590 591 # Configure TAP interfaces 592 setup_tap "$FIB0" inet6 ${ADDR0} ${MASK} 593 setup_tap "$FIB1" inet6 ${ADDR1} ${MASK} 594 595 # Check that a subnet route exists on both fibs 596 atf_check -o ignore setfib "$FIB0" route -6 get $ADDR1 597 atf_check -o ignore setfib "$FIB1" route -6 get $ADDR0 598} 599 600subnet_route_with_multiple_fibs_on_same_subnet_inet6_cleanup() 601{ 602 cleanup_ifaces 603} 604 605# Test that source address selection works correctly for UDP packets with 606# SO_DONTROUTE set that are sent on non-default FIBs. 607# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host" 608# Regression test for kern/187553 609# 610# The root cause was that ifa_ifwithnet() did not have a fib argument. It 611# would return an address from an interface on any FIB that had a subnet route 612# for the destination. If more than one were available, it would choose the 613# most specific. This is most easily tested by creating a FIB without a 614# default route, then trying to send a UDP packet with SO_DONTROUTE set to an 615# address which is not routable on that FIB. Absent the fix for this bug, 616# in_pcbladdr would choose an interface on any FIB with a default route. With 617# the fix, you will get EUNREACH or ENETUNREACH. 618atf_test_case udp_dontroute cleanup 619udp_dontroute_head() 620{ 621 atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works" 622 atf_set "require.user" "root" 623 atf_set "require.config" "fibs" 624} 625 626udp_dontroute_body() 627{ 628 # Configure the TAP interface to use an RFC5737 nonrouteable address 629 # and a non-default fib 630 ADDR0="192.0.2.2" 631 ADDR1="192.0.2.3" 632 SUBNET="192.0.2.0" 633 MASK="24" 634 # Use a different IP on the same subnet as the target 635 TARGET="192.0.2.100" 636 SRCDIR=`atf_get_srcdir` 637 638 # Check system configuration 639 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 640 atf_skip "This test requires net.add_addr_allfibs=0" 641 fi 642 get_fibs 2 643 644 # Configure the TAP interfaces 645 setup_tap ${FIB0} inet ${ADDR0} ${MASK} 646 TARGET_TAP=${TAP} 647 setup_tap ${FIB1} inet ${ADDR1} ${MASK} 648 649 # Send a UDP packet with SO_DONTROUTE. In the failure case, it will 650 # return ENETUNREACH, or send the packet to the wrong tap 651 atf_check -o ignore setfib ${FIB0} \ 652 ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 653 cleanup_ifaces 654 655 # Repeat, but this time target the other tap 656 setup_tap ${FIB0} inet ${ADDR0} ${MASK} 657 setup_tap ${FIB1} inet ${ADDR1} ${MASK} 658 TARGET_TAP=${TAP} 659 660 atf_check -o ignore setfib ${FIB1} \ 661 ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 662} 663 664udp_dontroute_cleanup() 665{ 666 cleanup_ifaces 667} 668 669atf_test_case udp_dontroute6 cleanup 670udp_dontroute6_head() 671{ 672 atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works" 673 atf_set "require.user" "root" 674 atf_set "require.config" "fibs" 675} 676 677udp_dontroute6_body() 678{ 679 if [ "$(atf_config_get ci false)" = "true" ]; then 680 atf_skip "https://bugs.freebsd.org/244172" 681 fi 682 # Configure the TAP interface to use an RFC3849 nonrouteable address 683 # and a non-default fib 684 ADDR0="2001:db8::2" 685 ADDR1="2001:db8::3" 686 SUBNET="2001:db8::" 687 MASK="64" 688 # Use a different IP on the same subnet as the target 689 TARGET="2001:db8::100" 690 SRCDIR=`atf_get_srcdir` 691 692 # Check system configuration 693 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 694 atf_skip "This test requires net.add_addr_allfibs=0" 695 fi 696 get_fibs 2 697 698 # Configure the TAP interfaces. Use no_dad so the addresses will be 699 # ready right away and won't be marked as tentative until DAD 700 # completes. 701 setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad 702 TARGET_TAP=${TAP} 703 setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad 704 705 # Send a UDP packet with SO_DONTROUTE. In the failure case, it will 706 # return ENETUNREACH, or send the packet to the wrong tap 707 atf_check -o ignore setfib ${FIB0} \ 708 ${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP} 709 cleanup_ifaces 710 711 # Repeat, but this time target the other tap 712 setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad 713 setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad 714 TARGET_TAP=${TAP} 715 716 atf_check -o ignore setfib ${FIB1} \ 717 ${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP} 718} 719 720udp_dontroute6_cleanup() 721{ 722 cleanup_ifaces 723} 724 725 726atf_init_test_cases() 727{ 728 atf_add_test_case arpresolve_checks_interface_fib 729 atf_add_test_case loopback_and_network_routes_on_nondefault_fib 730 atf_add_test_case loopback_and_network_routes_on_nondefault_fib_inet6 731 atf_add_test_case default_route_with_multiple_fibs_on_same_subnet 732 atf_add_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 733 atf_add_test_case same_ip_multiple_ifaces_fib0 734 atf_add_test_case same_ip_multiple_ifaces 735 atf_add_test_case same_ip_multiple_ifaces_inet6 736 atf_add_test_case slaac_on_nondefault_fib6 737 atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet 738 atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 739 atf_add_test_case udp_dontroute 740 atf_add_test_case udp_dontroute6 741} 742 743# Looks up one or more fibs from the configuration data and validates them. 744# Returns the results in the env varilables FIB0, FIB1, etc. 745 746# parameter numfibs The number of fibs to lookup 747get_fibs() 748{ 749 NUMFIBS=$1 750 net_fibs=`sysctl -n net.fibs` 751 i=0 752 while [ $i -lt "$NUMFIBS" ]; do 753 fib=`atf_config_get "fibs" | \ 754 awk -v i=$(( i + 1 )) '{print $i}'` 755 echo "fib is ${fib}" 756 eval FIB${i}=${fib} 757 if [ "$fib" -ge "$net_fibs" ]; then 758 atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}" 759 fi 760 i=$(( $i + 1 )) 761 done 762} 763 764# Creates a new pair of connected epair(4) interface, registers them for 765# cleanup, and returns their namen via the environment variables EPAIRA and 766# EPAIRB 767get_epair() 768{ 769 local EPAIRD 770 771 if (which pfctl && pfctl -s info | grep -q 'Status: Enabled') || 772 [ `sysctl -n net.inet.ip.fw.enable` = "1" ] || 773 (which ipf && ipf -V); then 774 atf_skip "firewalls interfere with this test" 775 fi 776 777 if EPAIRD=`ifconfig epair create`; then 778 # Record the epair device so we can clean it up later 779 echo ${EPAIRD} >> "ifaces_to_cleanup" 780 EPAIRA=${EPAIRD} 781 EPAIRB=${EPAIRD%a}b 782 else 783 atf_skip "Could not create epair(4) interfaces" 784 fi 785} 786 787# Creates a new tap(4) interface, registers it for cleanup, and returns the 788# name via the environment variable TAP 789get_tap() 790{ 791 local TAPD 792 793 if TAPD=`ifconfig tap create`; then 794 # Record the TAP device so we can clean it up later 795 echo ${TAPD} >> "ifaces_to_cleanup" 796 TAP=${TAPD} 797 else 798 atf_skip "Could not create a tap(4) interface" 799 fi 800} 801 802# Configure an ethernet interface 803# parameters: 804# Interface name 805# fib 806# Protocol (inet or inet6) 807# IP address 808# Netmask in number of bits (eg 24 or 8) 809# Extra flags 810# Return: None 811setup_iface() 812{ 813 local IFACE=$1 814 local FIB=$2 815 local PROTO=$3 816 local ADDR=$4 817 local MASK=$5 818 local FLAGS=$6 819 echo setfib ${FIB} \ 820 ifconfig $IFACE ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS 821 setfib ${FIB} ifconfig $IFACE ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS 822} 823 824# Create a tap(4) interface, configure it, and register it for cleanup. 825# parameters: 826# fib 827# Protocol (inet or inet6) 828# IP address 829# Netmask in number of bits (eg 24 or 8) 830# Extra flags 831# Return: the tap interface name as the env variable TAP 832setup_tap() 833{ 834 get_tap 835 setup_iface "$TAP" "$@" 836} 837 838cleanup_ifaces() 839{ 840 if [ -f ifaces_to_cleanup ]; then 841 for iface in $(cat ifaces_to_cleanup); do 842 echo ifconfig "${iface}" destroy 843 ifconfig "${iface}" destroy 2>/dev/null || true 844 done 845 rm -f ifaces_to_cleanup 846 fi 847} 848