1#!/bin/bash 2 3# Test insertion speed for packets with identical addresses/ports 4# that are all placed in distinct conntrack zones. 5 6sfx=$(mktemp -u "XXXXXXXX") 7ns="ns-$sfx" 8 9# Kselftest framework requirement - SKIP code is 4. 10ksft_skip=4 11 12zones=2000 13have_ct_tool=0 14ret=0 15 16cleanup() 17{ 18 ip netns del $ns 19} 20 21checktool (){ 22 if ! $1 > /dev/null 2>&1; then 23 echo "SKIP: Could not $2" 24 exit $ksft_skip 25 fi 26} 27 28checktool "nft --version" "run test without nft tool" 29checktool "ip -Version" "run test without ip tool" 30checktool "socat -V" "run test without socat tool" 31checktool "ip netns add $ns" "create net namespace" 32 33trap cleanup EXIT 34 35conntrack -V > /dev/null 2>&1 36if [ $? -eq 0 ];then 37 have_ct_tool=1 38fi 39 40ip -net "$ns" link set lo up 41 42test_zones() { 43 local max_zones=$1 44 45ip netns exec $ns sysctl -q net.netfilter.nf_conntrack_udp_timeout=3600 46ip netns exec $ns nft -f /dev/stdin<<EOF 47flush ruleset 48table inet raw { 49 map rndzone { 50 typeof numgen inc mod $max_zones : ct zone 51 } 52 53 chain output { 54 type filter hook output priority -64000; policy accept; 55 udp dport 12345 ct zone set numgen inc mod 65536 map @rndzone 56 } 57} 58EOF 59 ( 60 echo "add element inet raw rndzone {" 61 for i in $(seq 1 $max_zones);do 62 echo -n "$i : $i" 63 if [ $i -lt $max_zones ]; then 64 echo "," 65 else 66 echo "}" 67 fi 68 done 69 ) | ip netns exec $ns nft -f /dev/stdin 70 71 local i=0 72 local j=0 73 local outerstart=$(date +%s%3N) 74 local stop=$outerstart 75 76 while [ $i -lt $max_zones ]; do 77 local start=$(date +%s%3N) 78 i=$((i + 1000)) 79 j=$((j + 1)) 80 # nft rule in output places each packet in a different zone. 81 dd if=/dev/zero of=/dev/stdout bs=8k count=1000 2>/dev/null | ip netns exec "$ns" socat STDIN UDP:127.0.0.1:12345,sourceport=12345 82 if [ $? -ne 0 ] ;then 83 ret=1 84 break 85 fi 86 87 stop=$(date +%s%3N) 88 local duration=$((stop-start)) 89 echo "PASS: added 1000 entries in $duration ms (now $i total, loop $j)" 90 done 91 92 if [ $have_ct_tool -eq 1 ]; then 93 local count=$(ip netns exec "$ns" conntrack -C) 94 local duration=$((stop-outerstart)) 95 96 if [ $count -eq $max_zones ]; then 97 echo "PASS: inserted $count entries from packet path in $duration ms total" 98 else 99 ip netns exec $ns conntrack -S 1>&2 100 echo "FAIL: inserted $count entries from packet path in $duration ms total, expected $max_zones entries" 101 ret=1 102 fi 103 fi 104 105 if [ $ret -ne 0 ];then 106 echo "FAIL: insert $max_zones entries from packet path" 1>&2 107 fi 108} 109 110test_conntrack_tool() { 111 local max_zones=$1 112 113 ip netns exec $ns conntrack -F >/dev/null 2>/dev/null 114 115 local outerstart=$(date +%s%3N) 116 local start=$(date +%s%3N) 117 local stop=$start 118 local i=0 119 while [ $i -lt $max_zones ]; do 120 i=$((i + 1)) 121 ip netns exec "$ns" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \ 122 --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i >/dev/null 2>&1 123 if [ $? -ne 0 ];then 124 ip netns exec "$ns" conntrack -I -s 1.1.1.1 -d 2.2.2.2 --protonum 6 \ 125 --timeout 3600 --state ESTABLISHED --sport 12345 --dport 1000 --zone $i > /dev/null 126 echo "FAIL: conntrack -I returned an error" 127 ret=1 128 break 129 fi 130 131 if [ $((i%1000)) -eq 0 ];then 132 stop=$(date +%s%3N) 133 134 local duration=$((stop-start)) 135 echo "PASS: added 1000 entries in $duration ms (now $i total)" 136 start=$stop 137 fi 138 done 139 140 local count=$(ip netns exec "$ns" conntrack -C) 141 local duration=$((stop-outerstart)) 142 143 if [ $count -eq $max_zones ]; then 144 echo "PASS: inserted $count entries via ctnetlink in $duration ms" 145 else 146 ip netns exec $ns conntrack -S 1>&2 147 echo "FAIL: inserted $count entries via ctnetlink in $duration ms, expected $max_zones entries ($duration ms)" 148 ret=1 149 fi 150} 151 152test_zones $zones 153 154if [ $have_ct_tool -eq 1 ];then 155 test_conntrack_tool $zones 156else 157 echo "SKIP: Could not run ctnetlink insertion test without conntrack tool" 158 if [ $ret -eq 0 ];then 159 exit $ksft_skip 160 fi 161fi 162 163exit $ret 164