1#!/bin/bash
2#
3# This test is for stress-testing the nf_tables config plane path vs.
4# packet path processing: Make sure we never release rules that are
5# still visible to other cpus.
6#
7# set -e
8
9# Kselftest framework requirement - SKIP code is 4.
10ksft_skip=4
11
12testns=testns1
13tables="foo bar baz quux"
14
15nft --version > /dev/null 2>&1
16if [ $? -ne 0 ];then
17	echo "SKIP: Could not run test without nft tool"
18	exit $ksft_skip
19fi
20
21ip -Version > /dev/null 2>&1
22if [ $? -ne 0 ];then
23	echo "SKIP: Could not run test without ip tool"
24	exit $ksft_skip
25fi
26
27tmp=$(mktemp)
28
29for table in $tables; do
30	echo add table inet "$table" >> "$tmp"
31	echo flush table inet "$table" >> "$tmp"
32
33	echo "add chain inet $table INPUT { type filter hook input priority 0; }" >> "$tmp"
34	echo "add chain inet $table OUTPUT { type filter hook output priority 0; }" >> "$tmp"
35	for c in $(seq 1 400); do
36		chain=$(printf "chain%03u" "$c")
37		echo "add chain inet $table $chain" >> "$tmp"
38	done
39
40	for c in $(seq 1 400); do
41		chain=$(printf "chain%03u" "$c")
42		for BASE in INPUT OUTPUT; do
43			echo "add rule inet $table $BASE counter jump $chain" >> "$tmp"
44		done
45		echo "add rule inet $table $chain counter return" >> "$tmp"
46	done
47done
48
49ip netns add "$testns"
50ip -netns "$testns" link set lo up
51
52lscpu | grep ^CPU\(s\): | ( read cpu cpunum ;
53cpunum=$((cpunum-1))
54for i in $(seq 0 $cpunum);do
55	mask=$(printf 0x%x $((1<<$i)))
56        ip netns exec "$testns" taskset $mask ping -4 127.0.0.1 -fq > /dev/null &
57        ip netns exec "$testns" taskset $mask ping -6 ::1 -fq > /dev/null &
58done)
59
60sleep 1
61
62for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done
63
64for table in $tables;do
65	randsleep=$((RANDOM%10))
66	sleep $randsleep
67	ip netns exec "$testns" nft delete table inet $table 2>/dev/null
68done
69
70randsleep=$((RANDOM%10))
71sleep $randsleep
72
73pkill -9 ping
74
75wait
76
77rm -f "$tmp"
78ip netns del "$testns"
79