1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3 4BPF_FILE="lib/xdp_dummy.bpf.o" 5readonly STATS="$(mktemp -p /tmp ns-XXXXXX)" 6readonly BASE=`basename $STATS` 7readonly SRC=2 8readonly DST=1 9readonly DST_NAT=100 10readonly NS_SRC=$BASE$SRC 11readonly NS_DST=$BASE$DST 12# shellcheck disable=SC2155 # prefer RO variable over return value from cmd 13readonly YNL="$(dirname "$(readlink -f "$0")")/../../../net/ynl/pyynl/cli.py" 14 15# "baremetal" network used for raw UDP traffic 16readonly BM_NET_V4=192.168.1. 17readonly BM_NET_V6=2001:db8:: 18 19readonly CPUS=`nproc` 20ret=0 21 22cleanup() { 23 local ns 24 local jobs 25 readonly jobs="$(jobs -p)" 26 [ -n "${jobs}" ] && kill -1 ${jobs} 2>/dev/null 27 rm -f $STATS 28 29 for ns in $NS_SRC $NS_DST; do 30 ip netns del $ns 2>/dev/null 31 done 32} 33 34trap cleanup EXIT 35 36create_ns() { 37 local ns 38 39 for ns in $NS_SRC $NS_DST; do 40 ip netns add $ns 41 ip -n $ns link set dev lo up 42 done 43 44 ip link add name veth$SRC type veth peer name veth$DST 45 46 for ns in $SRC $DST; do 47 ip link set dev veth$ns netns $BASE$ns up 48 ip -n $BASE$ns addr add dev veth$ns $BM_NET_V4$ns/24 49 ip -n $BASE$ns addr add dev veth$ns $BM_NET_V6$ns/64 nodad 50 done 51} 52 53__chk_flag() { 54 local msg="$1" 55 local target=$2 56 local expected=$3 57 local flagname=$4 58 59 local flag=`ip netns exec $BASE$target ethtool -k veth$target |\ 60 grep $flagname | awk '{print $2}'` 61 62 printf "%-60s" "$msg" 63 if [ "$flag" = "$expected" ]; then 64 echo " ok " 65 else 66 echo " fail - expected $expected found $flag" 67 ret=1 68 fi 69} 70 71chk_gro_flag() { 72 __chk_flag "$1" $2 $3 generic-receive-offload 73} 74 75chk_tso_flag() { 76 __chk_flag "$1" $2 $3 tcp-segmentation-offload 77} 78 79chk_xdp_feature() { 80 local msg="$1" 81 local target=$2 82 local expected=$3 83 local feature=$4 84 local ifindex 85 local out 86 local st 87 local flag 88 89 ifindex=`ip netns exec $BASE$target cat /sys/class/net/veth$target/ifindex` 90 out=`ip netns exec $BASE$target "$YNL" --family netdev --do dev-get \ 91 --output-json --json "{\"ifindex\": $ifindex}" 2>&1` 92 st=$? 93 94 printf "%-60s" "$msg" 95 if [ $st -ne 0 ]; then 96 echo " fail - ynl cli error: $out" 97 ret=1 98 return 99 fi 100 101 flag=`echo "$out" | grep -c "\"$feature\""` 102 if [ "$flag" = "$expected" ]; then 103 echo " ok " 104 else 105 echo " fail - expected $expected found $flag" 106 ret=1 107 fi 108} 109 110chk_channels() { 111 local msg="$1" 112 local target=$2 113 local rx=$3 114 local tx=$4 115 116 local dev=veth$target 117 118 local cur_rx=`ip netns exec $BASE$target ethtool -l $dev |\ 119 grep RX: | tail -n 1 | awk '{print $2}' ` 120 local cur_tx=`ip netns exec $BASE$target ethtool -l $dev |\ 121 grep TX: | tail -n 1 | awk '{print $2}'` 122 local cur_combined=`ip netns exec $BASE$target ethtool -l $dev |\ 123 grep Combined: | tail -n 1 | awk '{print $2}'` 124 125 printf "%-60s" "$msg" 126 if [ "$cur_rx" = "$rx" -a "$cur_tx" = "$tx" -a "$cur_combined" = "n/a" ]; then 127 echo " ok " 128 else 129 echo " fail rx:$rx:$cur_rx tx:$tx:$cur_tx combined:n/a:$cur_combined" 130 fi 131} 132 133chk_gro() { 134 local msg="$1" 135 local expected=$2 136 137 ip netns exec $BASE$SRC ping -qc 1 $BM_NET_V4$DST >/dev/null 138 NSTAT_HISTORY=$STATS ip netns exec $NS_DST nstat -n 139 140 printf "%-60s" "$msg" 141 ip netns exec $BASE$DST ./udpgso_bench_rx -C 1000 -R 10 & 142 local spid=$! 143 sleep 0.1 144 145 ip netns exec $NS_SRC ./udpgso_bench_tx -4 -s 13000 -S 1300 -M 1 -D $BM_NET_V4$DST 146 local retc=$? 147 wait $spid 148 local rets=$? 149 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 150 echo " fail client exit code $retc, server $rets" 151 ret=1 152 return 153 fi 154 155 local pkts=`NSTAT_HISTORY=$STATS ip netns exec $NS_DST nstat IpInReceives | \ 156 awk '{print $2}' | tail -n 1` 157 if [ "$pkts" = "$expected" ]; then 158 echo " ok " 159 else 160 echo " fail - got $pkts packets, expected $expected " 161 ret=1 162 fi 163} 164 165__change_channels() 166{ 167 local cur_cpu 168 local end=$1 169 local cur 170 local i 171 172 while true; do 173 printf -v cur '%(%s)T' 174 [ $cur -le $end ] || break 175 176 for i in `seq 1 $CPUS`; do 177 ip netns exec $NS_SRC ethtool -L veth$SRC rx $i tx $i 178 ip netns exec $NS_DST ethtool -L veth$DST rx $i tx $i 179 done 180 181 for i in `seq 1 $((CPUS - 1))`; do 182 cur_cpu=$((CPUS - $i)) 183 ip netns exec $NS_SRC ethtool -L veth$SRC rx $cur_cpu tx $cur_cpu 184 ip netns exec $NS_DST ethtool -L veth$DST rx $cur_cpu tx $cur_cpu 185 done 186 done 187} 188 189__send_data() { 190 local end=$1 191 192 while true; do 193 printf -v cur '%(%s)T' 194 [ $cur -le $end ] || break 195 196 ip netns exec $NS_SRC ./udpgso_bench_tx -4 -s 1000 -M 300 -D $BM_NET_V4$DST 197 done 198} 199 200do_stress() { 201 local end 202 printf -v end '%(%s)T' 203 end=$((end + $STRESS)) 204 205 ip netns exec $NS_SRC ethtool -L veth$SRC rx 3 tx 3 206 ip netns exec $NS_DST ethtool -L veth$DST rx 3 tx 3 207 208 ip netns exec $NS_DST ./udpgso_bench_rx & 209 local rx_pid=$! 210 211 echo "Running stress test for $STRESS seconds..." 212 __change_channels $end & 213 local ch_pid=$! 214 __send_data $end & 215 local data_pid_1=$! 216 __send_data $end & 217 local data_pid_2=$! 218 __send_data $end & 219 local data_pid_3=$! 220 __send_data $end & 221 local data_pid_4=$! 222 223 wait $ch_pid $data_pid_1 $data_pid_2 $data_pid_3 $data_pid_4 224 kill -9 $rx_pid 225 echo "done" 226 227 # restore previous setting 228 ip netns exec $NS_SRC ethtool -L veth$SRC rx 2 tx 2 229 ip netns exec $NS_DST ethtool -L veth$DST rx 2 tx 1 230} 231 232usage() { 233 echo "Usage: $0 [-h] [-s <seconds>]" 234 echo -e "\t-h: show this help" 235 echo -e "\t-s: run optional stress tests for the given amount of seconds" 236} 237 238STRESS=0 239while getopts "hs:" option; do 240 case "$option" in 241 "h") 242 usage $0 243 exit 0 244 ;; 245 "s") 246 STRESS=$OPTARG 247 ;; 248 esac 249done 250 251if [ ! -f ${BPF_FILE} ]; then 252 echo "Missing ${BPF_FILE}. Run 'make' first" 253 exit 1 254fi 255 256[ $CPUS -lt 2 ] && echo "Only one CPU available, some tests will be skipped" 257[ $STRESS -gt 0 -a $CPUS -lt 3 ] && echo " stress test will be skipped, too" 258[ ! -f "$YNL" ] && echo "ynl cli not found, ndo-xmit tests will be skipped" 259 260create_ns 261chk_gro_flag "default - gro flag" $SRC off 262chk_gro_flag " - peer gro flag" $DST off 263chk_tso_flag " - tso flag" $SRC on 264chk_tso_flag " - peer tso flag" $DST on 265chk_gro " - aggregation" 1 266ip netns exec $NS_SRC ethtool -K veth$SRC tx-udp-segmentation off 267chk_gro " - aggregation with TSO off" 10 268cleanup 269 270create_ns 271ip netns exec $NS_DST ethtool -K veth$DST gro on 272chk_gro_flag "with gro on - gro flag" $DST on 273chk_gro_flag " - peer gro flag" $SRC off 274chk_tso_flag " - tso flag" $SRC on 275chk_tso_flag " - peer tso flag" $DST on 276ip netns exec $NS_SRC ethtool -K veth$SRC tx-udp-segmentation off 277ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on 278chk_gro " - aggregation with TSO off" 1 279cleanup 280 281create_ns 282ip -n $NS_DST link set dev veth$DST up 283ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp 284chk_gro_flag "gro vs xdp while down - gro flag off" $DST off 285ip -n $NS_DST link set dev veth$DST down 286chk_gro_flag " - after down" $DST off 287ip -n $NS_DST link set dev veth$DST xdp off 288chk_gro_flag " - after xdp off" $DST off 289ip -n $NS_DST link set dev veth$DST up 290chk_gro_flag " - after up" $DST off 291ip -n $NS_SRC link set dev veth$SRC xdp object ${BPF_FILE} section xdp 292chk_gro_flag " - after peer xdp" $DST off 293cleanup 294 295create_ns 296ip -n $NS_DST link set dev veth$DST up 297ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp 298ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on 299chk_gro_flag "gro vs xdp while down - gro flag on" $DST on 300ip -n $NS_DST link set dev veth$DST down 301chk_gro_flag " - after down" $DST on 302ip -n $NS_DST link set dev veth$DST xdp off 303chk_gro_flag " - after xdp off" $DST on 304ip -n $NS_DST link set dev veth$DST up 305chk_gro_flag " - after up" $DST on 306ip -n $NS_SRC link set dev veth$SRC xdp object ${BPF_FILE} section xdp 307chk_gro_flag " - after peer xdp" $DST on 308cleanup 309 310create_ns 311chk_channels "default channels" $DST 1 1 312 313ip -n $NS_DST link set dev veth$DST down 314ip netns exec $NS_DST ethtool -K veth$DST gro on 315chk_gro_flag "with gro enabled on link down - gro flag" $DST on 316chk_gro_flag " - peer gro flag" $SRC off 317chk_tso_flag " - tso flag" $SRC on 318chk_tso_flag " - peer tso flag" $DST on 319ip -n $NS_DST link set dev veth$DST up 320if [ -f "$YNL" ]; then 321 chk_xdp_feature " - peer ndo-xmit" $SRC 1 ndo-xmit 322 # make sure the peer flag is set before disabling gro while down 323 ip netns exec $NS_DST ethtool -K veth$DST gro off 324 ip netns exec $NS_DST ethtool -K veth$DST gro on 325 chk_xdp_feature " - peer ndo-xmit re-armed" $SRC 1 ndo-xmit 326 ip -n $NS_DST link set dev veth$DST down 327 ip netns exec $NS_DST ethtool -K veth$DST gro off 328 ip -n $NS_DST link set dev veth$DST up 329 chk_xdp_feature " - peer ndo-xmit cleared" $SRC 0 ndo-xmit 330 ip netns exec $NS_DST ethtool -K veth$DST gro on 331fi 332ip netns exec $NS_SRC ethtool -K veth$SRC tx-udp-segmentation off 333ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on 334chk_gro " - aggregation with TSO off" 1 335cleanup 336 337create_ns 338 339CUR_TX=1 340CUR_RX=1 341if [ $CPUS -gt 1 ]; then 342 ip netns exec $NS_DST ethtool -L veth$DST tx 2 343 chk_channels "setting tx channels" $DST 1 2 344 CUR_TX=2 345fi 346 347if [ $CPUS -gt 2 ]; then 348 ip netns exec $NS_DST ethtool -L veth$DST rx 3 tx 3 349 chk_channels "setting both rx and tx channels" $DST 3 3 350 CUR_RX=3 351 CUR_TX=3 352fi 353 354ip netns exec $NS_DST ethtool -L veth$DST combined 2 2>/dev/null 355chk_channels "bad setting: combined channels" $DST $CUR_RX $CUR_TX 356 357ip netns exec $NS_DST ethtool -L veth$DST tx $((CPUS + 1)) 2>/dev/null 358chk_channels "setting invalid channels nr" $DST $CUR_RX $CUR_TX 359 360if [ $CPUS -gt 1 ]; then 361 # this also tests queues nr reduction 362 ip netns exec $NS_DST ethtool -L veth$DST rx 1 tx 2 2>/dev/null 363 ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null 364 printf "%-60s" "bad setting: XDP with RX nr less than TX" 365 ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} \ 366 section xdp 2>/dev/null &&\ 367 echo "fail - set operation successful ?!?" || echo " ok " 368 369 # the following tests will run with multiple channels active 370 ip netns exec $NS_SRC ethtool -L veth$SRC rx 2 371 ip netns exec $NS_DST ethtool -L veth$DST rx 2 372 ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} \ 373 section xdp 2>/dev/null 374 printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set" 375 ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\ 376 echo "fail - set operation successful ?!?" || echo " ok " 377 CUR_RX=2 378 CUR_TX=2 379fi 380 381if [ $CPUS -gt 2 ]; then 382 printf "%-60s" "bad setting: increasing peer TX nr above RX with XDP set" 383 ip netns exec $NS_SRC ethtool -L veth$SRC tx 3 2>/dev/null &&\ 384 echo "fail - set operation successful ?!?" || echo " ok " 385 chk_channels "setting invalid channels nr" $DST 2 2 386fi 387 388ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp 2>/dev/null 389chk_gro_flag "with xdp attached - gro flag" $DST off 390chk_gro_flag " - peer gro flag" $SRC off 391chk_tso_flag " - tso flag" $SRC off 392chk_tso_flag " - peer tso flag" $DST on 393ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on 394chk_gro " - no aggregation" 10 395ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on 396chk_gro_flag " - gro flag with GRO on" $DST on 397chk_gro " - aggregation" 1 398 399 400ip -n $NS_DST link set dev veth$DST down 401ip -n $NS_SRC link set dev veth$SRC down 402chk_gro_flag " - after dev off, flag" $DST on 403chk_gro_flag " - peer flag" $SRC off 404 405ip netns exec $NS_DST ethtool -K veth$DST gro on 406ip -n $NS_DST link set dev veth$DST xdp off 407chk_gro_flag " - after gro on xdp off, gro flag" $DST on 408chk_gro_flag " - peer gro flag" $SRC off 409chk_tso_flag " - tso flag" $SRC on 410chk_tso_flag " - peer tso flag" $DST on 411 412if [ $CPUS -gt 1 ]; then 413 ip netns exec $NS_DST ethtool -L veth$DST tx 1 414 chk_channels "decreasing tx channels with device down" $DST 2 1 415fi 416 417ip -n $NS_DST link set dev veth$DST up 418ip -n $NS_SRC link set dev veth$SRC up 419chk_gro " - aggregation" 1 420 421if [ $CPUS -gt 1 ]; then 422 [ $STRESS -gt 0 -a $CPUS -gt 2 ] && do_stress 423 424 ip -n $NS_DST link set dev veth$DST down 425 ip -n $NS_SRC link set dev veth$SRC down 426 ip netns exec $NS_DST ethtool -L veth$DST tx 2 427 chk_channels "increasing tx channels with device down" $DST 2 2 428 ip -n $NS_DST link set dev veth$DST up 429 ip -n $NS_SRC link set dev veth$SRC up 430fi 431 432ip netns exec $NS_DST ethtool -K veth$DST gro off 433ip netns exec $NS_SRC ethtool -K veth$SRC tx-udp-segmentation off 434chk_gro "aggregation again with default and TSO off" 10 435 436exit $ret 437