icmp.sh backgrounds ping and then starts tcpdump, with no synchronization
between the two. If tcpdump is not capturing yet by the time the ICMP
unreachable replies come back, the test fails even though the kernel
behaved correctly:
FAIL - got ICMP response from , should be 192.0.0.8
The empty address is misleading: it means the capture matched nothing
before its 10s timeout, not that the reply had a wrong source address.
NS1's Icmp InDestUnreachs counter still increments across such a failure,
so the replies were generated and did reach NS1. Ping sends several probes
over its 3s deadline, so losing every one of them takes a multi-second
stall in tcpdump startup, which does happen on loaded CI hosts [1].
Fix it with the idiom already used by broadcast_ether_dst.sh and
macvlan_mcast_shared_mac.sh: start tcpdump first and wait for its
"listening" banner via slowwait() before sending traffic.
Fixes: 7e9838b7915e ("selftests/net: Add icmp.sh for testing ICMP dummy address
responses")
Link:
https://openqa.opensuse.org/tests/5907626/logfile?filename=icmp_sh.tap.txt#line-2
[1]
Signed-off-by: Ricardo B. Marlière (SUSE) <[email protected]>
---
tools/testing/selftests/net/icmp.sh | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/net/icmp.sh
b/tools/testing/selftests/net/icmp.sh
index 824cb0e35eff..593d5f3abcae 100755
--- a/tools/testing/selftests/net/icmp.sh
+++ b/tools/testing/selftests/net/icmp.sh
@@ -28,10 +28,11 @@ RT2=172.16.0.0/24
H2_IP6=2001:db8:1::2
TMPFILE=$(mktemp)
+TCPDUMP_ERR=$(mktemp)
cleanup()
{
- rm -f "$TMPFILE"
+ rm -f "$TMPFILE" "$TCPDUMP_ERR"
cleanup_ns $NS1 $NS2
}
@@ -53,11 +54,21 @@ ip -netns $NS2 route add $RT2 via inet6 $H1_IP6
# Make sure ns2 will respond with ICMP unreachable
ip netns exec $NS2 sysctl -qw net.ipv4.icmp_ratelimit=0 net.ipv4.ip_forward=1
-# Run the test - a ping runs in the background, and we capture ICMP responses
-# with tcpdump; -c 1 means it should exit on the first ping, but add a timeout
-# in case something goes wrong
+# Run the test - start tcpdump and wait for it to be capturing before
+# sending any traffic. -c 1 means it should exit on the first ping, but add
+# a timeout in case something goes wrong
+ip netns exec $NS1 timeout 10 tcpdump -tpni veth0 -c 1 \
+ 'icmp and icmp[icmptype] != icmp-echo' > $TMPFILE 2>$TCPDUMP_ERR &
+TCPDUMP_PID=$!
+if ! slowwait 3 grep -qs "listening" "$TCPDUMP_ERR"; then
+ echo "FAIL - tcpdump did not start listening"
+ cat "$TCPDUMP_ERR"
+ exit 1
+fi
+
ip netns exec $NS1 ping -w 3 -i 0.5 $PINGADDR >/dev/null &
-ip netns exec $NS1 timeout 10 tcpdump -tpni veth0 -c 1 'icmp and
icmp[icmptype] != icmp-echo' > $TMPFILE 2>/dev/null
+
+wait $TCPDUMP_PID
# Parse response and check for dummy address
# tcpdump output looks like:
---
base-commit: 786262be6048deab760f68c8acc2c85607165894
change-id: 20260901-selftests-net-icmp_race-6268d886249e
Best regards,
--
Ricardo B. Marlière (SUSE) <[email protected]>