aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/testing/selftests/netfilter/nft_trans_stress.sh
blob: 2ffba45a78bf450bd3f969476607d2866a2dcb85 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/bin/bash
#
# This test is for stress-testing the nf_tables config plane path vs.
# packet path processing: Make sure we never release rules that are
# still visible to other cpus.
#
# set -e

# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4

testns=testns-$(mktemp -u "XXXXXXXX")
tmp=""

tables="foo bar baz quux"
global_ret=0
eret=0
lret=0

cleanup() {
	ip netns pids "$testns" | xargs kill 2>/dev/null
	ip netns del "$testns"

	rm -f "$tmp"
}

check_result()
{
	local r=$1
	local OK="PASS"

	if [ $r -ne 0 ] ;then
		OK="FAIL"
		global_ret=$r
	fi

	echo "$OK: nft $2 test returned $r"

	eret=0
}

nft --version > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without nft tool"
	exit $ksft_skip
fi

ip -Version > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without ip tool"
	exit $ksft_skip
fi

trap cleanup EXIT
tmp=$(mktemp)

for table in $tables; do
	echo add table inet "$table" >> "$tmp"
	echo flush table inet "$table" >> "$tmp"

	echo "add chain inet $table INPUT { type filter hook input priority 0; }" >> "$tmp"
	echo "add chain inet $table OUTPUT { type filter hook output priority 0; }" >> "$tmp"
	for c in $(seq 1 400); do
		chain=$(printf "chain%03u" "$c")
		echo "add chain inet $table $chain" >> "$tmp"
	done

	for c in $(seq 1 400); do
		chain=$(printf "chain%03u" "$c")
		for BASE in INPUT OUTPUT; do
			echo "add rule inet $table $BASE counter jump $chain" >> "$tmp"
		done
		echo "add rule inet $table $chain counter return" >> "$tmp"
	done
done

ip netns add "$testns"
ip -netns "$testns" link set lo up

lscpu | grep ^CPU\(s\): | ( read cpu cpunum ;
cpunum=$((cpunum-1))
for i in $(seq 0 $cpunum);do
	mask=$(printf 0x%x $((1<<$i)))
        ip netns exec "$testns" taskset $mask ping -4 127.0.0.1 -fq > /dev/null &
        ip netns exec "$testns" taskset $mask ping -6 ::1 -fq > /dev/null &
done)

sleep 1

ip netns exec "$testns" nft -f "$tmp"
for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done

for table in $tables;do
	randsleep=$((RANDOM%2))
	sleep $randsleep
	ip netns exec "$testns" nft delete table inet $table
	lret=$?
	if [ $lret -ne 0 ]; then
		eret=$lret
	fi
done

check_result $eret "add/delete"

for i in $(seq 1 10) ; do
	(echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin

	lret=$?
	if [ $lret -ne 0 ]; then
		eret=$lret
	fi
done

check_result $eret "reload"

for i in $(seq 1 10) ; do
	(echo "flush ruleset"; cat "$tmp"
	 echo "insert rule inet foo INPUT meta nftrace set 1"
	 echo "insert rule inet foo OUTPUT meta nftrace set 1"
	 ) | ip netns exec "$testns" nft -f /dev/stdin
	lret=$?
	if [ $lret -ne 0 ]; then
		eret=$lret
	fi

	(echo "flush ruleset"; cat "$tmp"
	 ) | ip netns exec "$testns" nft -f /dev/stdin

	lret=$?
	if [ $lret -ne 0 ]; then
		eret=$lret
	fi
done

check_result $eret "add/delete with nftrace enabled"

echo "insert rule inet foo INPUT meta nftrace set 1" >> $tmp
echo "insert rule inet foo OUTPUT meta nftrace set 1" >> $tmp

for i in $(seq 1 10) ; do
	(echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin

	lret=$?
	if [ $lret -ne 0 ]; then
		eret=1
	fi
done

check_result $lret "add/delete with nftrace enabled"

exit $global_ret