File Index
Files and directories
Sign in
FILE

conntrack_clash.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/netfilter/conntrack_clash.sh BASH
  1#!/bin/bash
  2# SPDX-License-Identifier: GPL-2.0
  3
  4source lib.sh
  5
  6clash_resolution_active=0
  7dport=22111
  8ret=0
  9
 10cleanup()
 11{
 12	# netns cleanup also zaps any remaining socat echo server.
 13	cleanup_all_ns
 14}
 15
 16checktool "nft --version" "run test without nft"
 17checktool "conntrack --version" "run test without conntrack"
 18checktool "socat -h" "run test without socat"
 19
 20trap cleanup EXIT
 21
 22setup_ns nsclient1 nsclient2 nsrouter
 23
 24ip netns exec "$nsrouter" nft -f -<<EOF
 25table ip t {
 26	chain lb {
 27		meta l4proto udp dnat to numgen random mod 3 map { 0 : 10.0.2.1 . 9000, 1 : 10.0.2.1 . 9001, 2 : 10.0.2.1 . 9002 }
 28	}
 29
 30	chain prerouting {
 31		type nat hook prerouting priority dstnat
 32
 33		udp dport $dport counter jump lb
 34	}
 35
 36	chain output {
 37		type nat hook output priority dstnat
 38
 39		udp dport $dport counter jump lb
 40	}
 41}
 42EOF
 43
 44load_simple_ruleset()
 45{
 46ip netns exec "$1" nft -f -<<EOF
 47table ip t {
 48	chain forward {
 49		type filter hook forward priority 0
 50
 51		ct state new counter
 52	}
 53}
 54EOF
 55}
 56
 57spawn_servers()
 58{
 59	local ns="$1"
 60	local ports="9000 9001 9002"
 61
 62	for port in $ports; do
 63		ip netns exec "$ns" socat UDP-RECVFROM:$port,fork PIPE 2>/dev/null &
 64	done
 65
 66	for port in $ports; do
 67		wait_local_port_listen "$ns" $port udp
 68	done
 69}
 70
 71add_addr()
 72{
 73	local ns="$1"
 74	local dev="$2"
 75	local i="$3"
 76	local j="$4"
 77
 78	ip -net "$ns" link set "$dev" up
 79	ip -net "$ns" addr add "10.0.$i.$j/24" dev "$dev"
 80}
 81
 82ping_test()
 83{
 84	local ns="$1"
 85	local daddr="$2"
 86
 87	if ! ip netns exec "$ns" ping -q -c 1 $daddr > /dev/null;then
 88		echo "FAIL: ping from $ns to $daddr"
 89		exit 1
 90	fi
 91}
 92
 93run_one_clash_test()
 94{
 95	local ns="$1"
 96	local ctns="$2"
 97	local daddr="$3"
 98	local dport="$4"
 99	local entries
100	local cre
101
102	if ! ip netns exec "$ns" timeout 30 ./udpclash $daddr $dport;then
103		echo "INFO: did not receive expected number of replies for $daddr:$dport"
104		ip netns exec "$ctns" conntrack -S
105		# don't fail: check if clash resolution triggered after all.
106	fi
107
108	entries=$(ip netns exec "$ctns" conntrack -S | wc -l)
109	cre=$(ip netns exec "$ctns" conntrack -S | grep "clash_resolve=0" | wc -l)
110
111	if [ "$cre" -ne "$entries" ];then
112		clash_resolution_active=1
113		return 0
114	fi
115
116	# not a failure: clash resolution logic did not trigger.
117	# With right timing, xmit completed sequentially and
118	# no parallel insertion occurs.
119	return $ksft_xfail
120}
121
122run_clash_test()
123{
124	local ns="$1"
125	local ctns="$2"
126	local daddr="$3"
127	local dport="$4"
128	local softerr=0
129
130	for i in $(seq 1 10);do
131		run_one_clash_test "$ns" "$ctns" "$daddr" "$dport"
132		local rv=$?
133		if [ $rv -eq 0 ];then
134			echo "PASS: clash resolution test for $daddr:$dport on attempt $i"
135			return 0
136		elif [ $rv -eq $ksft_xfail ]; then
137			softerr=1
138		fi
139	done
140
141	[ $softerr -eq 1 ] && echo "XFAIL: clash resolution for $daddr:$dport did not trigger"
142}
143
144ip link add veth0 netns "$nsclient1" type veth peer name veth0 netns "$nsrouter"
145ip link add veth0 netns "$nsclient2" type veth peer name veth1 netns "$nsrouter"
146add_addr "$nsclient1" veth0 1 1
147add_addr "$nsclient2" veth0 2 1
148add_addr "$nsrouter" veth0 1 99
149add_addr "$nsrouter" veth1 2 99
150
151ip -net "$nsclient1" route add default via 10.0.1.99
152ip -net "$nsclient2" route add default via 10.0.2.99
153ip netns exec "$nsrouter" sysctl -q net.ipv4.ip_forward=1
154
155ping_test "$nsclient1" 10.0.1.99
156ping_test "$nsclient1" 10.0.2.1
157ping_test "$nsclient2" 10.0.1.1
158
159spawn_servers "$nsclient2"
160
161# exercise clash resolution with nat:
162# nsrouter is supposed to dnat to 10.0.2.1:900{0,1,2,3}.
163run_clash_test "$nsclient1" "$nsrouter" 10.0.1.99 "$dport"
164
165# exercise clash resolution without nat.
166load_simple_ruleset "$nsclient2"
167run_clash_test "$nsclient2" "$nsclient2" 127.0.0.1 9001
168
169if [ $clash_resolution_active -eq 0 ];then
170	[ "$ret" -eq 0 ] && ret=$ksft_xfail
171fi
172
173exit $ret
~/ Read-only file preview.