xref: /linux/tools/testing/selftests/net/netfilter/nft_zones_many.sh (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
1#!/bin/bash
2
3# Test insertion speed for packets with identical addresses/ports
4# that are all placed in distinct conntrack zones.
5
6source lib.sh
7
8zones=2000
9[ "$KSFT_MACHINE_SLOW" = yes ] && zones=500
10
11have_ct_tool=0
12ret=0
13
14cleanup()
15{
16	cleanup_all_ns
17}
18
19checktool "nft --version" "run test without nft tool"
20checktool "socat -V" "run test without socat tool"
21
22setup_ns ns1
23
24trap cleanup EXIT
25
26if conntrack -V > /dev/null 2>&1; then
27	have_ct_tool=1
28fi
29
30test_zones() {
31	local max_zones=$1
32
33ip netns exec "$ns1" nft -f /dev/stdin<<EOF
34flush ruleset
35table inet raw {
36	map rndzone {
37		typeof numgen inc mod $max_zones : ct zone
38	}
39
40	chain output {
41		type filter hook output priority -64000; policy accept;
42		udp dport 12345  ct zone set numgen inc mod 65536 map @rndzone
43	}
44}
45EOF
46if [ "$?" -ne 0 ];then
47	echo "SKIP: Cannot add nftables rules"
48	exit $ksft_skip
49fi
50
51	ip netns exec "$ns1" sysctl -q net.netfilter.nf_conntrack_udp_timeout=3600
52
53	(
54		echo "add element inet raw rndzone {"
55	for i in $(seq 1 "$max_zones");do
56		echo -n "$i : $i"
57		if [ "$i" -lt "$max_zones" ]; then
58			echo ","
59		else
60			echo "}"
61		fi
62	done
63	) | ip netns exec "$ns1" nft -f /dev/stdin
64
65	local i=0
66	local j=0
67	local outerstart
68	local stop
69	outerstart=$(date +%s%3N)
70	stop=$outerstart
71
72	while [ "$i" -lt "$max_zones" ]; do
73		local start
74		start=$(date +%s%3N)
75		i=$((i + 1000))
76		j=$((j + 1))
77		# nft rule in output places each packet in a different zone.
78		dd if=/dev/zero bs=8k count=1000 2>/dev/null | ip netns exec "$ns1" socat -u STDIN UDP:127.0.0.1:12345,sourceport=12345
79		if [ $? -ne 0 ] ;then
80			ret=1
81			break
82		fi
83
84		stop=$(date +%s%3N)
85		local duration=$((stop-start))
86		echo "PASS: added 1000 entries in $duration ms (now $i total, loop $j)"
87	done
88
89	if [ "$have_ct_tool" -eq 1 ]; then
90		local count duration
91		count=$(ip netns exec "$ns1" conntrack -C)
92		duration=$((stop-outerstart))
93
94		if [ "$count" -ge "$max_zones" ]; then
95			echo "PASS: inserted $count entries from packet path in $duration ms total"
96		else
97			ip netns exec "$ns1" conntrack -S 1>&2
98			echo "FAIL: inserted $count entries from packet path in $duration ms total, expected $max_zones entries"
99			ret=1
100		fi
101	fi
102
103	if [ $ret -ne 0 ];then
104		echo "FAIL: insert $max_zones entries from packet path" 1>&2
105	fi
106}
107
108test_conntrack_tool() {
109	local max_zones=$1
110
111	ip netns exec "$ns1" conntrack -F >/dev/null 2>/dev/null
112
113	local outerstart start stop i
114	outerstart=$(date +%s%3N)
115	start=$(date +%s%3N)
116	stop="$start"
117	i=0
118	while [ "$i" -lt "$max_zones" ]; do
119		i=$((i + 1))
120		ip netns exec "$ns1" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \
121	                 --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i >/dev/null 2>&1
122		if [ $? -ne 0 ];then
123			ip netns exec "$ns1" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \
124	                 --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i > /dev/null
125			echo "FAIL: conntrack -I returned an error"
126			ret=1
127			break
128		fi
129
130		if [ $((i%1000)) -eq 0 ];then
131			stop=$(date +%s%3N)
132
133			local duration=$((stop-start))
134			echo "PASS: added 1000 entries in $duration ms (now $i total)"
135			start=$stop
136		fi
137	done
138
139	local count
140	local duration
141	count=$(ip netns exec "$ns1" conntrack -C)
142	duration=$((stop-outerstart))
143
144	if [ "$count" -eq "$max_zones" ]; then
145		echo "PASS: inserted $count entries via ctnetlink in $duration ms"
146	else
147		ip netns exec "$ns1" conntrack -S 1>&2
148		echo "FAIL: inserted $count entries via ctnetlink in $duration ms, expected $max_zones entries ($duration ms)"
149		ret=1
150	fi
151}
152
153test_zones $zones
154
155if [ "$have_ct_tool" -eq 1 ];then
156	test_conntrack_tool $zones
157else
158	echo "SKIP: Could not run ctnetlink insertion test without conntrack tool"
159	if [ $ret -eq 0 ];then
160		exit $ksft_skip
161	fi
162fi
163
164exit $ret
165