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

selftest: Fixes for icmp_redirect test

I was really surprised that the IPv6 mtu exception followed by redirect
test was passing as nothing about the code suggests it should. The problem
is actually with the logic in the test script.

Fix the test cases as follows:
1. add debug function to dump the initial and redirect gateway addresses
for ipv6. This is shown only in verbose mode. It helps verify the
output of 'route get'.

2. fix the check_exception logic for the reset case to make sure that
for IPv4 neither mtu nor redirect appears in the 'route get' output.
For IPv6, make sure mtu is not present and the gateway is the initial
R1 lladdr.

3. fix the reset logic by using a function to delete the routes added by
initial_route_*. This format works better for the nexthop version of
the tests.

While improving the test cases, go ahead and ensure that forwarding is
disabled since IPv6 redirect requires it.

Also, runs with kernel debugging enabled sometimes show a failure with
one of the ipv4 tests, so spread the pings over longer time interval.

The end result is that 2 tests now show failures:

TEST: IPv6: mtu exception plus redirect [FAIL]

and the VRF version.

This is a bug in the IPv6 logic that will need to be fixed
separately. Redirect followed by MTU works because __ip6_rt_update_pmtu
hits the 'if (!rt6_cache_allowed_for_pmtu(rt6))' path and updates the
mtu on the exception rt6_info.

MTU followed by redirect does not have this logic. rt6_do_redirect
creates a new exception and then rt6_insert_exception removes the old
one which has the MTU exception.

Fixes: ec8105352869 ("selftests: Add redirect tests")
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David Ahern and committed by
David S. Miller
99513cfa df801522

+38 -8
+38 -8
tools/testing/selftests/net/icmp_redirect.sh
··· 80 80 fi 81 81 } 82 82 83 + log_debug() 84 + { 85 + if [ "$VERBOSE" = "1" ]; then 86 + echo "$*" 87 + fi 88 + } 89 + 83 90 run_cmd() 84 91 { 85 92 local cmd="$*" ··· 174 167 175 168 case "${ns}" in 176 169 h[12]) ip netns exec $ns sysctl -q -w net.ipv4.conf.all.accept_redirects=1 170 + ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=0 177 171 ip netns exec $ns sysctl -q -w net.ipv6.conf.all.accept_redirects=1 178 172 ip netns exec $ns sysctl -q -w net.ipv6.conf.all.keep_addr_on_down=1 179 173 ;; ··· 258 250 echo "Error: Failed to get link-local address of r1's eth0" 259 251 exit 1 260 252 fi 253 + log_debug "initial gateway is R1's lladdr = ${R1_LLADDR}" 261 254 262 255 R2_LLADDR=$(get_linklocal r2 eth0) 263 256 if [ $? -ne 0 ]; then 264 257 echo "Error: Failed to get link-local address of r2's eth0" 265 258 exit 1 266 259 fi 260 + log_debug "initial gateway is R2's lladdr = ${R2_LLADDR}" 267 261 } 268 262 269 263 change_h2_mtu() ··· 299 289 ip -netns h1 ro get ${H1_VRF_ARG} ${H2_N2_IP} | \ 300 290 grep -q "cache expires [0-9]*sec${mtu}" 301 291 else 292 + # want to verify that neither mtu nor redirected appears in 293 + # the route get output. The -v will wipe out the cache line 294 + # if either are set so the last grep -q will not find a match 302 295 ip -netns h1 ro get ${H1_VRF_ARG} ${H2_N2_IP} | \ 303 - grep -q "cache" 296 + grep -E -v 'mtu|redirected' | grep -q "cache" 304 297 fi 305 298 log_test $? 0 "IPv4: ${desc}" 306 299 307 300 if [ "$with_redirect" = "yes" ]; then 308 - ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | grep -q "${H2_N2_IP6} from :: via ${R2_LLADDR} dev br0.*${mtu}" 301 + ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | \ 302 + grep -q "${H2_N2_IP6} from :: via ${R2_LLADDR} dev br0.*${mtu}" 303 + elif [ -n "${mtu}" ]; then 304 + ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | \ 305 + grep -q "${mtu}" 309 306 else 310 - ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | grep -q "${mtu}" 307 + # IPv6 is a bit harder. First strip out the match if it 308 + # contains an mtu exception and then look for the first 309 + # gateway - R1's lladdr 310 + ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | \ 311 + grep -v "mtu" | grep -q "${R1_LLADDR}" 311 312 fi 312 313 log_test $? 0 "IPv6: ${desc}" 313 314 } ··· 327 306 { 328 307 local sz=$1 329 308 330 - run_cmd ip netns exec h1 ping -q -M want -i 0.2 -c 10 -w 2 -s ${sz} ${H1_PING_ARG} ${H2_N2_IP} 331 - run_cmd ip netns exec h1 ${ping6} -q -M want -i 0.2 -c 10 -w 2 -s ${sz} ${H1_PING_ARG} ${H2_N2_IP6} 309 + run_cmd ip netns exec h1 ping -q -M want -i 0.5 -c 10 -w 2 -s ${sz} ${H1_PING_ARG} ${H2_N2_IP} 310 + run_cmd ip netns exec h1 ${ping6} -q -M want -i 0.5 -c 10 -w 2 -s ${sz} ${H1_PING_ARG} ${H2_N2_IP6} 332 311 } 333 312 334 313 replace_route_legacy() ··· 336 315 # r1 to h2 via r2 and eth0 337 316 run_cmd ip -netns r1 ro replace ${H2_N2} via ${R2_N1_IP} dev eth0 338 317 run_cmd ip -netns r1 -6 ro replace ${H2_N2_6} via ${R2_LLADDR} dev eth0 318 + } 319 + 320 + reset_route_legacy() 321 + { 322 + run_cmd ip -netns r1 ro del ${H2_N2} 323 + run_cmd ip -netns r1 -6 ro del ${H2_N2_6} 324 + 325 + run_cmd ip -netns h1 ro del ${H1_VRF_ARG} ${H2_N2} 326 + run_cmd ip -netns h1 -6 ro del ${H1_VRF_ARG} ${H2_N2_6} 327 + 328 + initial_route_legacy 339 329 } 340 330 341 331 initial_route_legacy() ··· 405 373 406 374 # remove exceptions and restore routing 407 375 change_h2_mtu 1500 408 - ip -netns h1 li set br0 down 409 - ip -netns h1 li set br0 up 410 - eval initial_route_${ttype} 376 + eval reset_route_${ttype} 411 377 412 378 check_connectivity 413 379 if [ $? -ne 0 ]; then