1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# A test for strict prioritization of traffic in the switch. Run two streams of 5# traffic, each through a different ingress port, one tagged with PCP of 1, the 6# other with PCP of 2. Both streams converge at one egress port, where they are 7# assigned TC of, respectively, 1 and 2, with strict priority configured between 8# them. In H3, we expect to see (almost) exclusively the high-priority traffic. 9# 10# Please see qos_mc_aware.sh for an explanation of why we use mausezahn and 11# counters instead of just running iperf3. 12# 13# +---------------------------+ +-----------------------------+ 14# | H1 | | H2 | 15# | $h1.111 + | | + $h2.222 | 16# | 192.0.2.33/28 | | | | 192.0.2.65/28 | 17# | e-qos-map 0:1 | | | | e-qos-map 0:2 | 18# | | | | | | 19# | $h1 + | | + $h2 | 20# +-----------------|---------+ +---------|-------------------+ 21# | | 22# +-----------------|-------------------------------------|-------------------+ 23# | $swp1 + + $swp2 | 24# | >1Gbps | | >1Gbps | 25# | +---------------|-----------+ +----------|----------------+ | 26# | | $swp1.111 + | | + $swp2.222 | | 27# | | BR111 | SW | BR222 | | 28# | | $swp3.111 + | | + $swp3.222 | | 29# | +---------------|-----------+ +----------|----------------+ | 30# | \_____________________________________/ | 31# | | | 32# | + $swp3 | 33# | | 1Gbps bottleneck | 34# | | ETS: (up n->tc n for n in 0..7) | 35# | | strict priority | 36# +------------------------------------|--------------------------------------+ 37# | 38# +--------------------|--------------------+ 39# | + $h3 H3 | 40# | / \ | 41# | / \ | 42# | $h3.111 + + $h3.222 | 43# | 192.0.2.34/28 192.0.2.66/28 | 44# +-----------------------------------------+ 45 46ALL_TESTS=" 47 ping_ipv4 48 test_ets_strict 49" 50 51lib_dir=$(dirname $0)/../../../net/forwarding 52 53NUM_NETIFS=6 54source $lib_dir/lib.sh 55source $lib_dir/devlink_lib.sh 56source qos_lib.sh 57 58h1_create() 59{ 60 adf_simple_if_init $h1 61 62 mtu_set $h1 10000 63 defer mtu_restore $h1 64 65 vlan_create $h1 111 v$h1 192.0.2.33/28 66 defer vlan_destroy $h1 111 67 ip link set dev $h1.111 type vlan egress-qos-map 0:1 68} 69 70h2_create() 71{ 72 adf_simple_if_init $h2 73 74 mtu_set $h2 10000 75 defer mtu_restore $h2 76 77 vlan_create $h2 222 v$h2 192.0.2.65/28 78 defer vlan_destroy $h2 222 79 ip link set dev $h2.222 type vlan egress-qos-map 0:2 80} 81 82h3_create() 83{ 84 adf_simple_if_init $h3 85 86 mtu_set $h3 10000 87 defer mtu_restore $h3 88 89 vlan_create $h3 111 v$h3 192.0.2.34/28 90 defer vlan_destroy $h3 111 91 92 vlan_create $h3 222 v$h3 192.0.2.66/28 93 defer vlan_destroy $h3 222 94} 95 96switch_create() 97{ 98 ip link set dev $swp1 up 99 defer ip link set dev $swp1 down 100 101 mtu_set $swp1 10000 102 defer mtu_restore $swp1 103 104 ip link set dev $swp2 up 105 defer ip link set dev $swp2 down 106 107 mtu_set $swp2 10000 108 defer mtu_restore $swp2 109 110 # prio n -> TC n, strict scheduling 111 lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7 112 defer lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0 113 114 lldptool -T -i $swp3 -V ETS-CFG tsa=$( 115 )"0:strict,"$( 116 )"1:strict,"$( 117 )"2:strict,"$( 118 )"3:strict,"$( 119 )"4:strict,"$( 120 )"5:strict,"$( 121 )"6:strict,"$( 122 )"7:strict" 123 sleep 1 124 125 ip link set dev $swp3 up 126 defer ip link set dev $swp3 down 127 128 mtu_set $swp3 10000 129 defer mtu_restore $swp3 130 131 tc qdisc replace dev $swp3 root handle 101: tbf rate 1gbit \ 132 burst 128K limit 1G 133 defer tc qdisc del dev $swp3 root handle 101: 134 135 vlan_create $swp1 111 136 defer vlan_destroy $swp1 111 137 138 vlan_create $swp2 222 139 defer vlan_destroy $swp2 222 140 141 vlan_create $swp3 111 142 defer vlan_destroy $swp3 111 143 144 vlan_create $swp3 222 145 defer vlan_destroy $swp3 222 146 147 ip link add name br111 type bridge vlan_filtering 0 148 defer ip link del dev br111 149 ip link set dev br111 addrgenmode none 150 151 ip link set dev br111 up 152 defer ip link set dev br111 down 153 154 ip link set dev $swp1.111 master br111 155 defer ip link set dev $swp1.111 nomaster 156 157 ip link set dev $swp3.111 master br111 158 defer ip link set dev $swp3.111 nomaster 159 160 ip link add name br222 type bridge vlan_filtering 0 161 defer ip link del dev br222 162 ip link set dev br222 addrgenmode none 163 164 ip link set dev br222 up 165 defer ip link set dev br222 down 166 167 ip link set dev $swp2.222 master br222 168 defer ip link set dev $swp2.222 nomaster 169 170 ip link set dev $swp3.222 master br222 171 defer ip link set dev $swp3.222 nomaster 172 173 # Make sure that ingress quotas are smaller than egress so that there is 174 # room for both streams of traffic to be admitted to shared buffer. 175 devlink_pool_size_thtype_save 0 176 devlink_pool_size_thtype_set 0 dynamic 10000000 177 defer devlink_pool_size_thtype_restore 0 178 179 devlink_pool_size_thtype_save 4 180 devlink_pool_size_thtype_set 4 dynamic 10000000 181 defer devlink_pool_size_thtype_restore 4 182 183 devlink_port_pool_th_save $swp1 0 184 devlink_port_pool_th_set $swp1 0 6 185 defer devlink_port_pool_th_restore $swp1 0 186 187 devlink_tc_bind_pool_th_save $swp1 1 ingress 188 devlink_tc_bind_pool_th_set $swp1 1 ingress 0 6 189 defer devlink_tc_bind_pool_th_restore $swp1 1 ingress 190 191 devlink_port_pool_th_save $swp2 0 192 devlink_port_pool_th_set $swp2 0 6 193 defer devlink_port_pool_th_restore $swp2 0 194 195 devlink_tc_bind_pool_th_save $swp2 2 ingress 196 devlink_tc_bind_pool_th_set $swp2 2 ingress 0 6 197 defer devlink_tc_bind_pool_th_restore $swp2 2 ingress 198 199 devlink_tc_bind_pool_th_save $swp3 1 egress 200 devlink_tc_bind_pool_th_set $swp3 1 egress 4 7 201 defer devlink_tc_bind_pool_th_restore $swp3 1 egress 202 203 devlink_tc_bind_pool_th_save $swp3 2 egress 204 devlink_tc_bind_pool_th_set $swp3 2 egress 4 7 205 defer devlink_tc_bind_pool_th_restore $swp3 2 egress 206 207 devlink_port_pool_th_save $swp3 4 208 devlink_port_pool_th_set $swp3 4 7 209 defer devlink_port_pool_th_restore $swp3 4 210} 211 212setup_prepare() 213{ 214 h1=${NETIFS[p1]} 215 swp1=${NETIFS[p2]} 216 217 swp2=${NETIFS[p3]} 218 h2=${NETIFS[p4]} 219 220 swp3=${NETIFS[p5]} 221 h3=${NETIFS[p6]} 222 223 h3mac=$(mac_get $h3) 224 225 adf_vrf_prepare 226 227 h1_create 228 h2_create 229 h3_create 230 switch_create 231} 232 233ping_ipv4() 234{ 235 ping_test $h1 192.0.2.34 " from H1" 236 ping_test $h2 192.0.2.66 " from H2" 237} 238 239rel() 240{ 241 local old=$1; shift 242 local new=$1; shift 243 244 bc <<< " 245 scale=2 246 ret = 100 * $new / $old 247 if (ret > 0) { ret } else { 0 } 248 " 249} 250 251__run_hi_measure_rate() 252{ 253 local what=$1; shift 254 local -a uc_rate 255 256 start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac 257 defer stop_traffic $! 258 259 uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_2 "$what")) 260 check_err $? "Could not get high enough $what ingress rate" 261 262 echo ${uc_rate[@]} 263} 264 265run_hi_measure_rate() 266{ 267 in_defer_scope __run_hi_measure_rate "$@" 268} 269 270test_ets_strict() 271{ 272 RET=0 273 274 # Run high-prio traffic on its own. 275 local -a rate_2 276 rate_2=($(run_hi_measure_rate "prio 2")) 277 local rate_2_in=${rate_2[0]} 278 local rate_2_eg=${rate_2[1]} 279 280 # Start low-prio stream. 281 start_traffic $h1.111 192.0.2.33 192.0.2.34 $h3mac 282 defer stop_traffic $! 283 284 local -a rate_1 285 rate_1=($(measure_rate $swp1 $h3 rx_octets_prio_1 "prio 1")) 286 check_err $? "Could not get high enough prio-1 ingress rate" 287 local rate_1_in=${rate_1[0]} 288 local rate_1_eg=${rate_1[1]} 289 290 # High-prio and low-prio on their own should have about the same 291 # throughput. 292 local rel21=$(rel $rate_1_eg $rate_2_eg) 293 check_err $(bc <<< "$rel21 < 95") 294 check_err $(bc <<< "$rel21 > 105") 295 296 # Start the high-prio stream--now both streams run. 297 rate_3=($(run_hi_measure_rate "prio 2+1")) 298 local rate_3_in=${rate_3[0]} 299 local rate_3_eg=${rate_3[1]} 300 301 # High-prio should have about the same throughput whether or not 302 # low-prio is in the system. 303 local rel32=$(rel $rate_2_eg $rate_3_eg) 304 check_err $(bc <<< "$rel32 < 95") 305 306 log_test "strict priority" 307 echo "Ingress to switch:" 308 echo " p1 in rate $(humanize $rate_1_in)" 309 echo " p2 in rate $(humanize $rate_2_in)" 310 echo " p2 in rate w/ p1 $(humanize $rate_3_in)" 311 echo "Egress from switch:" 312 echo " p1 eg rate $(humanize $rate_1_eg)" 313 echo " p2 eg rate $(humanize $rate_2_eg) ($rel21% of p1)" 314 echo " p2 eg rate w/ p1 $(humanize $rate_3_eg) ($rel32% of p2)" 315} 316 317trap cleanup EXIT 318 319setup_prepare 320setup_wait 321 322tests_run 323 324exit $EXIT_STATUS 325