fibs_test.sh revision 267186
1263445Sasomers# 2263445Sasomers# Copyright (c) 2014 Spectra Logic Corporation 3263445Sasomers# All rights reserved. 4265586Sasomers# 5263445Sasomers# Redistribution and use in source and binary forms, with or without 6263445Sasomers# modification, are permitted provided that the following conditions 7263445Sasomers# are met: 8263445Sasomers# 1. Redistributions of source code must retain the above copyright 9263445Sasomers# notice, this list of conditions, and the following disclaimer, 10263445Sasomers# without modification. 11263445Sasomers# 2. Redistributions in binary form must reproduce at minimum a disclaimer 12263445Sasomers# substantially similar to the "NO WARRANTY" disclaimer below 13263445Sasomers# ("Disclaimer") and any redistribution must be conditioned upon 14263445Sasomers# including a substantially similar Disclaimer requirement for further 15263445Sasomers# binary redistribution. 16265586Sasomers# 17263445Sasomers# NO WARRANTY 18263445Sasomers# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19263445Sasomers# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20263445Sasomers# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21263445Sasomers# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22263445Sasomers# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23263445Sasomers# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24263445Sasomers# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25263445Sasomers# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26263445Sasomers# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27263445Sasomers# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28263445Sasomers# POSSIBILITY OF SUCH DAMAGES. 29265586Sasomers# 30263445Sasomers# Authors: Alan Somers (Spectra Logic Corporation) 31263445Sasomers# 32263445Sasomers# $FreeBSD: stable/10/tests/sys/netinet/fibs_test.sh 267186 2014-06-06 20:35:40Z asomers $ 33263445Sasomers 34263445Sasomers# All of the tests in this file requires the test-suite config variable "fibs" 35263445Sasomers# to be defined to a space-delimited list of FIBs that may be used for testing. 36263445Sasomers 37263445Sasomers# arpresolve should check the interface fib for routes to a target when 38263445Sasomers# creating an ARP table entry. This is a regression for kern/167947, where 39263445Sasomers# arpresolve only checked the default route. 40263445Sasomers# 41263445Sasomers# Outline: 42263445Sasomers# Create two tap(4) interfaces 43263445Sasomers# Simulate a crossover cable between them by using net/socat 44263445Sasomers# Use nping (from security/nmap) to send an ICMP echo request from one 45263445Sasomers# interface to the other, spoofing the source IP. The source IP must be 46265586Sasomers# spoofed, or else it will already have an entry in the arp table. 47263445Sasomers# Check whether an arp entry exists for the spoofed IP 48263445Sasomersatf_test_case arpresolve_checks_interface_fib cleanup 49263445Sasomersarpresolve_checks_interface_fib_head() 50263445Sasomers{ 51263445Sasomers atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes" 52263445Sasomers atf_set "require.user" "root" 53263445Sasomers atf_set "require.config" "fibs" 54263445Sasomers atf_set "require.progs" "socat nping" 55263445Sasomers} 56263445Sasomersarpresolve_checks_interface_fib_body() 57263445Sasomers{ 58263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 59263445Sasomers # and a non-default fib 60263445Sasomers ADDR0="192.0.2.2" 61263445Sasomers ADDR1="192.0.2.3" 62263445Sasomers SUBNET="192.0.2.0" 63263445Sasomers # Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need 64263445Sasomers # diffferent subnet masks, or FIB1 won't have a subnet route. 65263445Sasomers MASK0="24" 66263445Sasomers MASK1="25" 67263445Sasomers # Spoof a MAC that is reserved per RFC7042 68263445Sasomers SPOOF_ADDR="192.0.2.4" 69263445Sasomers SPOOF_MAC="00:00:5E:00:53:00" 70263445Sasomers 71263445Sasomers # Check system configuration 72263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 73263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 74263445Sasomers fi 75263445Sasomers get_fibs 2 76263445Sasomers 77263445Sasomers # Configure TAP interfaces 78263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK0} 79263445Sasomers TAP0=$TAP 80263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK1} 81263445Sasomers TAP1=$TAP 82263445Sasomers 83263445Sasomers # Simulate a crossover cable 84263445Sasomers socat /dev/${TAP0} /dev/${TAP1} & 85263445Sasomers SOCAT_PID=$! 86263445Sasomers echo ${SOCAT_PID} >> "processes_to_kill" 87265586Sasomers 88263445Sasomers # Send an ICMP echo request with a spoofed source IP 89263445Sasomers setfib 2 nping -c 1 -e ${TAP0} -S ${SPOOF_ADDR} \ 90263445Sasomers --source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \ 91263445Sasomers --icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \ 92263445Sasomers ${ADDR1} 93263445Sasomers # For informational and debugging purposes only, look for the 94263445Sasomers # characteristic error message 95263445Sasomers dmesg | grep "llinfo.*${SPOOF_ADDR}" 96263445Sasomers # Check that the ARP entry exists 97263445Sasomers atf_check -o match:"${SPOOF_ADDR}.*expires" setfib 3 arp ${SPOOF_ADDR} 98263445Sasomers} 99263445Sasomersarpresolve_checks_interface_fib_cleanup() 100263445Sasomers{ 101263445Sasomers for PID in `cat "processes_to_kill"`; do 102263445Sasomers kill $PID 103263445Sasomers done 104263445Sasomers cleanup_tap 105263445Sasomers} 106263445Sasomers 107263445Sasomers 108263445Sasomers# Regression test for kern/187549 109263445Sasomersatf_test_case loopback_and_network_routes_on_nondefault_fib cleanup 110263445Sasomersloopback_and_network_routes_on_nondefault_fib_head() 111263445Sasomers{ 112263445Sasomers atf_set "descr" "When creating and deleting loopback routes, use the interface's fib" 113263445Sasomers atf_set "require.user" "root" 114263445Sasomers atf_set "require.config" "fibs" 115263445Sasomers} 116263445Sasomers 117263445Sasomersloopback_and_network_routes_on_nondefault_fib_body() 118263445Sasomers{ 119263445Sasomers atf_expect_fail "kern/187549 Host and network routes for a new interface appear in the wrong FIB" 120263445Sasomers # Configure the TAP interface to use an RFC5737 nonrouteable address 121263445Sasomers # and a non-default fib 122263445Sasomers ADDR="192.0.2.2" 123263445Sasomers SUBNET="192.0.2.0" 124263445Sasomers MASK="24" 125263445Sasomers 126263445Sasomers # Check system configuration 127263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 128263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 129263445Sasomers fi 130263445Sasomers get_fibs 1 131263445Sasomers 132263445Sasomers # Configure a TAP interface 133263445Sasomers setup_tap ${FIB0} ${ADDR} ${MASK} 134263445Sasomers 135263445Sasomers # Check whether the host route exists in only the correct FIB 136263445Sasomers setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 137263445Sasomers if [ 0 -ne $? ]; then 138263445Sasomers setfib ${FIB0} netstat -rn -f inet 139263445Sasomers atf_fail "Host route did not appear in the correct FIB" 140263445Sasomers fi 141263445Sasomers setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 142263445Sasomers if [ 0 -eq $? ]; then 143263445Sasomers setfib 0 netstat -rn -f inet 144263445Sasomers atf_fail "Host route appeared in the wrong FIB" 145263445Sasomers fi 146263445Sasomers 147263445Sasomers # Check whether the network route exists in only the correct FIB 148263445Sasomers setfib ${FIB0} netstat -rn -f inet | \ 149263445Sasomers grep -q "^${SUBNET}/${MASK}.*${TAPD}" 150263445Sasomers if [ 0 -ne $? ]; then 151263445Sasomers setfib ${FIB0} netstat -rn -f inet 152263445Sasomers atf_fail "Network route did not appear in the correct FIB" 153263445Sasomers fi 154263445Sasomers setfib 0 netstat -rn -f inet | \ 155263445Sasomers grep -q "^${SUBNET}/${MASK}.*${TAPD}" 156263445Sasomers if [ 0 -eq $? ]; then 157263445Sasomers setfib ${FIB0} netstat -rn -f inet 158263445Sasomers atf_fail "Network route appeared in the wrong FIB" 159263445Sasomers fi 160263445Sasomers} 161263445Sasomers 162263445Sasomersloopback_and_network_routes_on_nondefault_fib_cleanup() 163263445Sasomers{ 164263445Sasomers cleanup_tap 165263445Sasomers} 166263445Sasomers 167263445Sasomers 168263445Sasomers# Regression test for kern/187552 169263445Sasomersatf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup 170263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_head() 171263445Sasomers{ 172263445Sasomers atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes" 173263445Sasomers atf_set "require.user" "root" 174263445Sasomers atf_set "require.config" "fibs" 175263445Sasomers} 176263445Sasomers 177263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_body() 178263445Sasomers{ 179263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 180263445Sasomers # and a non-default fib 181263445Sasomers ADDR0="192.0.2.2" 182263445Sasomers ADDR1="192.0.2.3" 183263445Sasomers GATEWAY="192.0.2.1" 184263445Sasomers SUBNET="192.0.2.0" 185263445Sasomers MASK="24" 186263445Sasomers 187263445Sasomers # Check system configuration 188263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 189263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 190263445Sasomers fi 191263445Sasomers get_fibs 2 192263445Sasomers 193263445Sasomers # Configure TAP interfaces 194263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK} 195263445Sasomers TAP0=$TAP 196263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK} 197263445Sasomers TAP1=$TAP 198263445Sasomers 199263445Sasomers # Attempt to add default routes 200263445Sasomers setfib ${FIB0} route add default ${GATEWAY} 201263445Sasomers setfib ${FIB1} route add default ${GATEWAY} 202263445Sasomers 203263445Sasomers # Verify that the default route exists for both fibs, with their 204263445Sasomers # respective interfaces. 205263445Sasomers atf_check -o match:"^default.*${TAP0}$" \ 206263445Sasomers setfib ${FIB0} netstat -rn -f inet 207263445Sasomers atf_check -o match:"^default.*${TAP1}$" \ 208263445Sasomers setfib ${FIB1} netstat -rn -f inet 209263445Sasomers} 210263445Sasomers 211263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_cleanup() 212263445Sasomers{ 213263445Sasomers cleanup_tap 214263445Sasomers} 215263445Sasomers 216263445Sasomers 217263445Sasomers# Regression test for kern/187550 218263445Sasomersatf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup 219263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_head() 220263445Sasomers{ 221263445Sasomers atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet" 222263445Sasomers atf_set "require.user" "root" 223263445Sasomers atf_set "require.config" "fibs" 224263445Sasomers} 225263445Sasomers 226263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_body() 227263445Sasomers{ 228263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 229263445Sasomers # and a non-default fib 230263445Sasomers ADDR0="192.0.2.2" 231263445Sasomers ADDR1="192.0.2.3" 232263445Sasomers SUBNET="192.0.2.0" 233263445Sasomers MASK="24" 234263445Sasomers 235263445Sasomers # Check system configuration 236263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 237263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 238263445Sasomers fi 239263445Sasomers get_fibs 2 240263445Sasomers 241263445Sasomers # Configure TAP interfaces 242263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK} 243263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK} 244263445Sasomers 245263445Sasomers # Check that a subnet route exists on both fibs 246263445Sasomers atf_check -o ignore setfib "$FIB0" route get $ADDR1 247263445Sasomers atf_check -o ignore setfib "$FIB1" route get $ADDR0 248263445Sasomers} 249263445Sasomers 250263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_cleanup() 251263445Sasomers{ 252263445Sasomers cleanup_tap 253263445Sasomers} 254263445Sasomers 255263445Sasomers# Test that source address selection works correctly for UDP packets with 256263445Sasomers# SO_DONTROUTE set that are sent on non-default FIBs. 257263445Sasomers# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host" 258263445Sasomers# Regression test for kern/187553 259267186Sasomers# 260267186Sasomers# The root cause was that ifa_ifwithnet() did not have a fib argument. It 261267186Sasomers# would return an address from an interface on any FIB that had a subnet route 262267186Sasomers# for the destination. If more than one were available, it would choose the 263267186Sasomers# most specific. This is most easily tested by creating a FIB without a 264267186Sasomers# default route, then trying to send a UDP packet with SO_DONTROUTE set to an 265267186Sasomers# address which is not routable on that FIB. Absent the fix for this bug, 266267186Sasomers# in_pcbladdr would choose an interface on any FIB with a default route. With 267267186Sasomers# the fix, you will get EUNREACH or ENETUNREACH. 268263445Sasomersatf_test_case udp_dontroute cleanup 269263445Sasomersudp_dontroute_head() 270263445Sasomers{ 271263445Sasomers atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works" 272263445Sasomers atf_set "require.user" "root" 273263445Sasomers atf_set "require.config" "fibs" 274263445Sasomers} 275263445Sasomers 276263445Sasomersudp_dontroute_body() 277263445Sasomers{ 278263445Sasomers atf_expect_fail "kern/187553 Source address selection for UDP packets with SO_DONTROUTE uses the default FIB" 279263445Sasomers # Configure the TAP interface to use an RFC5737 nonrouteable address 280263445Sasomers # and a non-default fib 281267186Sasomers ADDR0="192.0.2.2" 282267186Sasomers ADDR1="192.0.2.3" 283263445Sasomers SUBNET="192.0.2.0" 284263445Sasomers MASK="24" 285263445Sasomers # Use a different IP on the same subnet as the target 286263445Sasomers TARGET="192.0.2.100" 287267186Sasomers SRCDIR=`atf_get_srcdir` 288263445Sasomers 289263445Sasomers # Check system configuration 290263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 291263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 292263445Sasomers fi 293267186Sasomers get_fibs 2 294263445Sasomers 295267186Sasomers # Configure the TAP interfaces 296267186Sasomers setup_tap ${FIB0} ${ADDR0} ${MASK} 297267186Sasomers TARGET_TAP=${TAP} 298267186Sasomers setup_tap ${FIB1} ${ADDR1} ${MASK} 299263445Sasomers 300263445Sasomers # Send a UDP packet with SO_DONTROUTE. In the failure case, it will 301267186Sasomers # return ENETUNREACH, or send the packet to the wrong tap 302267186Sasomers atf_check -o ignore setfib ${FIB0} \ 303267186Sasomers ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 304267186Sasomers cleanup_tap 305267186Sasomers 306267186Sasomers # Repeat, but this time target the other tap 307267186Sasomers setup_tap ${FIB0} ${ADDR0} ${MASK} 308267186Sasomers setup_tap ${FIB1} ${ADDR1} ${MASK} 309267186Sasomers TARGET_TAP=${TAP} 310267186Sasomers 311267186Sasomers atf_check -o ignore setfib ${FIB1} \ 312267186Sasomers ${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP} 313263445Sasomers} 314263445Sasomers 315263445Sasomersudp_dontroute_cleanup() 316263445Sasomers{ 317263445Sasomers cleanup_tap 318263445Sasomers} 319263445Sasomers 320263445Sasomers 321263445Sasomersatf_init_test_cases() 322263445Sasomers{ 323263445Sasomers atf_add_test_case arpresolve_checks_interface_fib 324265586Sasomers atf_add_test_case loopback_and_network_routes_on_nondefault_fib 325265586Sasomers atf_add_test_case default_route_with_multiple_fibs_on_same_subnet 326265586Sasomers atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet 327263445Sasomers atf_add_test_case udp_dontroute 328263445Sasomers} 329263445Sasomers 330263445Sasomers# Looks up one or more fibs from the configuration data and validates them. 331263445Sasomers# Returns the results in the env varilables FIB0, FIB1, etc. 332263445Sasomers 333263445Sasomers# parameter numfibs The number of fibs to lookup 334263445Sasomersget_fibs() 335263445Sasomers{ 336263445Sasomers NUMFIBS=$1 337263445Sasomers net_fibs=`sysctl -n net.fibs` 338263445Sasomers i=0 339263445Sasomers while [ $i -lt "$NUMFIBS" ]; do 340263445Sasomers fib=`atf_config_get "fibs" | \ 341263445Sasomers awk -v i=$(( i + 1 )) '{print $i}'` 342263445Sasomers echo "fib is ${fib}" 343263445Sasomers eval FIB${i}=${fib} 344263445Sasomers if [ "$fib" -ge "$net_fibs" ]; then 345263445Sasomers atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}" 346263445Sasomers fi 347263445Sasomers i=$(( $i + 1 )) 348263445Sasomers done 349263445Sasomers} 350263445Sasomers 351263445Sasomers# Creates a new tap(4) interface, registers it for cleanup, and returns the 352263445Sasomers# name via the environment variable TAP 353263445Sasomersget_tap() 354263445Sasomers{ 355263445Sasomers local TAPN=0 356263445Sasomers while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do 357263445Sasomers if [ "$TAPN" -ge 8 ]; then 358263445Sasomers atf_skip "Could not create a tap(4) interface" 359263445Sasomers else 360263445Sasomers TAPN=$(($TAPN + 1)) 361263445Sasomers fi 362263445Sasomers done 363263445Sasomers local TAPD=tap${TAPN} 364263445Sasomers # Record the TAP device so we can clean it up later 365263445Sasomers echo ${TAPD} >> "tap_devices_to_cleanup" 366263445Sasomers TAP=${TAPD} 367263445Sasomers} 368263445Sasomers 369263445Sasomers# Create a tap(4) interface, configure it, and register it for cleanup. 370263445Sasomers# parameters: 371263445Sasomers# fib 372263445Sasomers# IP address 373263445Sasomers# Netmask in number of bits (eg 24 or 8) 374263445Sasomers# Return: the tap interface name as the env variable TAP 375263445Sasomerssetup_tap() 376263445Sasomers{ 377263445Sasomers local FIB=$1 378263445Sasomers local ADDR=$2 379263445Sasomers local MASK=$3 380263445Sasomers get_tap 381263445Sasomers echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB 382263445Sasomers setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB 383263445Sasomers} 384263445Sasomers 385263445Sasomerscleanup_tap() 386263445Sasomers{ 387263445Sasomers for TAPD in `cat "tap_devices_to_cleanup"`; do 388263445Sasomers ifconfig ${TAPD} destroy 389263445Sasomers done 390267186Sasomers rm "tap_devices_to_cleanup" 391263445Sasomers} 392