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