| # SPDX-License-Identifier: GPL-2.0 | |
| # Global interface: | |
| # $put -- port under test (e.g. $swp2) | |
| # collect_stats($streams...) -- A function to get stats for individual streams | |
| # ets_start_traffic($band) -- Start traffic for this band | |
| # ets_change_qdisc($op, $dev, $nstrict, $quanta...) -- Add or change qdisc | |
| # WS describes the Qdisc configuration. It has one value per band (so the | |
| # number of array elements indicates the number of bands). If the value is | |
| # 0, it is a strict band, otherwise the it's a DRR band and the value is | |
| # that band's quantum. | |
| declare -a WS | |
| qdisc_describe() | |
| { | |
| local nbands=${#WS[@]} | |
| local nstrict=0 | |
| local i | |
| for ((i = 0; i < nbands; i++)); do | |
| if ((!${WS[$i]})); then | |
| : $((nstrict++)) | |
| fi | |
| done | |
| echo -n "ets bands $nbands" | |
| if ((nstrict)); then | |
| echo -n " strict $nstrict" | |
| fi | |
| if ((nstrict < nbands)); then | |
| echo -n " quanta" | |
| for ((i = nstrict; i < nbands; i++)); do | |
| echo -n " ${WS[$i]}" | |
| done | |
| fi | |
| } | |
| __strict_eval() | |
| { | |
| local desc=$1; shift | |
| local d=$1; shift | |
| local total=$1; shift | |
| local above=$1; shift | |
| RET=0 | |
| if ((! total)); then | |
| check_err 1 "No traffic observed" | |
| log_test "$desc" | |
| return | |
| fi | |
| local ratio=$(echo "scale=2; 100 * $d / $total" | bc -l) | |
| if ((above)); then | |
| test $(echo "$ratio > 95.0" | bc -l) -eq 1 | |
| check_err $? "Not enough traffic" | |
| log_test "$desc" | |
| log_info "Expected ratio >95% Measured ratio $ratio" | |
| else | |
| test $(echo "$ratio < 5" | bc -l) -eq 1 | |
| check_err $? "Too much traffic" | |
| log_test "$desc" | |
| log_info "Expected ratio <5% Measured ratio $ratio" | |
| fi | |
| } | |
| strict_eval() | |
| { | |
| __strict_eval "$@" 1 | |
| } | |
| notraf_eval() | |
| { | |
| __strict_eval "$@" 0 | |
| } | |
| __ets_dwrr_test() | |
| { | |
| local -a streams=("$@") | |
| local low_stream=${streams[0]} | |
| local seen_strict=0 | |
| local -a t0 t1 d | |
| local stream | |
| local total | |
| local i | |
| echo "Testing $(qdisc_describe), streams ${streams[@]}" | |
| for stream in ${streams[@]}; do | |
| ets_start_traffic $stream | |
| done | |
| sleep 10 | |
| t0=($(collect_stats "${streams[@]}")) | |
| sleep 10 | |
| t1=($(collect_stats "${streams[@]}")) | |
| d=($(for ((i = 0; i < ${#streams[@]}; i++)); do | |
| echo $((${t1[$i]} - ${t0[$i]})) | |
| done)) | |
| total=$(echo ${d[@]} | sed 's/ /+/g' | bc) | |
| for ((i = 0; i < ${#streams[@]}; i++)); do | |
| local stream=${streams[$i]} | |
| if ((seen_strict)); then | |
| notraf_eval "band $stream" ${d[$i]} $total | |
| elif ((${WS[$stream]} == 0)); then | |
| strict_eval "band $stream" ${d[$i]} $total | |
| seen_strict=1 | |
| elif ((stream == low_stream)); then | |
| # Low stream is used as DWRR evaluation reference. | |
| continue | |
| else | |
| multipath_eval "bands $low_stream:$stream" \ | |
| ${WS[$low_stream]} ${WS[$stream]} \ | |
| ${d[0]} ${d[$i]} | |
| fi | |
| done | |
| for stream in ${streams[@]}; do | |
| stop_traffic | |
| done | |
| } | |
| ets_dwrr_test_012() | |
| { | |
| __ets_dwrr_test 0 1 2 | |
| } | |
| ets_dwrr_test_01() | |
| { | |
| __ets_dwrr_test 0 1 | |
| } | |
| ets_dwrr_test_12() | |
| { | |
| __ets_dwrr_test 1 2 | |
| } | |
| ets_qdisc_setup() | |
| { | |
| local dev=$1; shift | |
| local nstrict=$1; shift | |
| local -a quanta=("$@") | |
| local ndwrr=${#quanta[@]} | |
| local nbands=$((nstrict + ndwrr)) | |
| local nstreams=$(if ((nbands > 3)); then echo 3; else echo $nbands; fi) | |
| local priomap=$(seq 0 $((nstreams - 1))) | |
| local i | |
| WS=($( | |
| for ((i = 0; i < nstrict; i++)); do | |
| echo 0 | |
| done | |
| for ((i = 0; i < ndwrr; i++)); do | |
| echo ${quanta[$i]} | |
| done | |
| )) | |
| ets_change_qdisc $dev $nstrict "$priomap" ${quanta[@]} | |
| } | |
| ets_set_dwrr_uniform() | |
| { | |
| ets_qdisc_setup $put 0 3300 3300 3300 | |
| } | |
| ets_set_dwrr_varying() | |
| { | |
| ets_qdisc_setup $put 0 5000 3500 1500 | |
| } | |
| ets_set_strict() | |
| { | |
| ets_qdisc_setup $put 3 | |
| } | |
| ets_set_mixed() | |
| { | |
| ets_qdisc_setup $put 1 5000 2500 1500 | |
| } | |
| ets_change_quantum() | |
| { | |
| tc class change dev $put classid 10:2 ets quantum 8000 | |
| WS[1]=8000 | |
| } | |
| ets_set_dwrr_two_bands() | |
| { | |
| ets_qdisc_setup $put 0 5000 2500 | |
| } | |
| ets_test_strict() | |
| { | |
| ets_set_strict | |
| ets_dwrr_test_01 | |
| ets_dwrr_test_12 | |
| } | |
| ets_test_mixed() | |
| { | |
| ets_set_mixed | |
| ets_dwrr_test_01 | |
| ets_dwrr_test_12 | |
| } | |
| ets_test_dwrr() | |
| { | |
| ets_set_dwrr_uniform | |
| ets_dwrr_test_012 | |
| ets_set_dwrr_varying | |
| ets_dwrr_test_012 | |
| ets_change_quantum | |
| ets_dwrr_test_012 | |
| ets_set_dwrr_two_bands | |
| ets_dwrr_test_01 | |
| } |