atf_test_case arpresolve_checks_interface_fib cleanup
arpresolve_checks_interface_fib_head()
{
atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes"
atf_set "require.user" "root"
atf_set "require.progs" "nping"
}
arpresolve_checks_interface_fib_body()
{
ADDR0="192.0.2.2"
ADDR1="192.0.2.3"
SUBNET="192.0.2.0"
MASK0="24"
MASK1="25"
SPOOF_ADDR="192.0.2.4"
SPOOF_MAC="00:00:5E:00:53:00"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
get_epair
setup_iface "$EPAIRA" "$FIB0" inet ${ADDR0} ${MASK0}
setup_iface "$EPAIRB" "$FIB1" inet ${ADDR1} ${MASK1}
setfib "$FIB0" nping -c 1 -e ${EPAIRA} -S ${SPOOF_ADDR} \
--source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \
--icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \
${ADDR1}
dmesg | grep "llinfo.*${SPOOF_ADDR}"
atf_check -o match:"${SPOOF_ADDR}.*expires" setfib "$FIB1" arp ${SPOOF_ADDR}
}
arpresolve_checks_interface_fib_cleanup()
{
cleanup_ifaces
}
atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
loopback_and_network_routes_on_nondefault_fib_head()
{
atf_set "descr" "When creating and deleting loopback IPv4 routes, use the interface's fib"
atf_set "require.user" "root"
}
loopback_and_network_routes_on_nondefault_fib_body()
{
ADDR="192.0.2.2"
SUBNET="192.0.2.0"
MASK="24"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 1
setup_tap ${FIB0} inet ${ADDR} ${MASK}
setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
if [ 0 -ne $? ]; then
setfib ${FIB0} netstat -rn -f inet
atf_fail "Host route did not appear in the correct FIB"
fi
setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
if [ 0 -eq $? ]; then
setfib 0 netstat -rn -f inet
atf_fail "Host route appeared in the wrong FIB"
fi
setfib ${FIB0} netstat -rn -f inet | \
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
if [ 0 -ne $? ]; then
setfib ${FIB0} netstat -rn -f inet
atf_fail "Network route did not appear in the correct FIB"
fi
setfib 0 netstat -rn -f inet | \
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
if [ 0 -eq $? ]; then
setfib 0 netstat -rn -f inet
atf_fail "Network route appeared in the wrong FIB"
fi
}
loopback_and_network_routes_on_nondefault_fib_cleanup()
{
cleanup_ifaces
}
atf_test_case loopback_and_network_routes_on_nondefault_fib_inet6 cleanup
loopback_and_network_routes_on_nondefault_fib_inet6_head()
{
atf_set "descr" "When creating and deleting loopback IPv6 routes, use the interface's fib"
atf_set "require.user" "root"
}
loopback_and_network_routes_on_nondefault_fib_inet6_body()
{
ADDR="2001:db8::2"
SUBNET="2001:db8::"
MASK="64"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 1
setup_tap ${FIB0} inet6 ${ADDR} ${MASK}
setfib ${FIB0} netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
if [ 0 -ne $? ]; then
setfib ${FIB0} netstat -rn -f inet6
atf_fail "Host route did not appear in the correct FIB"
fi
setfib 0 netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
if [ 0 -eq $? ]; then
setfib 0 netstat -rn -f inet6
atf_fail "Host route appeared in the wrong FIB"
fi
setfib ${FIB0} netstat -rn -f inet6 | \
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
if [ 0 -ne $? ]; then
setfib ${FIB0} netstat -rn -f inet6
atf_fail "Network route did not appear in the correct FIB"
fi
setfib 0 netstat -rn -f inet6 | \
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
if [ 0 -eq $? ]; then
setfib 0 netstat -rn -f inet6
atf_fail "Network route appeared in the wrong FIB"
fi
}
loopback_and_network_routes_on_nondefault_fib_inet6_cleanup()
{
cleanup_ifaces
}
atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
default_route_with_multiple_fibs_on_same_subnet_head()
{
atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv4 routes"
atf_set "require.user" "root"
}
default_route_with_multiple_fibs_on_same_subnet_body()
{
ADDR0="192.0.2.2"
ADDR1="192.0.2.3"
GATEWAY="192.0.2.1"
SUBNET="192.0.2.0"
MASK="24"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap "$FIB0" inet ${ADDR0} ${MASK}
TAP0=$TAP
setup_tap "$FIB1" inet ${ADDR1} ${MASK}
TAP1=$TAP
setfib ${FIB0} route add default ${GATEWAY}
setfib ${FIB1} route add default ${GATEWAY}
atf_check -o match:"^default.*${TAP0}$" \
setfib ${FIB0} netstat -rn -f inet
atf_check -o match:"^default.*${TAP1}$" \
setfib ${FIB1} netstat -rn -f inet
}
default_route_with_multiple_fibs_on_same_subnet_cleanup()
{
cleanup_ifaces
}
atf_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
default_route_with_multiple_fibs_on_same_subnet_inet6_head()
{
atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv6 routes"
atf_set "require.user" "root"
}
default_route_with_multiple_fibs_on_same_subnet_inet6_body()
{
ADDR0="2001:db8::2"
ADDR1="2001:db8::3"
GATEWAY="2001:db8::1"
SUBNET="2001:db8::"
MASK="64"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
TAP0=$TAP
setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
TAP1=$TAP
setfib ${FIB0} route -6 add default ${GATEWAY}
setfib ${FIB1} route -6 add default ${GATEWAY}
atf_check -o match:"^default.*${TAP0}$" \
setfib ${FIB0} netstat -rn -f inet6
atf_check -o match:"^default.*${TAP1}$" \
setfib ${FIB1} netstat -rn -f inet6
}
default_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
{
cleanup_ifaces
}
atf_test_case same_ip_multiple_ifaces_fib0 cleanup
same_ip_multiple_ifaces_fib0_head()
{
atf_set "descr" "Can remove an IPv4 alias from an interface when the same IPv4 is also assigned to another interface."
atf_set "require.user" "root"
}
same_ip_multiple_ifaces_fib0_body()
{
ADDR="192.0.2.2"
MASK0="24"
MASK1="32"
setup_tap 0 inet ${ADDR} ${MASK0}
TAP0=${TAP}
atf_expect_fail "The test results in an ifconfig error and thus spuriously fails"
setup_tap 0 inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP1} -alias ${ADDR}
setup_tap 0 inet ${ADDR} ${MASK0}
TAP0=${TAP}
setup_tap 0 inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP0} -alias ${ADDR}
}
same_ip_multiple_ifaces_fib0_cleanup()
{
cleanup_ifaces
}
atf_test_case same_ip_multiple_ifaces cleanup
same_ip_multiple_ifaces_head()
{
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."
atf_set "require.user" "root"
}
same_ip_multiple_ifaces_body()
{
ADDR="192.0.2.2"
MASK0="24"
MASK1="32"
get_fibs 4
setup_tap ${FIB0} inet ${ADDR} ${MASK0}
TAP0=${TAP}
setup_tap ${FIB1} inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP1} -alias ${ADDR}
atf_check -o not-match:"^${ADDR}[[:space:]]" \
setfib ${FIB1} netstat -rn -f inet
setup_tap ${FIB2} inet ${ADDR} ${MASK0}
TAP0=${TAP}
setup_tap ${FIB3} inet ${ADDR} ${MASK1}
TAP1=${TAP}
ifconfig ${TAP0} -alias ${ADDR}
atf_check -o not-match:"^${ADDR}[[:space:]]" \
setfib ${FIB2} netstat -rn -f inet
}
same_ip_multiple_ifaces_cleanup()
{
for TAPD in `tail -r "ifaces_to_cleanup"`; do
echo ifconfig ${TAPD} destroy
ifconfig ${TAPD} destroy
done
}
atf_test_case same_ip_multiple_ifaces_inet6 cleanup
same_ip_multiple_ifaces_inet6_head()
{
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."
atf_set "require.user" "root"
}
same_ip_multiple_ifaces_inet6_body()
{
ADDR="2001:db8::2"
MASK0="64"
MASK1="128"
get_fibs 2
setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
TAP0=${TAP}
setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
TAP1=${TAP}
atf_check -s exit:0 ifconfig ${TAP1} inet6 ${ADDR} -alias
atf_check -o not-match:"^${ADDR}[[:space:]]" \
setfib ${FIB1} netstat -rn -f inet6
ifconfig ${TAP1} destroy
ifconfig ${TAP0} destroy
setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
TAP0=${TAP}
setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
TAP1=${TAP}
atf_check -s exit:0 ifconfig ${TAP0} inet6 ${ADDR} -alias
atf_check -o not-match:"^${ADDR}[[:space:]]" \
setfib ${FIB0} netstat -rn -f inet6
}
same_ip_multiple_ifaces_inet6_cleanup()
{
cleanup_ifaces
}
atf_test_case slaac_on_nondefault_fib6 cleanup
slaac_on_nondefault_fib6_head()
{
atf_set "descr" "SLAAC correctly installs routes on non-default FIBs"
atf_set "require.user" "root"
atf_set "require.config" "allow_sysctl_side_effects"
}
slaac_on_nondefault_fib6_body()
{
PREFIX="2001:db8:$(printf "%x" `jot -r 1 0 65535`):$(printf "%x" `jot -r 1 0 65535`)"
ADDR="$PREFIX::2"
GATEWAY="$PREFIX::1"
SUBNET="$PREFIX:"
MASK="64"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
sysctl -n "net.inet6.ip6.rfc6204w3" >> "rfc6204w3.state"
sysctl -n "net.inet6.ip6.forwarding" >> "forwarding.state"
sysctl net.inet6.ip6.forwarding=1
sysctl net.inet6.ip6.rfc6204w3=1
get_epair
setup_iface "$EPAIRA" "$FIB0" inet6 ${ADDR} ${MASK}
echo setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up
setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up
rtadvd -p rtadvd.pid -C rtadvd.sock -c /dev/null "$EPAIRA"
rtsol "$EPAIRB"
atf_check -o match:"inet6 ${SUBNET}.*prefixlen ${MASK}.*autoconf" \
ifconfig "$EPAIRB"
atf_check -o match:"${SUBNET}.*\<UHS\>.*lo0" \
netstat -rnf inet6 -F $FIB1
atf_check -o match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \
netstat -rnf inet6 -F $FIB1
atf_check -o match:"default.*\<UG\>.*$EPAIRB" \
netstat -rnf inet6 -F $FIB1
for fib in $( seq 0 $(($(sysctl -n net.fibs) - 1))); do
if [ "$fib" = "$FIB1" -o "$fib" = "$FIB0" ]; then
continue
fi
atf_check -o not-match:"${SUBNET}.*\<UHS\>.*lo0" \
netstat -rnf inet6 -F $fib
atf_check -o not-match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \
netstat -rnf inet6 -F $fib
atf_check -o not-match:"default.*\<UG\>.*$EPAIRB" \
netstat -rnf inet6 -F $fib
done
}
slaac_on_nondefault_fib6_cleanup()
{
if [ -f "rtadvd.pid" ]; then
pkill -kill -F rtadvd.pid
rm -f rtadvd.pid
fi
cleanup_ifaces
if [ -f "forwarding.state" ] ; then
sysctl "net.inet6.ip6.forwarding"=`cat "forwarding.state"`
rm "forwarding.state"
fi
if [ -f "rfc6204w3.state" ] ; then
sysctl "net.inet6.ip6.rfc6204w3"=`cat "rfc6204w3.state"`
rm "rfc6204w3.state"
fi
}
atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
subnet_route_with_multiple_fibs_on_same_subnet_head()
{
atf_set "descr" "Multiple FIBs can have IPv4 subnet routes for the same subnet"
atf_set "require.user" "root"
}
subnet_route_with_multiple_fibs_on_same_subnet_body()
{
ADDR0="192.0.2.2"
ADDR1="192.0.2.3"
SUBNET="192.0.2.0"
MASK="24"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap "$FIB0" inet ${ADDR0} ${MASK}
setup_tap "$FIB1" inet ${ADDR1} ${MASK}
atf_check -o ignore setfib "$FIB0" route get $ADDR1
atf_check -o ignore setfib "$FIB1" route get $ADDR0
}
subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
{
cleanup_ifaces
}
atf_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
subnet_route_with_multiple_fibs_on_same_subnet_inet6_head()
{
atf_set "descr" "Multiple FIBs can have IPv6 subnet routes for the same subnet"
atf_set "require.user" "root"
}
subnet_route_with_multiple_fibs_on_same_subnet_inet6_body()
{
ADDR0="2001:db8::2"
ADDR1="2001:db8::3"
SUBNET="2001:db8::"
MASK="64"
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
atf_check -o ignore setfib "$FIB0" route -6 get $ADDR1
atf_check -o ignore setfib "$FIB1" route -6 get $ADDR0
}
subnet_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
{
cleanup_ifaces
}
atf_test_case udp_dontroute cleanup
udp_dontroute_head()
{
atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works"
atf_set "require.user" "root"
}
udp_dontroute_body()
{
ADDR0="192.0.2.2"
ADDR1="192.0.2.3"
SUBNET="192.0.2.0"
MASK="24"
TARGET="192.0.2.100"
SRCDIR=`atf_get_srcdir`
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap ${FIB0} inet ${ADDR0} ${MASK}
TARGET_TAP=${TAP}
setup_tap ${FIB1} inet ${ADDR1} ${MASK}
atf_check -o ignore setfib ${FIB0} \
${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
cleanup_ifaces
setup_tap ${FIB0} inet ${ADDR0} ${MASK}
setup_tap ${FIB1} inet ${ADDR1} ${MASK}
TARGET_TAP=${TAP}
atf_check -o ignore setfib ${FIB1} \
${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
}
udp_dontroute_cleanup()
{
cleanup_ifaces
}
atf_test_case udp_dontroute6 cleanup
udp_dontroute6_head()
{
atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works"
atf_set "require.user" "root"
}
udp_dontroute6_body()
{
if [ "$(atf_config_get ci false)" = "true" ]; then
atf_skip "https://bugs.freebsd.org/244172"
fi
ADDR0="2001:db8::2"
ADDR1="2001:db8::3"
SUBNET="2001:db8::"
MASK="64"
TARGET="2001:db8::100"
SRCDIR=`atf_get_srcdir`
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
get_fibs 2
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
TARGET_TAP=${TAP}
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
atf_check -o ignore setfib ${FIB0} \
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
cleanup_ifaces
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
TARGET_TAP=${TAP}
atf_check -o ignore setfib ${FIB1} \
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
}
udp_dontroute6_cleanup()
{
cleanup_ifaces
}
atf_init_test_cases()
{
atf_add_test_case arpresolve_checks_interface_fib
atf_add_test_case loopback_and_network_routes_on_nondefault_fib
atf_add_test_case loopback_and_network_routes_on_nondefault_fib_inet6
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet_inet6
atf_add_test_case same_ip_multiple_ifaces_fib0
atf_add_test_case same_ip_multiple_ifaces
atf_add_test_case same_ip_multiple_ifaces_inet6
atf_add_test_case slaac_on_nondefault_fib6
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6
atf_add_test_case udp_dontroute
atf_add_test_case udp_dontroute6
}
get_fibs()
{
NUMFIBS=$1
net_fibs=`sysctl -n net.fibs`
if [ $net_fibs -lt $(($NUMFIBS + 1)) ]; then
atf_check -o ignore sysctl net.fibs=$(($NUMFIBS + 1))
net_fibs=`sysctl -n net.fibs`
fi
i=0
while [ $i -lt "$NUMFIBS" ]; do
eval FIB${i}=$(($i + 1))
i=$(( $i + 1 ))
done
}
get_epair()
{
local EPAIRD
if (which pfctl && pfctl -s info | grep -q 'Status: Enabled') ||
[ `sysctl -n net.inet.ip.fw.enable` = "1" ] ||
(which ipf && ipf -V); then
atf_skip "firewalls interfere with this test"
fi
if EPAIRD=`ifconfig epair create`; then
echo ${EPAIRD} >> "ifaces_to_cleanup"
EPAIRA=${EPAIRD}
EPAIRB=${EPAIRD%a}b
else
atf_skip "Could not create epair(4) interfaces"
fi
}
get_tap()
{
local TAPD
if TAPD=`ifconfig tap create`; then
echo ${TAPD} >> "ifaces_to_cleanup"
TAP=${TAPD}
else
atf_skip "Could not create a tap(4) interface"
fi
}
setup_iface()
{
local IFACE=$1
local FIB=$2
local PROTO=$3
local ADDR=$4
local MASK=$5
local FLAGS=$6
atf_check setfib ${FIB} ifconfig $IFACE ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
}
setup_tap()
{
get_tap
setup_iface "$TAP" "$@"
}
cleanup_ifaces()
{
if [ -f ifaces_to_cleanup ]; then
for iface in $(cat ifaces_to_cleanup); do
echo ifconfig "${iface}" destroy
ifconfig "${iface}" destroy 2>/dev/null || true
done
rm -f ifaces_to_cleanup
fi
}