1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test qdisc offload indication 5 6 7ALL_TESTS=" 8 test_root 9 test_port_tbf 10 test_etsprio 11 test_etsprio_port_tbf 12" 13NUM_NETIFS=1 14lib_dir=$(dirname $0)/../../../net/forwarding 15source $lib_dir/lib.sh 16 17check_not_offloaded() 18{ 19 local handle=$1; shift 20 local h 21 local offloaded 22 23 h=$(qdisc_stats_get $h1 "$handle" .handle) 24 [[ $h == '"'$handle'"' ]] 25 check_err $? "Qdisc with handle $handle does not exist" 26 27 offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) 28 [[ $offloaded == true ]] 29 check_fail $? "Qdisc with handle $handle offloaded, but should not be" 30} 31 32check_all_offloaded() 33{ 34 local handle=$1; shift 35 36 if [[ ! -z $handle ]]; then 37 local offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) 38 [[ $offloaded == true ]] 39 check_err $? "Qdisc with handle $handle not offloaded" 40 fi 41 42 local unoffloaded=$(tc q sh dev $h1 invisible | 43 grep -v offloaded | 44 sed s/root/parent\ root/ | 45 cut -d' ' -f 5) 46 [[ -z $unoffloaded ]] 47 check_err $? "Qdiscs with following parents not offloaded: $unoffloaded" 48 49 pre_cleanup 50} 51 52with_ets() 53{ 54 local handle=$1; shift 55 local locus=$1; shift 56 57 tc qdisc add dev $h1 $locus handle $handle \ 58 ets bands 8 priomap 7 6 5 4 3 2 1 0 59 "$@" 60 tc qdisc del dev $h1 $locus 61} 62 63with_prio() 64{ 65 local handle=$1; shift 66 local locus=$1; shift 67 68 tc qdisc add dev $h1 $locus handle $handle \ 69 prio bands 8 priomap 7 6 5 4 3 2 1 0 70 "$@" 71 tc qdisc del dev $h1 $locus 72} 73 74with_red() 75{ 76 local handle=$1; shift 77 local locus=$1; shift 78 79 tc qdisc add dev $h1 $locus handle $handle \ 80 red limit 1000000 min 200000 max 300000 probability 0.5 avpkt 1500 81 "$@" 82 tc qdisc del dev $h1 $locus 83} 84 85with_tbf() 86{ 87 local handle=$1; shift 88 local locus=$1; shift 89 90 tc qdisc add dev $h1 $locus handle $handle \ 91 tbf rate 400Mbit burst 128K limit 1M 92 "$@" 93 tc qdisc del dev $h1 $locus 94} 95 96with_pfifo() 97{ 98 local handle=$1; shift 99 local locus=$1; shift 100 101 tc qdisc add dev $h1 $locus handle $handle pfifo limit 100K 102 "$@" 103 tc qdisc del dev $h1 $locus 104} 105 106with_bfifo() 107{ 108 local handle=$1; shift 109 local locus=$1; shift 110 111 tc qdisc add dev $h1 $locus handle $handle bfifo limit 100K 112 "$@" 113 tc qdisc del dev $h1 $locus 114} 115 116with_drr() 117{ 118 local handle=$1; shift 119 local locus=$1; shift 120 121 tc qdisc add dev $h1 $locus handle $handle drr 122 "$@" 123 tc qdisc del dev $h1 $locus 124} 125 126with_qdiscs() 127{ 128 local handle=$1; shift 129 local parent=$1; shift 130 local kind=$1; shift 131 local next_handle=$((handle * 2)) 132 local locus; 133 134 if [[ $kind == "--" ]]; then 135 local cmd=$1; shift 136 $cmd $(printf %x: $parent) "$@" 137 else 138 if ((parent == 0)); then 139 locus=root 140 else 141 locus=$(printf "parent %x:1" $parent) 142 fi 143 144 with_$kind $(printf %x: $handle) "$locus" \ 145 with_qdiscs $next_handle $handle "$@" 146 fi 147} 148 149get_name() 150{ 151 local parent=$1; shift 152 local name=$(echo "" "${@^^}" | tr ' ' -) 153 154 if ((parent != 0)); then 155 kind=$(qdisc_stats_get $h1 $parent: .kind) 156 kind=${kind%\"} 157 kind=${kind#\"} 158 name="-${kind^^}$name" 159 fi 160 161 echo root$name 162} 163 164do_test_offloaded() 165{ 166 local handle=$1; shift 167 local parent=$1; shift 168 169 RET=0 170 with_qdiscs $handle $parent "$@" -- check_all_offloaded 171 log_test $(get_name $parent "$@")" offloaded" 172} 173 174do_test_nooffload() 175{ 176 local handle=$1; shift 177 local parent=$1; shift 178 179 local name=$(echo "${@^^}" | tr ' ' -) 180 local kind 181 182 RET=0 183 with_qdiscs $handle $parent "$@" -- check_not_offloaded 184 log_test $(get_name $parent "$@")" not offloaded" 185} 186 187do_test_combinations() 188{ 189 local handle=$1; shift 190 local parent=$1; shift 191 192 local cont 193 local leaf 194 local fifo 195 196 for cont in "" ets prio; do 197 for leaf in "" red tbf "red tbf" "tbf red"; do 198 for fifo in "" pfifo bfifo; do 199 if [[ -z "$cont$leaf$fifo" ]]; then 200 continue 201 fi 202 do_test_offloaded $handle $parent \ 203 $cont $leaf $fifo 204 done 205 done 206 done 207 208 for cont in ets prio; do 209 for leaf in red tbf; do 210 do_test_nooffload $handle $parent $cont red tbf $leaf 211 do_test_nooffload $handle $parent $cont tbf red $leaf 212 done 213 for leaf in "red red" "tbf tbf"; do 214 do_test_nooffload $handle $parent $cont $leaf 215 done 216 done 217 218 do_test_nooffload $handle $parent drr 219} 220 221test_root() 222{ 223 do_test_combinations 1 0 224} 225 226test_port_tbf() 227{ 228 with_tbf 1: root \ 229 do_test_combinations 8 1 230} 231 232do_test_etsprio() 233{ 234 local parent=$1; shift 235 local tbfpfx=$1; shift 236 local cont 237 238 for cont in ets prio; do 239 RET=0 240 with_$cont 8: "$parent" \ 241 with_red 11: "parent 8:1" \ 242 with_red 12: "parent 8:2" \ 243 with_tbf 13: "parent 8:3" \ 244 with_tbf 14: "parent 8:4" \ 245 check_all_offloaded 246 log_test "root$tbfpfx-ETS-{RED,TBF} offloaded" 247 248 RET=0 249 with_$cont 8: "$parent" \ 250 with_red 81: "parent 8:1" \ 251 with_tbf 811: "parent 81:1" \ 252 with_tbf 84: "parent 8:4" \ 253 with_red 841: "parent 84:1" \ 254 check_all_offloaded 255 log_test "root$tbfpfx-ETS-{RED-TBF,TBF-RED} offloaded" 256 257 RET=0 258 with_$cont 8: "$parent" \ 259 with_red 81: "parent 8:1" \ 260 with_tbf 811: "parent 81:1" \ 261 with_bfifo 8111: "parent 811:1" \ 262 with_tbf 82: "parent 8:2" \ 263 with_red 821: "parent 82:1" \ 264 with_bfifo 8211: "parent 821:1" \ 265 check_all_offloaded 266 log_test "root$tbfpfx-ETS-{RED-TBF-bFIFO,TBF-RED-bFIFO} offloaded" 267 done 268} 269 270test_etsprio() 271{ 272 do_test_etsprio root "" 273} 274 275test_etsprio_port_tbf() 276{ 277 with_tbf 1: root \ 278 do_test_etsprio "parent 1:1" "-TBF" 279} 280 281cleanup() 282{ 283 tc qdisc del dev $h1 root &>/dev/null 284} 285 286trap cleanup EXIT 287h1=${NETIFS[p1]} 288tests_run 289 290exit $EXIT_STATUS 291