Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: add script to stress-test nft packet path vs. control plane

Start flood ping for each cpu while loading/flushing rulesets to make
sure we do not access already-free'd rules from nf_tables evaluation loop.

Also add this to TARGETS so 'make run_tests' in selftest dir runs it
automatically.

This would have caught the bug fixed in previous change
("netfilter: nf_tables: do not skip inactive chains during generation update")
sooner.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
25d8bced 0fb39bbe

+87
+1
tools/testing/selftests/Makefile
··· 24 24 TARGETS += mount 25 25 TARGETS += mqueue 26 26 TARGETS += net 27 + TARGETS += netfilter 27 28 TARGETS += nsfs 28 29 TARGETS += powerpc 29 30 TARGETS += proc
+6
tools/testing/selftests/netfilter/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # Makefile for netfilter selftests 3 + 4 + TEST_PROGS := nft_trans_stress.sh 5 + 6 + include ../lib.mk
+2
tools/testing/selftests/netfilter/config
··· 1 + CONFIG_NET_NS=y 2 + NF_TABLES_INET=y
+78
tools/testing/selftests/netfilter/nft_trans_stress.sh
··· 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. 10 + ksft_skip=4 11 + 12 + testns=testns1 13 + tables="foo bar baz quux" 14 + 15 + nft --version > /dev/null 2>&1 16 + if [ $? -ne 0 ];then 17 + echo "SKIP: Could not run test without nft tool" 18 + exit $ksft_skip 19 + fi 20 + 21 + ip -Version > /dev/null 2>&1 22 + if [ $? -ne 0 ];then 23 + echo "SKIP: Could not run test without ip tool" 24 + exit $ksft_skip 25 + fi 26 + 27 + tmp=$(mktemp) 28 + 29 + for 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 47 + done 48 + 49 + ip netns add "$testns" 50 + ip -netns "$testns" link set lo up 51 + 52 + lscpu | grep ^CPU\(s\): | ( read cpu cpunum ; 53 + cpunum=$((cpunum-1)) 54 + for 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 & 58 + done) 59 + 60 + sleep 1 61 + 62 + for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done 63 + 64 + for table in $tables;do 65 + randsleep=$((RANDOM%10)) 66 + sleep $randsleep 67 + ip netns exec "$testns" nft delete table inet $table 2>/dev/null 68 + done 69 + 70 + randsleep=$((RANDOM%10)) 71 + sleep $randsleep 72 + 73 + pkill -9 ping 74 + 75 + wait 76 + 77 + rm -f "$tmp" 78 + ip netns del "$testns"