fibs_test.sh revision 265586
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 265586 2014-05-07 18:49:25Z 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 atf_expect_fail "kern/167947 arpresolve checks only the default FIB for the interface route" 59263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 60263445Sasomers # and a non-default fib 61263445Sasomers ADDR0="192.0.2.2" 62263445Sasomers ADDR1="192.0.2.3" 63263445Sasomers SUBNET="192.0.2.0" 64263445Sasomers # Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need 65263445Sasomers # diffferent subnet masks, or FIB1 won't have a subnet route. 66263445Sasomers MASK0="24" 67263445Sasomers MASK1="25" 68263445Sasomers # Spoof a MAC that is reserved per RFC7042 69263445Sasomers SPOOF_ADDR="192.0.2.4" 70263445Sasomers SPOOF_MAC="00:00:5E:00:53:00" 71263445Sasomers 72263445Sasomers # Check system configuration 73263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 74263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 75263445Sasomers fi 76263445Sasomers get_fibs 2 77263445Sasomers 78263445Sasomers # Configure TAP interfaces 79263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK0} 80263445Sasomers TAP0=$TAP 81263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK1} 82263445Sasomers TAP1=$TAP 83263445Sasomers 84263445Sasomers # Simulate a crossover cable 85263445Sasomers socat /dev/${TAP0} /dev/${TAP1} & 86263445Sasomers SOCAT_PID=$! 87263445Sasomers echo ${SOCAT_PID} >> "processes_to_kill" 88265586Sasomers 89263445Sasomers # Send an ICMP echo request with a spoofed source IP 90263445Sasomers setfib 2 nping -c 1 -e ${TAP0} -S ${SPOOF_ADDR} \ 91263445Sasomers --source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \ 92263445Sasomers --icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \ 93263445Sasomers ${ADDR1} 94263445Sasomers # For informational and debugging purposes only, look for the 95263445Sasomers # characteristic error message 96263445Sasomers dmesg | grep "llinfo.*${SPOOF_ADDR}" 97263445Sasomers # Check that the ARP entry exists 98263445Sasomers atf_check -o match:"${SPOOF_ADDR}.*expires" setfib 3 arp ${SPOOF_ADDR} 99263445Sasomers} 100263445Sasomersarpresolve_checks_interface_fib_cleanup() 101263445Sasomers{ 102263445Sasomers for PID in `cat "processes_to_kill"`; do 103263445Sasomers kill $PID 104263445Sasomers done 105263445Sasomers cleanup_tap 106263445Sasomers} 107263445Sasomers 108263445Sasomers 109263445Sasomers# Regression test for kern/187549 110263445Sasomersatf_test_case loopback_and_network_routes_on_nondefault_fib cleanup 111263445Sasomersloopback_and_network_routes_on_nondefault_fib_head() 112263445Sasomers{ 113263445Sasomers atf_set "descr" "When creating and deleting loopback routes, use the interface's fib" 114263445Sasomers atf_set "require.user" "root" 115263445Sasomers atf_set "require.config" "fibs" 116263445Sasomers} 117263445Sasomers 118263445Sasomersloopback_and_network_routes_on_nondefault_fib_body() 119263445Sasomers{ 120263445Sasomers atf_expect_fail "kern/187549 Host and network routes for a new interface appear in the wrong FIB" 121263445Sasomers # Configure the TAP interface to use an RFC5737 nonrouteable address 122263445Sasomers # and a non-default fib 123263445Sasomers ADDR="192.0.2.2" 124263445Sasomers SUBNET="192.0.2.0" 125263445Sasomers MASK="24" 126263445Sasomers 127263445Sasomers # Check system configuration 128263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 129263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 130263445Sasomers fi 131263445Sasomers get_fibs 1 132263445Sasomers 133263445Sasomers # Configure a TAP interface 134263445Sasomers setup_tap ${FIB0} ${ADDR} ${MASK} 135263445Sasomers 136263445Sasomers # Check whether the host route exists in only the correct FIB 137263445Sasomers setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 138263445Sasomers if [ 0 -ne $? ]; then 139263445Sasomers setfib ${FIB0} netstat -rn -f inet 140263445Sasomers atf_fail "Host route did not appear in the correct FIB" 141263445Sasomers fi 142263445Sasomers setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0" 143263445Sasomers if [ 0 -eq $? ]; then 144263445Sasomers setfib 0 netstat -rn -f inet 145263445Sasomers atf_fail "Host route appeared in the wrong FIB" 146263445Sasomers fi 147263445Sasomers 148263445Sasomers # Check whether the network route exists in only the correct FIB 149263445Sasomers setfib ${FIB0} netstat -rn -f inet | \ 150263445Sasomers grep -q "^${SUBNET}/${MASK}.*${TAPD}" 151263445Sasomers if [ 0 -ne $? ]; then 152263445Sasomers setfib ${FIB0} netstat -rn -f inet 153263445Sasomers atf_fail "Network route did not appear in the correct FIB" 154263445Sasomers fi 155263445Sasomers setfib 0 netstat -rn -f inet | \ 156263445Sasomers grep -q "^${SUBNET}/${MASK}.*${TAPD}" 157263445Sasomers if [ 0 -eq $? ]; then 158263445Sasomers setfib ${FIB0} netstat -rn -f inet 159263445Sasomers atf_fail "Network route appeared in the wrong FIB" 160263445Sasomers fi 161263445Sasomers} 162263445Sasomers 163263445Sasomersloopback_and_network_routes_on_nondefault_fib_cleanup() 164263445Sasomers{ 165263445Sasomers cleanup_tap 166263445Sasomers} 167263445Sasomers 168263445Sasomers 169263445Sasomers# Regression test for kern/187552 170263445Sasomersatf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup 171263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_head() 172263445Sasomers{ 173263445Sasomers atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes" 174263445Sasomers atf_set "require.user" "root" 175263445Sasomers atf_set "require.config" "fibs" 176263445Sasomers} 177263445Sasomers 178263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_body() 179263445Sasomers{ 180263445Sasomers atf_expect_fail "kern/187552 default route uses the wrong interface when multiple interfaces have the same subnet but different fibs" 181263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 182263445Sasomers # and a non-default fib 183263445Sasomers ADDR0="192.0.2.2" 184263445Sasomers ADDR1="192.0.2.3" 185263445Sasomers GATEWAY="192.0.2.1" 186263445Sasomers SUBNET="192.0.2.0" 187263445Sasomers MASK="24" 188263445Sasomers 189263445Sasomers # Check system configuration 190263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 191263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 192263445Sasomers fi 193263445Sasomers get_fibs 2 194263445Sasomers 195263445Sasomers # Configure TAP interfaces 196263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK} 197263445Sasomers TAP0=$TAP 198263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK} 199263445Sasomers TAP1=$TAP 200263445Sasomers 201263445Sasomers # Attempt to add default routes 202263445Sasomers setfib ${FIB0} route add default ${GATEWAY} 203263445Sasomers setfib ${FIB1} route add default ${GATEWAY} 204263445Sasomers 205263445Sasomers # Verify that the default route exists for both fibs, with their 206263445Sasomers # respective interfaces. 207263445Sasomers atf_check -o match:"^default.*${TAP0}$" \ 208263445Sasomers setfib ${FIB0} netstat -rn -f inet 209263445Sasomers atf_check -o match:"^default.*${TAP1}$" \ 210263445Sasomers setfib ${FIB1} netstat -rn -f inet 211263445Sasomers} 212263445Sasomers 213263445Sasomersdefault_route_with_multiple_fibs_on_same_subnet_cleanup() 214263445Sasomers{ 215263445Sasomers cleanup_tap 216263445Sasomers} 217263445Sasomers 218263445Sasomers 219263445Sasomers# Regression test for kern/187550 220263445Sasomersatf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup 221263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_head() 222263445Sasomers{ 223263445Sasomers atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet" 224263445Sasomers atf_set "require.user" "root" 225263445Sasomers atf_set "require.config" "fibs" 226263445Sasomers} 227263445Sasomers 228263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_body() 229263445Sasomers{ 230263445Sasomers atf_expect_fail "kern/187550 Multiple interfaces on different FIBs but the same subnet don't all have a subnet route" 231263445Sasomers # Configure the TAP interfaces to use a RFC5737 nonrouteable addresses 232263445Sasomers # and a non-default fib 233263445Sasomers ADDR0="192.0.2.2" 234263445Sasomers ADDR1="192.0.2.3" 235263445Sasomers SUBNET="192.0.2.0" 236263445Sasomers MASK="24" 237263445Sasomers 238263445Sasomers # Check system configuration 239263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 240263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 241263445Sasomers fi 242263445Sasomers get_fibs 2 243263445Sasomers 244263445Sasomers # Configure TAP interfaces 245263445Sasomers setup_tap "$FIB0" ${ADDR0} ${MASK} 246263445Sasomers setup_tap "$FIB1" ${ADDR1} ${MASK} 247263445Sasomers 248263445Sasomers # Check that a subnet route exists on both fibs 249263445Sasomers atf_check -o ignore setfib "$FIB0" route get $ADDR1 250263445Sasomers atf_check -o ignore setfib "$FIB1" route get $ADDR0 251263445Sasomers} 252263445Sasomers 253263445Sasomerssubnet_route_with_multiple_fibs_on_same_subnet_cleanup() 254263445Sasomers{ 255263445Sasomers cleanup_tap 256263445Sasomers} 257263445Sasomers 258263445Sasomers# Test that source address selection works correctly for UDP packets with 259263445Sasomers# SO_DONTROUTE set that are sent on non-default FIBs. 260263445Sasomers# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host" 261263445Sasomers# Regression test for kern/187553 262263445Sasomersatf_test_case udp_dontroute cleanup 263263445Sasomersudp_dontroute_head() 264263445Sasomers{ 265263445Sasomers atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works" 266263445Sasomers atf_set "require.user" "root" 267263445Sasomers atf_set "require.config" "fibs" 268263445Sasomers} 269263445Sasomers 270263445Sasomersudp_dontroute_body() 271263445Sasomers{ 272263445Sasomers atf_expect_fail "kern/187553 Source address selection for UDP packets with SO_DONTROUTE uses the default FIB" 273263445Sasomers # Configure the TAP interface to use an RFC5737 nonrouteable address 274263445Sasomers # and a non-default fib 275263445Sasomers ADDR="192.0.2.2" 276263445Sasomers SUBNET="192.0.2.0" 277263445Sasomers MASK="24" 278263445Sasomers # Use a different IP on the same subnet as the target 279263445Sasomers TARGET="192.0.2.100" 280263445Sasomers 281263445Sasomers # Check system configuration 282263445Sasomers if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then 283263445Sasomers atf_skip "This test requires net.add_addr_allfibs=0" 284263445Sasomers fi 285263445Sasomers get_fibs 1 286263445Sasomers 287263445Sasomers # Configure a TAP interface 288263445Sasomers setup_tap ${FIB0} ${ADDR} ${MASK} 289263445Sasomers 290263445Sasomers # Send a UDP packet with SO_DONTROUTE. In the failure case, it will 291263445Sasomers # return ENETUNREACH 292263445Sasomers SRCDIR=`atf_get_srcdir` 293263445Sasomers atf_check -o ignore setfib ${FIB0} ${SRCDIR}/udp_dontroute ${TARGET} 294263445Sasomers} 295263445Sasomers 296263445Sasomersudp_dontroute_cleanup() 297263445Sasomers{ 298263445Sasomers cleanup_tap 299263445Sasomers} 300263445Sasomers 301263445Sasomers 302263445Sasomersatf_init_test_cases() 303263445Sasomers{ 304263445Sasomers atf_add_test_case arpresolve_checks_interface_fib 305265586Sasomers atf_add_test_case loopback_and_network_routes_on_nondefault_fib 306265586Sasomers atf_add_test_case default_route_with_multiple_fibs_on_same_subnet 307265586Sasomers atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet 308263445Sasomers atf_add_test_case udp_dontroute 309263445Sasomers} 310263445Sasomers 311263445Sasomers# Looks up one or more fibs from the configuration data and validates them. 312263445Sasomers# Returns the results in the env varilables FIB0, FIB1, etc. 313263445Sasomers 314263445Sasomers# parameter numfibs The number of fibs to lookup 315263445Sasomersget_fibs() 316263445Sasomers{ 317263445Sasomers NUMFIBS=$1 318263445Sasomers net_fibs=`sysctl -n net.fibs` 319263445Sasomers i=0 320263445Sasomers while [ $i -lt "$NUMFIBS" ]; do 321263445Sasomers fib=`atf_config_get "fibs" | \ 322263445Sasomers awk -v i=$(( i + 1 )) '{print $i}'` 323263445Sasomers echo "fib is ${fib}" 324263445Sasomers eval FIB${i}=${fib} 325263445Sasomers if [ "$fib" -ge "$net_fibs" ]; then 326263445Sasomers atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}" 327263445Sasomers fi 328263445Sasomers i=$(( $i + 1 )) 329263445Sasomers done 330263445Sasomers} 331263445Sasomers 332263445Sasomers# Creates a new tap(4) interface, registers it for cleanup, and returns the 333263445Sasomers# name via the environment variable TAP 334263445Sasomersget_tap() 335263445Sasomers{ 336263445Sasomers local TAPN=0 337263445Sasomers while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do 338263445Sasomers if [ "$TAPN" -ge 8 ]; then 339263445Sasomers atf_skip "Could not create a tap(4) interface" 340263445Sasomers else 341263445Sasomers TAPN=$(($TAPN + 1)) 342263445Sasomers fi 343263445Sasomers done 344263445Sasomers local TAPD=tap${TAPN} 345263445Sasomers # Record the TAP device so we can clean it up later 346263445Sasomers echo ${TAPD} >> "tap_devices_to_cleanup" 347263445Sasomers TAP=${TAPD} 348263445Sasomers} 349263445Sasomers 350263445Sasomers# Create a tap(4) interface, configure it, and register it for cleanup. 351263445Sasomers# parameters: 352263445Sasomers# fib 353263445Sasomers# IP address 354263445Sasomers# Netmask in number of bits (eg 24 or 8) 355263445Sasomers# Return: the tap interface name as the env variable TAP 356263445Sasomerssetup_tap() 357263445Sasomers{ 358263445Sasomers local FIB=$1 359263445Sasomers local ADDR=$2 360263445Sasomers local MASK=$3 361263445Sasomers get_tap 362263445Sasomers echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB 363263445Sasomers setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB 364263445Sasomers} 365263445Sasomers 366263445Sasomerscleanup_tap() 367263445Sasomers{ 368263445Sasomers for TAPD in `cat "tap_devices_to_cleanup"`; do 369263445Sasomers ifconfig ${TAPD} destroy 370263445Sasomers done 371263445Sasomers} 372