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=testns-$(mktemp -u "XXXXXXXX") 13 14tables="foo bar baz quux" 15global_ret=0 16eret=0 17lret=0 18 19check_result() 20{ 21 local r=$1 22 local OK="PASS" 23 24 if [ $r -ne 0 ] ;then 25 OK="FAIL" 26 global_ret=$r 27 fi 28 29 echo "$OK: nft $2 test returned $r" 30 31 eret=0 32} 33 34nft --version > /dev/null 2>&1 35if [ $? -ne 0 ];then 36 echo "SKIP: Could not run test without nft tool" 37 exit $ksft_skip 38fi 39 40ip -Version > /dev/null 2>&1 41if [ $? -ne 0 ];then 42 echo "SKIP: Could not run test without ip tool" 43 exit $ksft_skip 44fi 45 46tmp=$(mktemp) 47 48for table in $tables; do 49 echo add table inet "$table" >> "$tmp" 50 echo flush table inet "$table" >> "$tmp" 51 52 echo "add chain inet $table INPUT { type filter hook input priority 0; }" >> "$tmp" 53 echo "add chain inet $table OUTPUT { type filter hook output priority 0; }" >> "$tmp" 54 for c in $(seq 1 400); do 55 chain=$(printf "chain%03u" "$c") 56 echo "add chain inet $table $chain" >> "$tmp" 57 done 58 59 for c in $(seq 1 400); do 60 chain=$(printf "chain%03u" "$c") 61 for BASE in INPUT OUTPUT; do 62 echo "add rule inet $table $BASE counter jump $chain" >> "$tmp" 63 done 64 echo "add rule inet $table $chain counter return" >> "$tmp" 65 done 66done 67 68ip netns add "$testns" 69ip -netns "$testns" link set lo up 70 71lscpu | grep ^CPU\(s\): | ( read cpu cpunum ; 72cpunum=$((cpunum-1)) 73for i in $(seq 0 $cpunum);do 74 mask=$(printf 0x%x $((1<<$i))) 75 ip netns exec "$testns" taskset $mask ping -4 127.0.0.1 -fq > /dev/null & 76 ip netns exec "$testns" taskset $mask ping -6 ::1 -fq > /dev/null & 77done) 78 79sleep 1 80 81ip netns exec "$testns" nft -f "$tmp" 82for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done 83 84for table in $tables;do 85 randsleep=$((RANDOM%2)) 86 sleep $randsleep 87 ip netns exec "$testns" nft delete table inet $table 88 lret=$? 89 if [ $lret -ne 0 ]; then 90 eret=$lret 91 fi 92done 93 94check_result $eret "add/delete" 95 96for i in $(seq 1 10) ; do 97 (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin 98 99 lret=$? 100 if [ $lret -ne 0 ]; then 101 eret=$lret 102 fi 103done 104 105check_result $eret "reload" 106 107for i in $(seq 1 10) ; do 108 (echo "flush ruleset"; cat "$tmp" 109 echo "insert rule inet foo INPUT meta nftrace set 1" 110 echo "insert rule inet foo OUTPUT meta nftrace set 1" 111 ) | ip netns exec "$testns" nft -f /dev/stdin 112 lret=$? 113 if [ $lret -ne 0 ]; then 114 eret=$lret 115 fi 116 117 (echo "flush ruleset"; cat "$tmp" 118 ) | ip netns exec "$testns" nft -f /dev/stdin 119 120 lret=$? 121 if [ $lret -ne 0 ]; then 122 eret=$lret 123 fi 124done 125 126check_result $eret "add/delete with nftrace enabled" 127 128echo "insert rule inet foo INPUT meta nftrace set 1" >> $tmp 129echo "insert rule inet foo OUTPUT meta nftrace set 1" >> $tmp 130 131for i in $(seq 1 10) ; do 132 (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin 133 134 lret=$? 135 if [ $lret -ne 0 ]; then 136 eret=1 137 fi 138done 139 140check_result $lret "add/delete with nftrace enabled" 141 142pkill -9 ping 143 144wait 145 146rm -f "$tmp" 147ip netns del "$testns" 148 149exit $global_ret 150