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