#!/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