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