0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 PAUSE_ON_FAIL=no
0016 VERBOSE=0
0017
0018 which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
0019
0020
0021
0022
0023 log_test()
0024 {
0025 local rc=$1
0026 local expected=$2
0027 local msg="$3"
0028
0029 if [ ${rc} -eq ${expected} ]; then
0030 printf "TEST: %-60s [ OK ]\n" "${msg}"
0031 nsuccess=$((nsuccess+1))
0032 else
0033 ret=1
0034 nfail=$((nfail+1))
0035 printf "TEST: %-60s [FAIL]\n" "${msg}"
0036 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
0037 echo
0038 echo "hit enter to continue, 'q' to quit"
0039 read a
0040 [ "$a" = "q" ] && exit 1
0041 fi
0042 fi
0043
0044 [ "$VERBOSE" = "1" ] && echo
0045 }
0046
0047 run_cmd()
0048 {
0049 local cmd="$*"
0050 local out
0051 local rc
0052
0053 if [ "$VERBOSE" = "1" ]; then
0054 echo "COMMAND: $cmd"
0055 fi
0056
0057 out=$(eval $cmd 2>&1)
0058 rc=$?
0059 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
0060 echo "$out"
0061 fi
0062
0063 [ "$VERBOSE" = "1" ] && echo
0064
0065 return $rc
0066 }
0067
0068
0069
0070
0071 create_ns()
0072 {
0073 local ns=${1}
0074
0075 ip netns del ${ns} 2>/dev/null
0076
0077 ip netns add ${ns}
0078 ip -netns ${ns} addr add 127.0.0.1/8 dev lo
0079 ip -netns ${ns} link set lo up
0080
0081 ip netns exec ${ns} sysctl -q -w net.ipv6.conf.all.keep_addr_on_down=1
0082 case ${ns} in
0083 h*)
0084 ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=0
0085 ;;
0086 r*)
0087 ip netns exec $ns sysctl -q -w net.ipv4.ip_forward=1
0088 ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=1
0089 ;;
0090 esac
0091 }
0092
0093 setup()
0094 {
0095 local ns
0096 local i
0097
0098
0099
0100 for ns in h0 r1 h1 h2 h3
0101 do
0102 create_ns ${ns}
0103 done
0104
0105
0106
0107
0108
0109 for i in 0 1 2 3
0110 do
0111 ip -netns h${i} li add eth0 type veth peer name r1h${i}
0112 ip -netns h${i} li set eth0 up
0113 ip -netns h${i} li set r1h${i} netns r1 name eth${i} up
0114
0115 ip -netns h${i} addr add dev eth0 172.16.10${i}.1/24
0116 ip -netns h${i} -6 addr add dev eth0 2001:db8:10${i}::1/64
0117 ip -netns r1 addr add dev eth${i} 172.16.10${i}.254/24
0118 ip -netns r1 -6 addr add dev eth${i} 2001:db8:10${i}::64/64
0119 done
0120
0121 ip -netns h0 nexthop add id 4 via 172.16.100.254 dev eth0
0122 ip -netns h0 nexthop add id 6 via 2001:db8:100::64 dev eth0
0123
0124
0125 for i in 1 2 3
0126 do
0127 ip -netns h0 ro add 172.16.10${i}.0/24 nhid 4
0128 ip -netns h${i} ro add 172.16.100.0/24 via 172.16.10${i}.254
0129
0130 ip -netns h0 -6 ro add 2001:db8:10${i}::/64 nhid 6
0131 ip -netns h${i} -6 ro add 2001:db8:100::/64 via 2001:db8:10${i}::64
0132 done
0133
0134 if [ "$VERBOSE" = "1" ]; then
0135 echo
0136 echo "host 1 config"
0137 ip -netns h0 li sh
0138 ip -netns h0 ro sh
0139 ip -netns h0 -6 ro sh
0140 fi
0141
0142
0143 }
0144
0145 cleanup()
0146 {
0147 for n in h0 r1 h1 h2 h3
0148 do
0149 ip netns del ${n} 2>/dev/null
0150 done
0151 }
0152
0153 change_mtu()
0154 {
0155 local hostid=$1
0156 local mtu=$2
0157
0158 run_cmd ip -netns h${hostid} li set eth0 mtu ${mtu}
0159 run_cmd ip -netns r1 li set eth${hostid} mtu ${mtu}
0160 }
0161
0162
0163
0164
0165 validate_v4_exception()
0166 {
0167 local i=$1
0168 local mtu=$2
0169 local ping_sz=$3
0170 local dst="172.16.10${i}.1"
0171 local h0=172.16.100.1
0172 local r1=172.16.100.254
0173 local rc
0174
0175 if [ ${ping_sz} != "0" ]; then
0176 run_cmd ip netns exec h0 ping -s ${ping_sz} -c5 -w5 ${dst}
0177 fi
0178
0179 if [ "$VERBOSE" = "1" ]; then
0180 echo "Route get"
0181 ip -netns h0 ro get ${dst}
0182 echo "Searching for:"
0183 echo " cache .* mtu ${mtu}"
0184 echo
0185 fi
0186
0187 ip -netns h0 ro get ${dst} | \
0188 grep -q "cache .* mtu ${mtu}"
0189 rc=$?
0190
0191 log_test $rc 0 "IPv4: host 0 to host ${i}, mtu ${mtu}"
0192 }
0193
0194 validate_v6_exception()
0195 {
0196 local i=$1
0197 local mtu=$2
0198 local ping_sz=$3
0199 local dst="2001:db8:10${i}::1"
0200 local h0=2001:db8:100::1
0201 local r1=2001:db8:100::64
0202 local rc
0203
0204 if [ ${ping_sz} != "0" ]; then
0205 run_cmd ip netns exec h0 ${ping6} -s ${ping_sz} -c5 -w5 ${dst}
0206 fi
0207
0208 if [ "$VERBOSE" = "1" ]; then
0209 echo "Route get"
0210 ip -netns h0 -6 ro get ${dst}
0211 echo "Searching for:"
0212 echo " ${dst} from :: via ${r1} dev eth0 src ${h0} .* mtu ${mtu}"
0213 echo
0214 fi
0215
0216 ip -netns h0 -6 ro get ${dst} | \
0217 grep -q "${dst} from :: via ${r1} dev eth0 src ${h0} .* mtu ${mtu}"
0218 rc=$?
0219
0220 log_test $rc 0 "IPv6: host 0 to host ${i}, mtu ${mtu}"
0221 }
0222
0223
0224
0225
0226 while getopts :pv o
0227 do
0228 case $o in
0229 p) PAUSE_ON_FAIL=yes;;
0230 v) VERBOSE=1;;
0231 esac
0232 done
0233
0234 cleanup
0235 setup
0236 sleep 2
0237
0238 cpus=$(cat /sys/devices/system/cpu/online)
0239 cpus="$(seq ${cpus/-/ })"
0240 ret=0
0241 for i in 1 2 3
0242 do
0243
0244 for c in ${cpus}; do
0245 run_cmd taskset -c ${c} ip netns exec h0 ping -c1 -w1 172.16.10${i}.1
0246 [ $? -ne 0 ] && printf "\nERROR: ping to h${i} failed\n" && ret=1
0247
0248 run_cmd taskset -c ${c} ip netns exec h0 ${ping6} -c1 -w1 2001:db8:10${i}::1
0249 [ $? -ne 0 ] && printf "\nERROR: ping6 to h${i} failed\n" && ret=1
0250
0251 [ $ret -ne 0 ] && break
0252 done
0253 [ $ret -ne 0 ] && break
0254 done
0255
0256 if [ $ret -eq 0 ]; then
0257
0258 change_mtu 1 1300
0259 validate_v4_exception 1 1300 1350
0260 validate_v6_exception 1 1300 1350
0261 echo
0262
0263 change_mtu 2 1350
0264 validate_v4_exception 2 1350 1400
0265 validate_v6_exception 2 1350 1400
0266 echo
0267
0268 change_mtu 3 1400
0269 validate_v4_exception 3 1400 1450
0270 validate_v6_exception 3 1400 1450
0271 echo
0272
0273 validate_v4_exception 1 1300 0
0274 validate_v6_exception 1 1300 0
0275 echo
0276
0277 validate_v4_exception 2 1350 0
0278 validate_v6_exception 2 1350 0
0279 echo
0280
0281 validate_v4_exception 3 1400 0
0282 validate_v6_exception 3 1400 0
0283
0284
0285 ip -netns h0 ro del 172.16.102.0/24 nhid 4
0286 ip -netns h0 -6 ro del 2001:db8:102::/64 nhid 6
0287
0288 ip -netns h0 nexthop del id 4
0289 ip -netns h0 nexthop del id 6
0290 fi
0291
0292 cleanup