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 simple_if_init $h1 61 defer simple_if_fini $h1 62 63 mtu_set $h1 10000 64 defer mtu_restore $h1 65 66 vlan_create $h1 111 v$h1 192.0.2.33/28 67 defer vlan_destroy $h1 111 68 ip link set dev $h1.111 type vlan egress-qos-map 0:1 69} 70 71h2_create() 72{ 73 simple_if_init $h2 74 defer simple_if_fini $h2 75 76 mtu_set $h2 10000 77 defer mtu_restore $h2 78 79 vlan_create $h2 222 v$h2 192.0.2.65/28 80 defer vlan_destroy $h2 222 81 ip link set dev $h2.222 type vlan egress-qos-map 0:2 82} 83 84h3_create() 85{ 86 simple_if_init $h3 87 defer simple_if_fini $h3 88 89 mtu_set $h3 10000 90 defer mtu_restore $h3 91 92 vlan_create $h3 111 v$h3 192.0.2.34/28 93 defer vlan_destroy $h3 111 94 95 vlan_create $h3 222 v$h3 192.0.2.66/28 96 defer vlan_destroy $h3 222 97} 98 99switch_create() 100{ 101 ip link set dev $swp1 up 102 defer ip link set dev $swp1 down 103 104 mtu_set $swp1 10000 105 defer mtu_restore $swp1 106 107 ip link set dev $swp2 up 108 defer ip link set dev $swp2 down 109 110 mtu_set $swp2 10000 111 defer mtu_restore $swp2 112 113 # prio n -> TC n, strict scheduling 114 lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7 115 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 116 117 lldptool -T -i $swp3 -V ETS-CFG tsa=$( 118 )"0:strict,"$( 119 )"1:strict,"$( 120 )"2:strict,"$( 121 )"3:strict,"$( 122 )"4:strict,"$( 123 )"5:strict,"$( 124 )"6:strict,"$( 125 )"7:strict" 126 sleep 1 127 128 ip link set dev $swp3 up 129 defer ip link set dev $swp3 down 130 131 mtu_set $swp3 10000 132 defer mtu_restore $swp3 133 134 tc qdisc replace dev $swp3 root handle 101: tbf rate 1gbit \ 135 burst 128K limit 1G 136 defer tc qdisc del dev $swp3 root handle 101: 137 138 vlan_create $swp1 111 139 defer vlan_destroy $swp1 111 140 141 vlan_create $swp2 222 142 defer vlan_destroy $swp2 222 143 144 vlan_create $swp3 111 145 defer vlan_destroy $swp3 111 146 147 vlan_create $swp3 222 148 defer vlan_destroy $swp3 222 149 150 ip link add name br111 type bridge vlan_filtering 0 151 defer ip link del dev br111 152 ip link set dev br111 addrgenmode none 153 154 ip link set dev br111 up 155 defer ip link set dev br111 down 156 157 ip link set dev $swp1.111 master br111 158 defer ip link set dev $swp1.111 nomaster 159 160 ip link set dev $swp3.111 master br111 161 defer ip link set dev $swp3.111 nomaster 162 163 ip link add name br222 type bridge vlan_filtering 0 164 defer ip link del dev br222 165 ip link set dev br222 addrgenmode none 166 167 ip link set dev br222 up 168 defer ip link set dev br222 down 169 170 ip link set dev $swp2.222 master br222 171 defer ip link set dev $swp2.222 nomaster 172 173 ip link set dev $swp3.222 master br222 174 defer ip link set dev $swp3.222 nomaster 175 176 # Make sure that ingress quotas are smaller than egress so that there is 177 # room for both streams of traffic to be admitted to shared buffer. 178 devlink_pool_size_thtype_save 0 179 devlink_pool_size_thtype_set 0 dynamic 10000000 180 defer devlink_pool_size_thtype_restore 0 181 182 devlink_pool_size_thtype_save 4 183 devlink_pool_size_thtype_set 4 dynamic 10000000 184 defer devlink_pool_size_thtype_restore 4 185 186 devlink_port_pool_th_save $swp1 0 187 devlink_port_pool_th_set $swp1 0 6 188 defer devlink_port_pool_th_restore $swp1 0 189 190 devlink_tc_bind_pool_th_save $swp1 1 ingress 191 devlink_tc_bind_pool_th_set $swp1 1 ingress 0 6 192 defer devlink_tc_bind_pool_th_restore $swp1 1 ingress 193 194 devlink_port_pool_th_save $swp2 0 195 devlink_port_pool_th_set $swp2 0 6 196 defer devlink_port_pool_th_restore $swp2 0 197 198 devlink_tc_bind_pool_th_save $swp2 2 ingress 199 devlink_tc_bind_pool_th_set $swp2 2 ingress 0 6 200 defer devlink_tc_bind_pool_th_restore $swp2 2 ingress 201 202 devlink_tc_bind_pool_th_save $swp3 1 egress 203 devlink_tc_bind_pool_th_set $swp3 1 egress 4 7 204 defer devlink_tc_bind_pool_th_restore $swp3 1 egress 205 206 devlink_tc_bind_pool_th_save $swp3 2 egress 207 devlink_tc_bind_pool_th_set $swp3 2 egress 4 7 208 defer devlink_tc_bind_pool_th_restore $swp3 2 egress 209 210 devlink_port_pool_th_save $swp3 4 211 devlink_port_pool_th_set $swp3 4 7 212 defer devlink_port_pool_th_restore $swp3 4 213} 214 215setup_prepare() 216{ 217 h1=${NETIFS[p1]} 218 swp1=${NETIFS[p2]} 219 220 swp2=${NETIFS[p3]} 221 h2=${NETIFS[p4]} 222 223 swp3=${NETIFS[p5]} 224 h3=${NETIFS[p6]} 225 226 h3mac=$(mac_get $h3) 227 228 vrf_prepare 229 defer vrf_cleanup 230 231 h1_create 232 h2_create 233 h3_create 234 switch_create 235} 236 237ping_ipv4() 238{ 239 ping_test $h1 192.0.2.34 " from H1" 240 ping_test $h2 192.0.2.66 " from H2" 241} 242 243rel() 244{ 245 local old=$1; shift 246 local new=$1; shift 247 248 bc <<< " 249 scale=2 250 ret = 100 * $new / $old 251 if (ret > 0) { ret } else { 0 } 252 " 253} 254 255__run_hi_measure_rate() 256{ 257 local what=$1; shift 258 local -a uc_rate 259 260 start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac 261 defer stop_traffic $! 262 263 uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_2 "$what")) 264 check_err $? "Could not get high enough $what ingress rate" 265 266 echo ${uc_rate[@]} 267} 268 269run_hi_measure_rate() 270{ 271 in_defer_scope __run_hi_measure_rate "$@" 272} 273 274test_ets_strict() 275{ 276 RET=0 277 278 # Run high-prio traffic on its own. 279 local -a rate_2 280 rate_2=($(run_hi_measure_rate "prio 2")) 281 local rate_2_in=${rate_2[0]} 282 local rate_2_eg=${rate_2[1]} 283 284 # Start low-prio stream. 285 start_traffic $h1.111 192.0.2.33 192.0.2.34 $h3mac 286 defer stop_traffic $! 287 288 local -a rate_1 289 rate_1=($(measure_rate $swp1 $h3 rx_octets_prio_1 "prio 1")) 290 check_err $? "Could not get high enough prio-1 ingress rate" 291 local rate_1_in=${rate_1[0]} 292 local rate_1_eg=${rate_1[1]} 293 294 # High-prio and low-prio on their own should have about the same 295 # throughput. 296 local rel21=$(rel $rate_1_eg $rate_2_eg) 297 check_err $(bc <<< "$rel21 < 95") 298 check_err $(bc <<< "$rel21 > 105") 299 300 # Start the high-prio stream--now both streams run. 301 rate_3=($(run_hi_measure_rate "prio 2+1")) 302 local rate_3_in=${rate_3[0]} 303 local rate_3_eg=${rate_3[1]} 304 305 # High-prio should have about the same throughput whether or not 306 # low-prio is in the system. 307 local rel32=$(rel $rate_2_eg $rate_3_eg) 308 check_err $(bc <<< "$rel32 < 95") 309 310 log_test "strict priority" 311 echo "Ingress to switch:" 312 echo " p1 in rate $(humanize $rate_1_in)" 313 echo " p2 in rate $(humanize $rate_2_in)" 314 echo " p2 in rate w/ p1 $(humanize $rate_3_in)" 315 echo "Egress from switch:" 316 echo " p1 eg rate $(humanize $rate_1_eg)" 317 echo " p2 eg rate $(humanize $rate_2_eg) ($rel21% of p1)" 318 echo " p2 eg rate w/ p1 $(humanize $rate_3_eg) ($rel32% of p2)" 319} 320 321trap cleanup EXIT 322 323setup_prepare 324setup_wait 325 326tests_run 327 328exit $EXIT_STATUS 329