selftests: netfilter: tone-down conntrack clash test

The test is supposed to observe that the 'clash_resolve' stat counter
incremented (i.e., the code path was covered).
This check was incorrect, 'conntrack -S' needs to be called in the
revevant namespace, not the initial netns.

The clash resolution logic in conntrack is only exercised when multiple
packets with the same udp quadruple race. Depending on kernel config,
number of CPUs, scheduling policy etc.  this might not trigger even
after several retries.  Thus the script eventually returns SKIP if the
retry count is exceeded.

The udpclash tool with also exit with a failure if it did not observe
the expected number of replies.

In the script, make a note of this but do not fail anymore, just check if
the clash resolution logic triggered after all.

Remove the 'single-core' test: while unlikely, with preemptible kernel it
should be possible to also trigger clash resolution logic.

With this change the test will either SKIP or pass.

Hard error could be restored later once its clear whats going on, so
also dump 'conntrack -S' when some packets went missing to see if
conntrack dropped them on insert.

Fixes: 78a5883635 ("selftests: netfilter: add conntrack clash resolution test case")
Signed-off-by: Florian Westphal <fw@strlen.de>
Link: https://patch.msgid.link/20250721223652.6956-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Florian Westphal 2025-07-22 00:36:49 +02:00 committed by Jakub Kicinski
parent 71c33df471
commit dca56cc8b5

View File

@ -93,32 +93,28 @@ ping_test()
run_one_clash_test()
{
local ns="$1"
local daddr="$2"
local dport="$3"
local ctns="$2"
local daddr="$3"
local dport="$4"
local entries
local cre
if ! ip netns exec "$ns" ./udpclash $daddr $dport;then
echo "FAIL: did not receive expected number of replies for $daddr:$dport"
ret=1
return 1
echo "INFO: did not receive expected number of replies for $daddr:$dport"
ip netns exec "$ctns" conntrack -S
# don't fail: check if clash resolution triggered after all.
fi
entries=$(conntrack -S | wc -l)
cre=$(conntrack -S | grep -v "clash_resolve=0" | wc -l)
entries=$(ip netns exec "$ctns" conntrack -S | wc -l)
cre=$(ip netns exec "$ctns" conntrack -S | grep "clash_resolve=0" | wc -l)
if [ "$cre" -ne "$entries" ];then
clash_resolution_active=1
return 0
fi
# 1 cpu -> parallel insertion impossible
if [ "$entries" -eq 1 ]; then
return 0
fi
# not a failure: clash resolution logic did not trigger, but all replies
# were received. With right timing, xmit completed sequentially and
# not a failure: clash resolution logic did not trigger.
# With right timing, xmit completed sequentially and
# no parallel insertion occurs.
return $ksft_skip
}
@ -126,20 +122,23 @@ run_one_clash_test()
run_clash_test()
{
local ns="$1"
local daddr="$2"
local dport="$3"
local ctns="$2"
local daddr="$3"
local dport="$4"
local softerr=0
for i in $(seq 1 10);do
run_one_clash_test "$ns" "$daddr" "$dport"
run_one_clash_test "$ns" "$ctns" "$daddr" "$dport"
local rv=$?
if [ $rv -eq 0 ];then
echo "PASS: clash resolution test for $daddr:$dport on attempt $i"
return 0
elif [ $rv -eq 1 ];then
echo "FAIL: clash resolution test for $daddr:$dport on attempt $i"
return 1
elif [ $rv -eq $ksft_skip ]; then
softerr=1
fi
done
[ $softerr -eq 1 ] && echo "SKIP: clash resolution for $daddr:$dport did not trigger"
}
ip link add veth0 netns "$nsclient1" type veth peer name veth0 netns "$nsrouter"
@ -161,11 +160,11 @@ spawn_servers "$nsclient2"
# exercise clash resolution with nat:
# nsrouter is supposed to dnat to 10.0.2.1:900{0,1,2,3}.
run_clash_test "$nsclient1" 10.0.1.99 "$dport"
run_clash_test "$nsclient1" "$nsrouter" 10.0.1.99 "$dport"
# exercise clash resolution without nat.
load_simple_ruleset "$nsclient2"
run_clash_test "$nsclient2" 127.0.0.1 9001
run_clash_test "$nsclient2" "$nsclient2" 127.0.0.1 9001
if [ $clash_resolution_active -eq 0 ];then
[ "$ret" -eq 0 ] && ret=$ksft_skip