Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # Run traceroute/traceroute6 tests
0005 #
0006 
0007 VERBOSE=0
0008 PAUSE_ON_FAIL=no
0009 
0010 ################################################################################
0011 #
0012 log_test()
0013 {
0014         local rc=$1
0015         local expected=$2
0016         local msg="$3"
0017 
0018         if [ ${rc} -eq ${expected} ]; then
0019                 printf "TEST: %-60s  [ OK ]\n" "${msg}"
0020                 nsuccess=$((nsuccess+1))
0021         else
0022                 ret=1
0023                 nfail=$((nfail+1))
0024                 printf "TEST: %-60s  [FAIL]\n" "${msg}"
0025                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
0026                         echo
0027                         echo "hit enter to continue, 'q' to quit"
0028                         read a
0029                         [ "$a" = "q" ] && exit 1
0030                 fi
0031         fi
0032 }
0033 
0034 run_cmd()
0035 {
0036         local ns
0037         local cmd
0038         local out
0039         local rc
0040 
0041         ns="$1"
0042         shift
0043         cmd="$*"
0044 
0045         if [ "$VERBOSE" = "1" ]; then
0046                 printf "    COMMAND: $cmd\n"
0047         fi
0048 
0049         out=$(eval ip netns exec ${ns} ${cmd} 2>&1)
0050         rc=$?
0051         if [ "$VERBOSE" = "1" -a -n "$out" ]; then
0052                 echo "    $out"
0053         fi
0054 
0055         [ "$VERBOSE" = "1" ] && echo
0056 
0057         return $rc
0058 }
0059 
0060 ################################################################################
0061 # create namespaces and interconnects
0062 
0063 create_ns()
0064 {
0065         local ns=$1
0066         local addr=$2
0067         local addr6=$3
0068 
0069         [ -z "${addr}" ] && addr="-"
0070         [ -z "${addr6}" ] && addr6="-"
0071 
0072         ip netns add ${ns}
0073 
0074         ip netns exec ${ns} ip link set lo up
0075         if [ "${addr}" != "-" ]; then
0076                 ip netns exec ${ns} ip addr add dev lo ${addr}
0077         fi
0078         if [ "${addr6}" != "-" ]; then
0079                 ip netns exec ${ns} ip -6 addr add dev lo ${addr6}
0080         fi
0081 
0082         ip netns exec ${ns} ip ro add unreachable default metric 8192
0083         ip netns exec ${ns} ip -6 ro add unreachable default metric 8192
0084 
0085         ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1
0086         ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
0087         ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
0088         ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1
0089         ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0
0090 }
0091 
0092 # create veth pair to connect namespaces and apply addresses.
0093 connect_ns()
0094 {
0095         local ns1=$1
0096         local ns1_dev=$2
0097         local ns1_addr=$3
0098         local ns1_addr6=$4
0099         local ns2=$5
0100         local ns2_dev=$6
0101         local ns2_addr=$7
0102         local ns2_addr6=$8
0103 
0104         ip netns exec ${ns1} ip li add ${ns1_dev} type veth peer name tmp
0105         ip netns exec ${ns1} ip li set ${ns1_dev} up
0106         ip netns exec ${ns1} ip li set tmp netns ${ns2} name ${ns2_dev}
0107         ip netns exec ${ns2} ip li set ${ns2_dev} up
0108 
0109         if [ "${ns1_addr}" != "-" ]; then
0110                 ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr}
0111         fi
0112 
0113         if [ "${ns2_addr}" != "-" ]; then
0114                 ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr}
0115         fi
0116 
0117         if [ "${ns1_addr6}" != "-" ]; then
0118                 ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr6}
0119         fi
0120 
0121         if [ "${ns2_addr6}" != "-" ]; then
0122                 ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr6}
0123         fi
0124 }
0125 
0126 ################################################################################
0127 # traceroute6 test
0128 #
0129 # Verify that in this scenario
0130 #
0131 #        ------------------------ N2
0132 #         |                    |
0133 #       ------              ------  N3  ----
0134 #       | R1 |              | R2 |------|H2|
0135 #       ------              ------      ----
0136 #         |                    |
0137 #        ------------------------ N1
0138 #                  |
0139 #                 ----
0140 #                 |H1|
0141 #                 ----
0142 #
0143 # where H1's default route goes through R1 and R1's default route goes
0144 # through R2 over N2, traceroute6 from H1 to H2 reports R2's address
0145 # on N2 and not N1.
0146 #
0147 # Addresses are assigned as follows:
0148 #
0149 # N1: 2000:101::/64
0150 # N2: 2000:102::/64
0151 # N3: 2000:103::/64
0152 #
0153 # R1's host part of address: 1
0154 # R2's host part of address: 2
0155 # H1's host part of address: 3
0156 # H2's host part of address: 4
0157 #
0158 # For example:
0159 # the IPv6 address of R1's interface on N2 is 2000:102::1/64
0160 
0161 cleanup_traceroute6()
0162 {
0163         local ns
0164 
0165         for ns in host-1 host-2 router-1 router-2
0166         do
0167                 ip netns del ${ns} 2>/dev/null
0168         done
0169 }
0170 
0171 setup_traceroute6()
0172 {
0173         brdev=br0
0174 
0175         # start clean
0176         cleanup_traceroute6
0177 
0178         set -e
0179         create_ns host-1
0180         create_ns host-2
0181         create_ns router-1
0182         create_ns router-2
0183 
0184         # Setup N3
0185         connect_ns router-2 eth3 - 2000:103::2/64 host-2 eth3 - 2000:103::4/64
0186         ip netns exec host-2 ip route add default via 2000:103::2
0187 
0188         # Setup N2
0189         connect_ns router-1 eth2 - 2000:102::1/64 router-2 eth2 - 2000:102::2/64
0190         ip netns exec router-1 ip route add default via 2000:102::2
0191 
0192         # Setup N1. host-1 and router-2 connect to a bridge in router-1.
0193         ip netns exec router-1 ip link add name ${brdev} type bridge
0194         ip netns exec router-1 ip link set ${brdev} up
0195         ip netns exec router-1 ip addr add 2000:101::1/64 dev ${brdev}
0196 
0197         connect_ns host-1 eth0 - 2000:101::3/64 router-1 eth0 - -
0198         ip netns exec router-1 ip link set dev eth0 master ${brdev}
0199         ip netns exec host-1 ip route add default via 2000:101::1
0200 
0201         connect_ns router-2 eth1 - 2000:101::2/64 router-1 eth1 - -
0202         ip netns exec router-1 ip link set dev eth1 master ${brdev}
0203 
0204         # Prime the network
0205         ip netns exec host-1 ping6 -c5 2000:103::4 >/dev/null 2>&1
0206 
0207         set +e
0208 }
0209 
0210 run_traceroute6()
0211 {
0212         if [ ! -x "$(command -v traceroute6)" ]; then
0213                 echo "SKIP: Could not run IPV6 test without traceroute6"
0214                 return
0215         fi
0216 
0217         setup_traceroute6
0218 
0219         # traceroute6 host-2 from host-1 (expects 2000:102::2)
0220         run_cmd host-1 "traceroute6 2000:103::4 | grep -q 2000:102::2"
0221         log_test $? 0 "IPV6 traceroute"
0222 
0223         cleanup_traceroute6
0224 }
0225 
0226 ################################################################################
0227 # traceroute test
0228 #
0229 # Verify that traceroute from H1 to H2 shows 1.0.1.1 in this scenario
0230 #
0231 #                    1.0.3.1/24
0232 # ---- 1.0.1.3/24    1.0.1.1/24 ---- 1.0.2.1/24    1.0.2.4/24 ----
0233 # |H1|--------------------------|R1|--------------------------|H2|
0234 # ----            N1            ----            N2            ----
0235 #
0236 # where net.ipv4.icmp_errors_use_inbound_ifaddr is set on R1 and
0237 # 1.0.3.1/24 and 1.0.1.1/24 are respectively R1's primary and secondary
0238 # address on N1.
0239 #
0240 
0241 cleanup_traceroute()
0242 {
0243         local ns
0244 
0245         for ns in host-1 host-2 router
0246         do
0247                 ip netns del ${ns} 2>/dev/null
0248         done
0249 }
0250 
0251 setup_traceroute()
0252 {
0253         # start clean
0254         cleanup_traceroute
0255 
0256         set -e
0257         create_ns host-1
0258         create_ns host-2
0259         create_ns router
0260 
0261         connect_ns host-1 eth0 1.0.1.3/24 - \
0262                    router eth1 1.0.3.1/24 -
0263         ip netns exec host-1 ip route add default via 1.0.1.1
0264 
0265         ip netns exec router ip addr add 1.0.1.1/24 dev eth1
0266         ip netns exec router sysctl -qw \
0267                                 net.ipv4.icmp_errors_use_inbound_ifaddr=1
0268 
0269         connect_ns host-2 eth0 1.0.2.4/24 - \
0270                    router eth2 1.0.2.1/24 -
0271         ip netns exec host-2 ip route add default via 1.0.2.1
0272 
0273         # Prime the network
0274         ip netns exec host-1 ping -c5 1.0.2.4 >/dev/null 2>&1
0275 
0276         set +e
0277 }
0278 
0279 run_traceroute()
0280 {
0281         if [ ! -x "$(command -v traceroute)" ]; then
0282                 echo "SKIP: Could not run IPV4 test without traceroute"
0283                 return
0284         fi
0285 
0286         setup_traceroute
0287 
0288         # traceroute host-2 from host-1 (expects 1.0.1.1). Takes a while.
0289         run_cmd host-1 "traceroute 1.0.2.4 | grep -q 1.0.1.1"
0290         log_test $? 0 "IPV4 traceroute"
0291 
0292         cleanup_traceroute
0293 }
0294 
0295 ################################################################################
0296 # Run tests
0297 
0298 run_tests()
0299 {
0300         run_traceroute6
0301         run_traceroute
0302 }
0303 
0304 ################################################################################
0305 # main
0306 
0307 declare -i nfail=0
0308 declare -i nsuccess=0
0309 
0310 while getopts :pv o
0311 do
0312         case $o in
0313                 p) PAUSE_ON_FAIL=yes;;
0314                 v) VERBOSE=$(($VERBOSE + 1));;
0315                 *) exit 1;;
0316         esac
0317 done
0318 
0319 run_tests
0320 
0321 printf "\nTests passed: %3d\n" ${nsuccess}
0322 printf "Tests failed: %3d\n"   ${nfail}