Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftest: net: add some traceroute tests

Added the following traceroute tests.

IPV6:
Verify that in this scenario

------------------------ N2
| |
------ ------ N3 ----
| R1 | | R2 |------|H2|
------ ------ ----
| |
------------------------ N1
|
----
|H1|
----

where H1's default route goes through R1 and R1's default route goes
through R2 over N2, traceroute6 from H1 to H2 reports R2's address
on N2 and not N1.

IPV4:
Verify that traceroute from H1 to H2 shows 1.0.1.1 in this scenario

1.0.3.1/24
---- 1.0.1.3/24 1.0.1.1/24 ---- 1.0.2.1/24 1.0.2.4/24 ----
|H1|--------------------------|R1|--------------------------|H2|
---- N1 ---- N2 ----

where net.ipv4.icmp_errors_use_inbound_ifaddr is set on R1 and
1.0.3.1/24 and 1.0.1.1/24 are respectively R1's primary and secondary
address on N1.

v2: fixed some typos, and have bridge in R1 instead of R2 in IPV6 test.

Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Francesco Ruggeri and committed by
David S. Miller
3c28d99f 3edcc568

+323 -1
+1 -1
tools/testing/selftests/net/Makefile
··· 10 10 TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh 11 11 TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh 12 12 TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh 13 - TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh 13 + TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh traceroute.sh 14 14 TEST_PROGS_EXTENDED := in_netns.sh 15 15 TEST_GEN_FILES = socket nettest 16 16 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
+322
tools/testing/selftests/net/traceroute.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Run traceroute/traceroute6 tests 5 + # 6 + 7 + VERBOSE=0 8 + PAUSE_ON_FAIL=no 9 + 10 + ################################################################################ 11 + # 12 + log_test() 13 + { 14 + local rc=$1 15 + local expected=$2 16 + local msg="$3" 17 + 18 + if [ ${rc} -eq ${expected} ]; then 19 + printf "TEST: %-60s [ OK ]\n" "${msg}" 20 + nsuccess=$((nsuccess+1)) 21 + else 22 + ret=1 23 + nfail=$((nfail+1)) 24 + printf "TEST: %-60s [FAIL]\n" "${msg}" 25 + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 26 + echo 27 + echo "hit enter to continue, 'q' to quit" 28 + read a 29 + [ "$a" = "q" ] && exit 1 30 + fi 31 + fi 32 + } 33 + 34 + run_cmd() 35 + { 36 + local ns 37 + local cmd 38 + local out 39 + local rc 40 + 41 + ns="$1" 42 + shift 43 + cmd="$*" 44 + 45 + if [ "$VERBOSE" = "1" ]; then 46 + printf " COMMAND: $cmd\n" 47 + fi 48 + 49 + out=$(eval ip netns exec ${ns} ${cmd} 2>&1) 50 + rc=$? 51 + if [ "$VERBOSE" = "1" -a -n "$out" ]; then 52 + echo " $out" 53 + fi 54 + 55 + [ "$VERBOSE" = "1" ] && echo 56 + 57 + return $rc 58 + } 59 + 60 + ################################################################################ 61 + # create namespaces and interconnects 62 + 63 + create_ns() 64 + { 65 + local ns=$1 66 + local addr=$2 67 + local addr6=$3 68 + 69 + [ -z "${addr}" ] && addr="-" 70 + [ -z "${addr6}" ] && addr6="-" 71 + 72 + ip netns add ${ns} 73 + 74 + ip netns exec ${ns} ip link set lo up 75 + if [ "${addr}" != "-" ]; then 76 + ip netns exec ${ns} ip addr add dev lo ${addr} 77 + fi 78 + if [ "${addr6}" != "-" ]; then 79 + ip netns exec ${ns} ip -6 addr add dev lo ${addr6} 80 + fi 81 + 82 + ip netns exec ${ns} ip ro add unreachable default metric 8192 83 + ip netns exec ${ns} ip -6 ro add unreachable default metric 8192 84 + 85 + ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1 86 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 87 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1 88 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1 89 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0 90 + } 91 + 92 + # create veth pair to connect namespaces and apply addresses. 93 + connect_ns() 94 + { 95 + local ns1=$1 96 + local ns1_dev=$2 97 + local ns1_addr=$3 98 + local ns1_addr6=$4 99 + local ns2=$5 100 + local ns2_dev=$6 101 + local ns2_addr=$7 102 + local ns2_addr6=$8 103 + 104 + ip netns exec ${ns1} ip li add ${ns1_dev} type veth peer name tmp 105 + ip netns exec ${ns1} ip li set ${ns1_dev} up 106 + ip netns exec ${ns1} ip li set tmp netns ${ns2} name ${ns2_dev} 107 + ip netns exec ${ns2} ip li set ${ns2_dev} up 108 + 109 + if [ "${ns1_addr}" != "-" ]; then 110 + ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr} 111 + fi 112 + 113 + if [ "${ns2_addr}" != "-" ]; then 114 + ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr} 115 + fi 116 + 117 + if [ "${ns1_addr6}" != "-" ]; then 118 + ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr6} 119 + fi 120 + 121 + if [ "${ns2_addr6}" != "-" ]; then 122 + ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr6} 123 + fi 124 + } 125 + 126 + ################################################################################ 127 + # traceroute6 test 128 + # 129 + # Verify that in this scenario 130 + # 131 + # ------------------------ N2 132 + # | | 133 + # ------ ------ N3 ---- 134 + # | R1 | | R2 |------|H2| 135 + # ------ ------ ---- 136 + # | | 137 + # ------------------------ N1 138 + # | 139 + # ---- 140 + # |H1| 141 + # ---- 142 + # 143 + # where H1's default route goes through R1 and R1's default route goes 144 + # through R2 over N2, traceroute6 from H1 to H2 reports R2's address 145 + # on N2 and not N1. 146 + # 147 + # Addresses are assigned as follows: 148 + # 149 + # N1: 2000:101::/64 150 + # N2: 2000:102::/64 151 + # N3: 2000:103::/64 152 + # 153 + # R1's host part of address: 1 154 + # R2's host part of address: 2 155 + # H1's host part of address: 3 156 + # H2's host part of address: 4 157 + # 158 + # For example: 159 + # the IPv6 address of R1's interface on N2 is 2000:102::1/64 160 + 161 + cleanup_traceroute6() 162 + { 163 + local ns 164 + 165 + for ns in host-1 host-2 router-1 router-2 166 + do 167 + ip netns del ${ns} 2>/dev/null 168 + done 169 + } 170 + 171 + setup_traceroute6() 172 + { 173 + brdev=br0 174 + 175 + # start clean 176 + cleanup_traceroute6 177 + 178 + set -e 179 + create_ns host-1 180 + create_ns host-2 181 + create_ns router-1 182 + create_ns router-2 183 + 184 + # Setup N3 185 + connect_ns router-2 eth3 - 2000:103::2/64 host-2 eth3 - 2000:103::4/64 186 + ip netns exec host-2 ip route add default via 2000:103::2 187 + 188 + # Setup N2 189 + connect_ns router-1 eth2 - 2000:102::1/64 router-2 eth2 - 2000:102::2/64 190 + ip netns exec router-1 ip route add default via 2000:102::2 191 + 192 + # Setup N1. host-1 and router-2 connect to a bridge in router-1. 193 + ip netns exec router-1 ip link add name ${brdev} type bridge 194 + ip netns exec router-1 ip link set ${brdev} up 195 + ip netns exec router-1 ip addr add 2000:101::1/64 dev ${brdev} 196 + 197 + connect_ns host-1 eth0 - 2000:101::3/64 router-1 eth0 - - 198 + ip netns exec router-1 ip link set dev eth0 master ${brdev} 199 + ip netns exec host-1 ip route add default via 2000:101::1 200 + 201 + connect_ns router-2 eth1 - 2000:101::2/64 router-1 eth1 - - 202 + ip netns exec router-1 ip link set dev eth1 master ${brdev} 203 + 204 + # Prime the network 205 + ip netns exec host-1 ping6 -c5 2000:103::4 >/dev/null 2>&1 206 + 207 + set +e 208 + } 209 + 210 + run_traceroute6() 211 + { 212 + if [ ! -x "$(command -v traceroute6)" ]; then 213 + echo "SKIP: Could not run IPV6 test without traceroute6" 214 + return 215 + fi 216 + 217 + setup_traceroute6 218 + 219 + # traceroute6 host-2 from host-1 (expects 2000:102::2) 220 + run_cmd host-1 "traceroute6 2000:103::4 | grep -q 2000:102::2" 221 + log_test $? 0 "IPV6 traceroute" 222 + 223 + cleanup_traceroute6 224 + } 225 + 226 + ################################################################################ 227 + # traceroute test 228 + # 229 + # Verify that traceroute from H1 to H2 shows 1.0.1.1 in this scenario 230 + # 231 + # 1.0.3.1/24 232 + # ---- 1.0.1.3/24 1.0.1.1/24 ---- 1.0.2.1/24 1.0.2.4/24 ---- 233 + # |H1|--------------------------|R1|--------------------------|H2| 234 + # ---- N1 ---- N2 ---- 235 + # 236 + # where net.ipv4.icmp_errors_use_inbound_ifaddr is set on R1 and 237 + # 1.0.3.1/24 and 1.0.1.1/24 are respectively R1's primary and secondary 238 + # address on N1. 239 + # 240 + 241 + cleanup_traceroute() 242 + { 243 + local ns 244 + 245 + for ns in host-1 host-2 router 246 + do 247 + ip netns del ${ns} 2>/dev/null 248 + done 249 + } 250 + 251 + setup_traceroute() 252 + { 253 + # start clean 254 + cleanup_traceroute 255 + 256 + set -e 257 + create_ns host-1 258 + create_ns host-2 259 + create_ns router 260 + 261 + connect_ns host-1 eth0 1.0.1.3/24 - \ 262 + router eth1 1.0.3.1/24 - 263 + ip netns exec host-1 ip route add default via 1.0.1.1 264 + 265 + ip netns exec router ip addr add 1.0.1.1/24 dev eth1 266 + ip netns exec router sysctl -qw \ 267 + net.ipv4.icmp_errors_use_inbound_ifaddr=1 268 + 269 + connect_ns host-2 eth0 1.0.2.4/24 - \ 270 + router eth2 1.0.2.1/24 - 271 + ip netns exec host-2 ip route add default via 1.0.2.1 272 + 273 + # Prime the network 274 + ip netns exec host-1 ping -c5 1.0.2.4 >/dev/null 2>&1 275 + 276 + set +e 277 + } 278 + 279 + run_traceroute() 280 + { 281 + if [ ! -x "$(command -v traceroute)" ]; then 282 + echo "SKIP: Could not run IPV4 test without traceroute" 283 + return 284 + fi 285 + 286 + setup_traceroute 287 + 288 + # traceroute host-2 from host-1 (expects 1.0.1.1). Takes a while. 289 + run_cmd host-1 "traceroute 1.0.2.4 | grep -q 1.0.1.1" 290 + log_test $? 0 "IPV4 traceroute" 291 + 292 + cleanup_traceroute 293 + } 294 + 295 + ################################################################################ 296 + # Run tests 297 + 298 + run_tests() 299 + { 300 + run_traceroute6 301 + run_traceroute 302 + } 303 + 304 + ################################################################################ 305 + # main 306 + 307 + declare -i nfail=0 308 + declare -i nsuccess=0 309 + 310 + while getopts :pv o 311 + do 312 + case $o in 313 + p) PAUSE_ON_FAIL=yes;; 314 + v) VERBOSE=$(($VERBOSE + 1));; 315 + *) exit 1;; 316 + esac 317 + done 318 + 319 + run_tests 320 + 321 + printf "\nTests passed: %3d\n" ${nsuccess} 322 + printf "Tests failed: %3d\n" ${nfail}