Commit dca56cc8 authored by Florian Westphal's avatar Florian Westphal Committed by Jakub Kicinski
Browse files

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: 78a58836 ("selftests: netfilter: add conntrack clash resolution test case")
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Link: https://patch.msgid.link/20250721223652.6956-1-fw@strlen.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 71c33df4
Loading
Loading
Loading
Loading
+22 −23
Original line number Diff line number Diff line
@@ -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