mirror of
https://github.com/dtaht/unicast-extensions.git
synced 2024-05-11 05:55:07 +00:00
176 lines
5.6 KiB
Bash
Executable File
176 lines
5.6 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
# Self-tests for IPv4 address extensions: the kernel's ability to accept
|
|
# certain traditionally unused or unallocated IPv4 addresses. Currently
|
|
# the kernel accepts addresses in 0/8 and 240/4 as valid. These tests
|
|
# check this for interface assignment, ping, TCP, and forwarding. Must
|
|
# be run as root (to manipulate network namespaces and virtual interfaces).
|
|
|
|
# This is work in progress toward an eventual submission to the Linux
|
|
# selftests (in linux/tools/testing/selftests).
|
|
|
|
# TODO: This needs a nettest binary, from linux/tools/testing/selftests/net;
|
|
# either integrate this with the selftests so this is guaranteed to
|
|
# be available, or use a different dependency for TCP socket testing!
|
|
|
|
# TODO: can we make this faster by having nettest indicate exactly
|
|
# when the listening socket has been bound or something?
|
|
|
|
if [ -x ./nettest ]; then
|
|
NETTEST=./nettest
|
|
elif [ -x /tmp/nettest ]; then
|
|
NETTEST=/tmp/nettest # XXX this is only for testing because
|
|
# we should definitely not run a script
|
|
# with a fixed name from /tmp as root!
|
|
else
|
|
NETTEST=`which nettest`
|
|
fi
|
|
|
|
result=0
|
|
|
|
hide_output(){ exec 3>&1; exec 4>&2; exec >/dev/null; exec 2>/dev/null; }
|
|
show_output(){ exec >&3; exec 2>&4; }
|
|
|
|
show_result(){
|
|
if [ $1 -eq 0 ]; then
|
|
printf "TEST: %-60s [ OK ]\n" "${2}"
|
|
else
|
|
printf "TEST: %-60s [FAIL]\n" "${2}"
|
|
result=1
|
|
fi
|
|
}
|
|
|
|
_do_pingtest(){
|
|
# expects caller to set up foo-ns and bar-ns namespaces
|
|
# and clean them up afterward
|
|
ip netns exec foo-ns ifconfig foo inet $1/$3 || return 1
|
|
ip netns exec bar-ns ifconfig bar inet $2/$3 || return 1
|
|
ip netns exec foo-ns timeout 2 ping -c 1 $2 || return 1
|
|
ip netns exec bar-ns timeout 2 ping -c 1 $1 || return 1
|
|
|
|
# using nettest (for this simple test, it's akin to netcat)
|
|
ip netns exec foo-ns "$NETTEST" -s &
|
|
sleep 0.5
|
|
ip netns exec bar-ns "$NETTEST" -r $1 || return 1
|
|
|
|
ip netns exec bar-ns "$NETTEST" -s &
|
|
sleep 0.5
|
|
ip netns exec foo-ns "$NETTEST" -r $2 || return 1
|
|
|
|
wait
|
|
return 0
|
|
}
|
|
|
|
_do_route_test(){
|
|
# expects caller to set up foo-ns, bar-ns, and router_ns before,
|
|
# and clean them up afterward
|
|
|
|
ip netns exec foo-ns ifconfig foo inet $1/$5 || return 1
|
|
ip netns exec bar-ns ifconfig bar inet $4/$5 || return 1
|
|
ip netns exec router-ns ifconfig foo1 inet $2/$5 || return 1
|
|
ip netns exec router-ns ifconfig bar1 inet $3/$5 || return 1
|
|
echo 1 | ip netns exec router-ns tee /proc/sys/net/ipv4/ip_forward
|
|
ip netns exec foo-ns route add -net default gw $2 || return 1
|
|
ip netns exec bar-ns route add -net default gw $3 || return 1
|
|
ip netns exec foo-ns timeout 2 ping -c 1 $2 || return 1
|
|
ip netns exec foo-ns timeout 2 ping -c 1 $4 || return 1
|
|
ip netns exec bar-ns timeout 2 ping -c 1 $3 || return 1
|
|
ip netns exec bar-ns timeout 2 ping -c 1 $1 || return 1
|
|
|
|
ip netns exec foo-ns "$NETTEST" -s &
|
|
sleep 0.5
|
|
ip netns exec bar-ns "$NETTEST" -r $1 || return 1
|
|
|
|
ip netns exec bar-ns "$NETTEST" -s &
|
|
sleep 0.5
|
|
ip netns exec foo-ns "$NETTEST" -r $4 || return 1
|
|
|
|
wait
|
|
return 0
|
|
}
|
|
|
|
pingtest(){
|
|
hide_output
|
|
ip netns add foo-ns
|
|
ip netns add bar-ns
|
|
ip link add foo netns foo-ns type veth peer name bar netns bar-ns
|
|
|
|
test_result=0
|
|
_do_pingtest "$@" || test_result=1
|
|
|
|
ip netns del foo-ns
|
|
ip netns del bar-ns
|
|
show_output
|
|
|
|
# inverted tests will expect failure instead of success
|
|
[ -n "$expect_failure" ] && test_result=`expr 1 - $test_result`
|
|
|
|
show_result $test_result "$4"
|
|
}
|
|
|
|
|
|
route_test(){
|
|
# [a] <---> [b]-[c] <---> [d] /mask
|
|
test_result=0
|
|
hide_output
|
|
ip netns add foo-ns
|
|
ip netns add bar-ns
|
|
ip netns add router-ns
|
|
ip link add foo netns foo-ns type veth peer name foo1 netns router-ns
|
|
ip link add bar netns bar-ns type veth peer name bar1 netns router-ns
|
|
|
|
test_result=0
|
|
_do_route_test "$@" || test_result=1
|
|
|
|
ip netns del foo-ns
|
|
ip netns del bar-ns
|
|
ip netns del router-ns
|
|
|
|
show_output
|
|
show_result $test_result "$6"
|
|
}
|
|
|
|
# Test support for 240/4
|
|
pingtest 240.1.2.1 240.1.2.4 24 "assign and ping within 240/4 (1 of 2)"
|
|
pingtest 250.100.2.1 250.100.30.4 16 "assign and ping within 240/4 (2 of 2)"
|
|
|
|
# Test support for 0/8
|
|
pingtest 0.1.2.17 0.1.2.23 24 "assign and ping within 0/8 (1 of 2)"
|
|
pingtest 0.77.240.17 0.77.2.23 16 "assign and ping within 0/8 (2 of 2)"
|
|
|
|
# It should still not be possible to use 0.0.0.0 or 255.255.255.255
|
|
# as a unicast address. Thus, these tests expect failure.
|
|
expect_failure=true
|
|
pingtest 0.0.1.5 0.0.0.0 16 "assigning 0.0.0.0 is forbidden"
|
|
pingtest 255.255.255.1 255.255.255.255 16 "assigning 255.255.255.255 is forbidden"
|
|
unset expect_failure
|
|
|
|
# But, even 255.255/16 is OK!
|
|
pingtest 255.255.3.1 255.255.50.77 16 "assign and ping inside 255.255/16"
|
|
|
|
# Or 255.255.255/24
|
|
pingtest 255.255.255.1 255.255.255.254 24 "assign and ping inside 255.255.255/24"
|
|
|
|
# Test support for zeroth host
|
|
# pingtest 5.10.15.20 5.10.15.0 24 "assign and ping zeroth host"
|
|
|
|
# Test support for not having all of 127 be loopback
|
|
# pingtest 127.99.4.5 127.99.4.6 16 "assign and ping inside 127/8"
|
|
|
|
# Routing between different networks
|
|
route_test 240.5.6.7 240.5.6.1 255.1.2.1 255.1.2.3 24 "route between 240.5.6/24 and 255.1.2/24"
|
|
route_test 0.200.6.7 0.200.38.1 245.99.101.1 245.99.200.111 16 "route between 0.200/16 and 245.99/16"
|
|
|
|
# Routing using zeroth host as a gateway/endpoint (also requires zeroth host
|
|
# patch)!
|
|
# route_test 192.168.42.1 192.168.42.0 9.8.7.6 9.8.7.0 24 "route using zeroth host"
|
|
|
|
# TODO: It's slightly harder to have tests for TCP, not just ICMP, because
|
|
# the ping responder is in the kernel, while answering TCP via netcat
|
|
# requires a subprocess or subshell. However this could certainly be
|
|
# done with a subshell, like { echo hello | timeout 2 nc -l 12345; } &
|
|
# or similar.
|
|
|
|
exit ${result}
|