#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # # Test qdisc offload indication ALL_TESTS=" test_root test_port_tbf test_etsprio test_etsprio_port_tbf " NUM_NETIFS=1 lib_dir=$(dirname $0)/../../../net/forwarding source $lib_dir/lib.sh check_not_offloaded() { local handle=$1; shift local h local offloaded h=$(qdisc_stats_get $h1 "$handle" .handle) [[ $h == '"'$handle'"' ]] check_err $? "Qdisc with handle $handle does not exist" offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) [[ $offloaded == true ]] check_fail $? "Qdisc with handle $handle offloaded, but should not be" } check_all_offloaded() { local handle=$1; shift if [[ ! -z $handle ]]; then local offloaded=$(qdisc_stats_get $h1 "$handle" .offloaded) [[ $offloaded == true ]] check_err $? "Qdisc with handle $handle not offloaded" fi local unoffloaded=$(tc q sh dev $h1 invisible | grep -v offloaded | sed s/root/parent\ root/ | cut -d' ' -f 5) [[ -z $unoffloaded ]] check_err $? "Qdiscs with following parents not offloaded: $unoffloaded" pre_cleanup } with_ets() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle \ ets bands 8 priomap 7 6 5 4 3 2 1 0 "$@" tc qdisc del dev $h1 $locus } with_prio() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle \ prio bands 8 priomap 7 6 5 4 3 2 1 0 "$@" tc qdisc del dev $h1 $locus } with_red() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle \ red limit 1000000 min 200000 max 300000 probability 0.5 avpkt 1500 "$@" tc qdisc del dev $h1 $locus } with_tbf() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle \ tbf rate 400Mbit burst 128K limit 1M "$@" tc qdisc del dev $h1 $locus } with_pfifo() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle pfifo limit 100K "$@" tc qdisc del dev $h1 $locus } with_bfifo() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle bfifo limit 100K "$@" tc qdisc del dev $h1 $locus } with_drr() { local handle=$1; shift local locus=$1; shift tc qdisc add dev $h1 $locus handle $handle drr "$@" tc qdisc del dev $h1 $locus } with_qdiscs() { local handle=$1; shift local parent=$1; shift local kind=$1; shift local next_handle=$((handle * 2)) local locus; if [[ $kind == "--" ]]; then local cmd=$1; shift $cmd $(printf %x: $parent) "$@" else if ((parent == 0)); then locus=root else locus=$(printf "parent %x:1" $parent) fi with_$kind $(printf %x: $handle) "$locus" \ with_qdiscs $next_handle $handle "$@" fi } get_name() { local parent=$1; shift local name=$(echo "" "${@^^}" | tr ' ' -) if ((parent != 0)); then kind=$(qdisc_stats_get $h1 $parent: .kind) kind=${kind%\"} kind=${kind#\"} name="-${kind^^}$name" fi echo root$name } do_test_offloaded() { local handle=$1; shift local parent=$1; shift RET=0 with_qdiscs $handle $parent "$@" -- check_all_offloaded log_test $(get_name $parent "$@")" offloaded" } do_test_nooffload() { local handle=$1; shift local parent=$1; shift local name=$(echo "${@^^}" | tr ' ' -) local kind RET=0 with_qdiscs $handle $parent "$@" -- check_not_offloaded log_test $(get_name $parent "$@")" not offloaded" } do_test_combinations() { local handle=$1; shift local parent=$1; shift local cont local leaf local fifo for cont in "" ets prio; do for leaf in "" red tbf "red tbf" "tbf red"; do for fifo in "" pfifo bfifo; do if [[ -z "$cont$leaf$fifo" ]]; then continue fi do_test_offloaded $handle $parent \ $cont $leaf $fifo done done done for cont in ets prio; do for leaf in red tbf; do do_test_nooffload $handle $parent $cont red tbf $leaf do_test_nooffload $handle $parent $cont tbf red $leaf done for leaf in "red red" "tbf tbf"; do do_test_nooffload $handle $parent $cont $leaf done done do_test_nooffload $handle $parent drr } test_root() { do_test_combinations 1 0 } test_port_tbf() { with_tbf 1: root \ do_test_combinations 8 1 } do_test_etsprio() { local parent=$1; shift local tbfpfx=$1; shift local cont for cont in ets prio; do RET=0 with_$cont 8: "$parent" \ with_red 11: "parent 8:1" \ with_red 12: "parent 8:2" \ with_tbf 13: "parent 8:3" \ with_tbf 14: "parent 8:4" \ check_all_offloaded log_test "root$tbfpfx-ETS-{RED,TBF} offloaded" RET=0 with_$cont 8: "$parent" \ with_red 81: "parent 8:1" \ with_tbf 811: "parent 81:1" \ with_tbf 84: "parent 8:4" \ with_red 841: "parent 84:1" \ check_all_offloaded log_test "root$tbfpfx-ETS-{RED-TBF,TBF-RED} offloaded" RET=0 with_$cont 8: "$parent" \ with_red 81: "parent 8:1" \ with_tbf 811: "parent 81:1" \ with_bfifo 8111: "parent 811:1" \ with_tbf 82: "parent 8:2" \ with_red 821: "parent 82:1" \ with_bfifo 8211: "parent 821:1" \ check_all_offloaded log_test "root$tbfpfx-ETS-{RED-TBF-bFIFO,TBF-RED-bFIFO} offloaded" done } test_etsprio() { do_test_etsprio root "" } test_etsprio_port_tbf() { with_tbf 1: root \ do_test_etsprio "parent 1:1" "-TBF" } cleanup() { tc qdisc del dev $h1 root &>/dev/null } trap cleanup EXIT h1=${NETIFS[p1]} tests_run exit $EXIT_STATUS