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 atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0" 167 # Configure the TAP interface to use a nonrouteable RFC3849 168 # address and a non-default fib 169 ADDR="2001:db8::2" 170 SUBNET="2001:db8::" 171 MASK="64" 172 173 # Check system configuration 174 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 175 atf_skip "This test requires net.add_addr_allfibs=0" 176 fi 177 get_fibs 1 178 179 # Configure a TAP interface 180 setup_tap ${FIB0} inet6 ${ADDR} ${MASK} 181 182 # Check whether the host route exists in only the correct FIB 183 setfib ${FIB0} netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0" 184 if [ 0 -ne $? ]; then 185 setfib ${FIB0} netstat -rn -f inet6 186 atf_fail "Host route did not appear in the correct FIB" 187 fi 188 setfib 0 netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0" 189 if [ 0 -eq $? ]; then 190 setfib 0 netstat -rn -f inet6 191 atf_fail "Host route appeared in the wrong FIB" 192 fi 193 194 # Check whether the network route exists in only the correct FIB 195 setfib ${FIB0} netstat -rn -f inet6 | \ 196 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 197 if [ 0 -ne $? ]; then 198 setfib ${FIB0} netstat -rn -f inet6 199 atf_fail "Network route did not appear in the correct FIB" 200 fi 201 setfib 0 netstat -rn -f inet6 | \ 202 grep -q "^${SUBNET}/${MASK}.*${TAPD}" 203 if [ 0 -eq $? ]; then 204 setfib 0 netstat -rn -f inet6 205 atf_fail "Network route appeared in the wrong FIB" 206 fi 207} 208 209loopback_and_network_routes_on_nondefault_fib_inet6_cleanup() 210{ 211 cleanup_ifaces 212} 213 214 215# Regression test for kern/187552 216atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup 217default_route_with_multiple_fibs_on_same_subnet_head() 218{ 219 atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv4 routes" 220 atf_set "require.user" "root" 221 atf_set "require.config" "fibs" 222} 223 224default_route_with_multiple_fibs_on_same_subnet_body() 225{ 226 # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 227 # and a non-default fib 228 ADDR0="192.0.2.2" 229 ADDR1="192.0.2.3" 230 GATEWAY="192.0.2.1" 231 SUBNET="192.0.2.0" 232 MASK="24" 233 234 # Check system configuration 235 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 236 atf_skip "This test requires net.add_addr_allfibs=0" 237 fi 238 get_fibs 2 239 240 # Configure TAP interfaces 241 setup_tap "$FIB0" inet ${ADDR0} ${MASK} 242 TAP0=$TAP 243 setup_tap "$FIB1" inet ${ADDR1} ${MASK} 244 TAP1=$TAP 245 246 # Attempt to add default routes 247 setfib ${FIB0} route add default ${GATEWAY} 248 setfib ${FIB1} route add default ${GATEWAY} 249 250 # Verify that the default route exists for both fibs, with their 251 # respective interfaces. 252 atf_check -o match:"^default.*${TAP0}$" \ 253 setfib ${FIB0} netstat -rn -f inet 254 atf_check -o match:"^default.*${TAP1}$" \ 255 setfib ${FIB1} netstat -rn -f inet 256} 257 258default_route_with_multiple_fibs_on_same_subnet_cleanup() 259{ 260 cleanup_ifaces 261} 262 263atf_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 cleanup 264default_route_with_multiple_fibs_on_same_subnet_inet6_head() 265{ 266 atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv6 routes" 267 atf_set "require.user" "root" 268 atf_set "require.config" "fibs" 269} 270 271default_route_with_multiple_fibs_on_same_subnet_inet6_body() 272{ 273 # Configure the TAP interfaces to use nonrouteable RFC3849 274 # addresses and non-default FIBs 275 ADDR0="2001:db8::2" 276 ADDR1="2001:db8::3" 277 GATEWAY="2001:db8::1" 278 SUBNET="2001:db8::" 279 MASK="64" 280 281 # Check system configuration 282 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 283 atf_skip "This test requires net.add_addr_allfibs=0" 284 fi 285 get_fibs 2 286 287 # Configure TAP interfaces 288 setup_tap "$FIB0" inet6 ${ADDR0} ${MASK} 289 TAP0=$TAP 290 setup_tap "$FIB1" inet6 ${ADDR1} ${MASK} 291 TAP1=$TAP 292 293 # Attempt to add default routes 294 setfib ${FIB0} route -6 add default ${GATEWAY} 295 setfib ${FIB1} route -6 add default ${GATEWAY} 296 297 # Verify that the default route exists for both fibs, with their 298 # respective interfaces. 299 atf_check -o match:"^default.*${TAP0}$" \ 300 setfib ${FIB0} netstat -rn -f inet6 301 atf_check -o match:"^default.*${TAP1}$" \ 302 setfib ${FIB1} netstat -rn -f inet6 303} 304 305default_route_with_multiple_fibs_on_same_subnet_inet6_cleanup() 306{ 307 cleanup_ifaces 308} 309 310 311# Regression test for PR kern/189089 312# Create two tap interfaces and assign them both the same IP address but with 313# different netmasks, and both on the default FIB. Then remove one's IP 314# address. Hopefully the machine won't panic. 315atf_test_case same_ip_multiple_ifaces_fib0 cleanup 316same_ip_multiple_ifaces_fib0_head() 317{ 318 atf_set "descr" "Can remove an IPv4 alias from an interface when the same IPv4 is also assigned to another interface." 319 atf_set "require.user" "root" 320 atf_set "require.config" "fibs" 321} 322same_ip_multiple_ifaces_fib0_body() 323{ 324 ADDR="192.0.2.2" 325 MASK0="24" 326 MASK1="32" 327 328 # Unlike most of the tests in this file, this is applicable regardless 329 # of net.add_addr_allfibs 330 331 # Setup the interfaces, then remove one alias. It should not panic. 332 setup_tap 0 inet ${ADDR} ${MASK0} 333 TAP0=${TAP} 334 setup_tap 0 inet ${ADDR} ${MASK1} 335 TAP1=${TAP} 336 ifconfig ${TAP1} -alias ${ADDR} 337 338 # Do it again, in the opposite order. It should not panic. 339 setup_tap 0 inet ${ADDR} ${MASK0} 340 TAP0=${TAP} 341 setup_tap 0 inet ${ADDR} ${MASK1} 342 TAP1=${TAP} 343 ifconfig ${TAP0} -alias ${ADDR} 344} 345same_ip_multiple_ifaces_fib0_cleanup() 346{ 347 cleanup_ifaces 348} 349 350# Regression test for PR kern/189088 351# Test that removing an IP address works even if the same IP is assigned to a 352# different interface, on a different FIB. Tests the same code that whose 353# panic was regressed by same_ip_multiple_ifaces_fib0. 354# Create two tap interfaces and assign them both the same IP address but with 355# different netmasks, and on different FIBs. Then remove one's IP 356# address. Hopefully the machine won't panic. Also, the IP's hostroute should 357# dissappear from the correct fib. 358atf_test_case same_ip_multiple_ifaces cleanup 359same_ip_multiple_ifaces_head() 360{ 361 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." 362 atf_set "require.user" "root" 363 atf_set "require.config" "fibs" 364} 365same_ip_multiple_ifaces_body() 366{ 367 atf_expect_fail "kern/189088 Assigning the same IP to multiple interfaces in different FIBs creates a host route for only one" 368 ADDR="192.0.2.2" 369 MASK0="24" 370 MASK1="32" 371 372 # Unlike most of the tests in this file, this is applicable regardless 373 # of net.add_addr_allfibs 374 get_fibs 2 375 376 # Setup the interfaces, then remove one alias. It should not panic. 377 setup_tap ${FIB0} inet ${ADDR} ${MASK0} 378 TAP0=${TAP} 379 setup_tap ${FIB1} inet ${ADDR} ${MASK1} 380 TAP1=${TAP} 381 ifconfig ${TAP1} -alias ${ADDR} 382 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 383 setfib ${FIB1} netstat -rn -f inet 384 385 # Do it again, in the opposite order. It should not panic. 386 setup_tap ${FIB0} inet ${ADDR} ${MASK0} 387 TAP0=${TAP} 388 setup_tap ${FIB1} inet ${ADDR} ${MASK1} 389 TAP1=${TAP} 390 ifconfig ${TAP0} -alias ${ADDR} 391 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 392 setfib ${FIB0} netstat -rn -f inet 393} 394same_ip_multiple_ifaces_cleanup() 395{ 396 # Due to PR kern/189088, we must destroy the interfaces in LIFO order 397 # in order for the routes to be correctly cleaned up. 398 for TAPD in `tail -r "ifaces_to_cleanup"`; do 399 echo ifconfig ${TAPD} destroy 400 ifconfig ${TAPD} destroy 401 done 402} 403 404atf_test_case same_ip_multiple_ifaces_inet6 cleanup 405same_ip_multiple_ifaces_inet6_head() 406{ 407 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." 408 atf_set "require.user" "root" 409 atf_set "require.config" "fibs" 410} 411same_ip_multiple_ifaces_inet6_body() 412{ 413 ADDR="2001:db8::2" 414 MASK0="64" 415 MASK1="128" 416 417 # Unlike most of the tests in this file, this is applicable regardless 418 # of net.add_addr_allfibs 419 get_fibs 2 420 421 # Setup the interfaces, then remove one alias. It should not panic. 422 setup_tap ${FIB0} inet6 ${ADDR} ${MASK0} 423 TAP0=${TAP} 424 setup_tap ${FIB1} inet6 ${ADDR} ${MASK1} 425 TAP1=${TAP} 426 atf_check -s exit:0 ifconfig ${TAP1} inet6 ${ADDR} -alias 427 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 428 setfib ${FIB1} netstat -rn -f inet6 429 ifconfig ${TAP1} destroy 430 ifconfig ${TAP0} destroy 431 432 # Do it again, in the opposite order. It should not panic. 433 setup_tap ${FIB0} inet6 ${ADDR} ${MASK0} 434 TAP0=${TAP} 435 setup_tap ${FIB1} inet6 ${ADDR} ${MASK1} 436 TAP1=${TAP} 437 atf_check -s exit:0 ifconfig ${TAP0} inet6 ${ADDR} -alias 438 atf_check -o not-match:"^${ADDR}[[:space:]]" \ 439 setfib ${FIB0} netstat -rn -f inet6 440} 441same_ip_multiple_ifaces_inet6_cleanup() 442{ 443 cleanup_ifaces 444} 445 446atf_test_case slaac_on_nondefault_fib6 cleanup 447slaac_on_nondefault_fib6_head() 448{ 449 atf_set "descr" "SLAAC correctly installs routes on non-default FIBs" 450 atf_set "require.user" "root" 451 atf_set "require.config" "fibs" "allow_sysctl_side_effects" 452} 453slaac_on_nondefault_fib6_body() 454{ 455 # Configure the epair interfaces to use nonrouteable RFC3849 456 # addresses and non-default FIBs 457 ADDR="2001:db8::2" 458 GATEWAY="2001:db8::1" 459 SUBNET="2001:db8:" 460 MASK="64" 461 462 atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0" 463 464 # Check system configuration 465 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 466 atf_skip "This test requires net.add_addr_allfibs=0" 467 fi 468 get_fibs 2 469 470 sysctl -n "net.inet6.ip6.rfc6204w3" >> "rfc6204w3.state" 471 sysctl -n "net.inet6.ip6.forwarding" >> "forwarding.state" 472 # Enable forwarding so the kernel will send RAs 473 sysctl net.inet6.ip6.forwarding=1 474 # Enable RFC6204W3 mode so the kernel will enable default router 475 # selection while also forwarding packets 476 sysctl net.inet6.ip6.rfc6204w3=1 477 478 # Configure epair interfaces 479 get_epair 480 setup_iface "$EPAIRA" "$FIB0" inet6 ${ADDR} ${MASK} 481 echo ifconfig "$EPAIRB" up inet6 fib $FIB1 -ifdisabled accept_rtadv 482 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up 483 rtadvd -p rtadvd.pid -C rtadvd.sock -c /dev/null "$EPAIRA" 484 rtsol "$EPAIRB" 485 486 # Check SLAAC address 487 atf_check -o match:"inet6 ${SUBNET}.*prefixlen ${MASK}.*autoconf" \ 488 ifconfig "$EPAIRB" 489 # Check local route 490 atf_check -o match:"${SUBNET}.*\<UHS\>.*lo0" \ 491 netstat -rnf inet6 -F $FIB1 492 # Check subnet route 493 atf_check -o match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \ 494 netstat -rnf inet6 -F $FIB1 495 # Check default route 496 atf_check -o match:"default.*\<UG\>.*$EPAIRB" \ 497 netstat -rnf inet6 -F $FIB1 498 499 # Check that none of the above routes appeared on other routes 500 for fib in $( seq 0 $(($(sysctl -n net.fibs) - 1))); do 501 if [ "$fib" = "$FIB1" -o "$fib" = "$FIB0" ]; then 502 continue 503 fi 504 atf_check -o not-match:"${SUBNET}.*\<UHS\>.*lo0" \ 505 netstat -rnf inet6 -F $fib 506 atf_check -o not-match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \ 507 netstat -rnf inet6 -F $fib 508 atf_check -o not-match:"default.*\<UG\>.*$EPAIRB" \ 509 netstat -rnf inet6 -F $fib 510 done 511} 512slaac_on_nondefault_fib6_cleanup() 513{ 514 cleanup_ifaces 515 if [ -f "rtadvd.pid" ]; then 516 pkill -F rtadvd.pid 517 rm rtadvd.pid 518 fi 519 if [ -f "rfc6204w3.state" ] ; then 520 sysctl "net.inet6.ip6.rfc6204w3"=`cat "rfc6204w3.state"` 521 rm "rfc6204w3.state" 522 fi 523 if [ -f "forwarding.state" ] ; then 524 sysctl "net.inet6.ip6.forwarding"=`cat "forwarding.state"` 525 rm "forwarding.state" 526 fi 527} 528 529# Regression test for kern/187550 530atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup 531subnet_route_with_multiple_fibs_on_same_subnet_head() 532{ 533 atf_set "descr" "Multiple FIBs can have IPv4 subnet routes for the same subnet" 534 atf_set "require.user" "root" 535 atf_set "require.config" "fibs" 536} 537 538subnet_route_with_multiple_fibs_on_same_subnet_body() 539{ 540 # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 541 # and a non-default fib 542 ADDR0="192.0.2.2" 543 ADDR1="192.0.2.3" 544 SUBNET="192.0.2.0" 545 MASK="24" 546 547 # Check system configuration 548 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 549 atf_skip "This test requires net.add_addr_allfibs=0" 550 fi 551 get_fibs 2 552 553 # Configure TAP interfaces 554 setup_tap "$FIB0" inet ${ADDR0} ${MASK} 555 setup_tap "$FIB1" inet ${ADDR1} ${MASK} 556 557 # Check that a subnet route exists on both fibs 558 atf_check -o ignore setfib "$FIB0" route get $ADDR1 559 atf_check -o ignore setfib "$FIB1" route get $ADDR0 560} 561 562subnet_route_with_multiple_fibs_on_same_subnet_cleanup() 563{ 564 cleanup_ifaces 565} 566 567atf_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 cleanup 568subnet_route_with_multiple_fibs_on_same_subnet_inet6_head() 569{ 570 atf_set "descr" "Multiple FIBs can have IPv6 subnet routes for the same subnet" 571 atf_set "require.user" "root" 572 atf_set "require.config" "fibs" 573} 574 575subnet_route_with_multiple_fibs_on_same_subnet_inet6_body() 576{ 577 # Configure the TAP interfaces to use a RFC3849 nonrouteable addresses 578 # and a non-default fib 579 ADDR0="2001:db8::2" 580 ADDR1="2001:db8::3" 581 SUBNET="2001:db8::" 582 MASK="64" 583 584 # Check system configuration 585 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 586 atf_skip "This test requires net.add_addr_allfibs=0" 587 fi 588 get_fibs 2 589 590 # Configure TAP interfaces 591 setup_tap "$FIB0" inet6 ${ADDR0} ${MASK} 592 setup_tap "$FIB1" inet6 ${ADDR1} ${MASK} 593 594 # Check that a subnet route exists on both fibs 595 atf_check -o ignore setfib "$FIB0" route -6 get $ADDR1 596 atf_check -o ignore setfib "$FIB1" route -6 get $ADDR0 597} 598 599subnet_route_with_multiple_fibs_on_same_subnet_inet6_cleanup() 600{ 601 cleanup_ifaces 602} 603 604# Test that source address selection works correctly for UDP packets with 605# SO_DONTROUTE set that are sent on non-default FIBs. 606# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host" 607# Regression test for kern/187553 608# 609# The root cause was that ifa_ifwithnet() did not have a fib argument. It 610# would return an address from an interface on any FIB that had a subnet route 611# for the destination. If more than one were available, it would choose the 612# most specific. This is most easily tested by creating a FIB without a 613# default route, then trying to send a UDP packet with SO_DONTROUTE set to an 614# address which is not routable on that FIB. Absent the fix for this bug, 615# in_pcbladdr would choose an interface on any FIB with a default route. With 616# the fix, you will get EUNREACH or ENETUNREACH. 617atf_test_case udp_dontroute cleanup 618udp_dontroute_head() 619{ 620 atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works" 621 atf_set "require.user" "root" 622 atf_set "require.config" "fibs" 623} 624 625udp_dontroute_body() 626{ 627 # Configure the TAP interface to use an RFC5737 nonrouteable address 628 # and a non-default fib 629 ADDR0="192.0.2.2" 630 ADDR1="192.0.2.3" 631 SUBNET="192.0.2.0" 632 MASK="24" 633 # Use a different IP on the same subnet as the target 634 TARGET="192.0.2.100" 635 SRCDIR=`atf_get_srcdir` 636 637 # Check system configuration 638 if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 639 atf_skip "This test requires net.add_addr_allfibs=0" 640 fi 641 get_fibs 2 642 643 # Configure the TAP interfaces 644 setup_tap ${FIB0} inet ${ADDR0} ${MASK} 645 TARGET_TAP=${TAP} 646 setup_tap ${FIB1} inet ${ADDR1} ${MASK} 647 648 # Send a UDP packet with SO_DONTROUTE. In the failure case, it will 649 # return ENETUNREACH, or send the packet to the wrong tap 650 atf_check -o ignore setfib ${FIB0} \ 651 ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 652 cleanup_ifaces 653 654 # Repeat, but this time target the other tap 655 setup_tap ${FIB0} inet ${ADDR0} ${MASK} 656 setup_tap ${FIB1} inet ${ADDR1} ${MASK} 657 TARGET_TAP=${TAP} 658 659 atf_check -o ignore setfib ${FIB1} \ 660 ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 661} 662 663udp_dontroute_cleanup() 664{ 665 cleanup_ifaces 666} 667 668atf_test_case udp_dontroute6 cleanup 669udp_dontroute6_head() 670{ 671 atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works" 672 atf_set "require.user" "root" 673 atf_set "require.config" "fibs" 674} 675 676udp_dontroute6_body() 677{ 678 # Configure the TAP interface to use an RFC3849 nonrouteable address 679 # and a non-default fib 680 ADDR0="2001:db8::2" 681 ADDR1="2001:db8::3" 682 SUBNET="2001:db8::" 683 MASK="64" 684 # Use a different IP on the same subnet as the target 685 TARGET="2001:db8::100" 686 SRCDIR=`atf_get_srcdir` 687 688 atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0" 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 TAP 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