xref: /linux/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh (revision cdd30ebb1b9f36159d66f088b61aee264e649d7a)
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