xref: /linux/tools/testing/selftests/net/forwarding/sch_ets_core.sh (revision c34e9ab9a612ee8b18273398ef75c207b01f516d)
1# SPDX-License-Identifier: GPL-2.0
2
3# This is a template for ETS Qdisc test.
4#
5# This test sends from H1 several traffic streams with 802.1p-tagged packets.
6# The tags are used at $swp1 to prioritize the traffic. Each stream is then
7# queued at a different ETS band according to the assigned priority. After
8# runnig for a while, counters at H2 are consulted to determine whether the
9# traffic scheduling was according to the ETS configuration.
10#
11# This template is supposed to be embedded by a test driver, which implements
12# statistics collection, any HW-specific stuff, and prominently configures the
13# system to assure that there is overcommitment at $swp2. That is necessary so
14# that the ETS traffic selection algorithm kicks in and has to schedule some
15# traffic at the expense of other.
16#
17# A driver for veth-based testing is in sch_ets.sh, an example of a driver for
18# an offloaded data path is in selftests/drivers/net/mlxsw/sch_ets.sh.
19#
20# +---------------------------------------------------------------------+
21# | H1                                                                  |
22# |     + $h1.10              + $h1.11              + $h1.12            |
23# |     | 192.0.2.1/28        | 192.0.2.17/28       | 192.0.2.33/28     |
24# |     | egress-qos-map      | egress-qos-map      | egress-qos-map    |
25# |     |  0:0                |  0:1                |  0:2              |
26# |     \____________________ | ____________________/                   |
27# |                          \|/                                        |
28# |                           + $h1                                     |
29# +---------------------------|-----------------------------------------+
30#                             |
31# +---------------------------|-----------------------------------------+
32# | SW                        + $swp1                                   |
33# |                           | >1Gbps                                  |
34# |      ____________________/|\____________________                    |
35# |     /                     |                     \                   |
36# |  +--|----------------+ +--|----------------+ +--|----------------+  |
37# |  |  + $swp1.10       | |  + $swp1.11       | |  + $swp1.12       |  |
38# |  |    ingress-qos-map| |    ingress-qos-map| |    ingress-qos-map|  |
39# |  |     0:0 1:1 2:2   | |     0:0 1:1 2:2   | |     0:0 1:1 2:2   |  |
40# |  |                   | |                   | |                   |  |
41# |  |    BR10           | |    BR11           | |    BR12           |  |
42# |  |                   | |                   | |                   |  |
43# |  |  + $swp2.10       | |  + $swp2.11       | |  + $swp2.12       |  |
44# |  +--|----------------+ +--|----------------+ +--|----------------+  |
45# |     \____________________ | ____________________/                   |
46# |                          \|/                                        |
47# |                           + $swp2                                   |
48# |                           | 1Gbps (ethtool or HTB qdisc)            |
49# |                           | qdisc ets quanta $W0 $W1 $W2            |
50# |                           |           priomap 0 1 2                 |
51# +---------------------------|-----------------------------------------+
52#                             |
53# +---------------------------|-----------------------------------------+
54# | H2                        + $h2                                     |
55# |      ____________________/|\____________________                    |
56# |     /                     |                     \                   |
57# |     + $h2.10              + $h2.11              + $h2.12            |
58# |       192.0.2.2/28          192.0.2.18/28         192.0.2.34/28     |
59# +---------------------------------------------------------------------+
60
61NUM_NETIFS=4
62CHECK_TC=yes
63source $lib_dir/lib.sh
64source $lib_dir/sch_ets_tests.sh
65
66PARENT=root
67QDISC_DEV=
68
69sip()
70{
71	echo 192.0.2.$((16 * $1 + 1))
72}
73
74dip()
75{
76	echo 192.0.2.$((16 * $1 + 2))
77}
78
79# Callback from sch_ets_tests.sh
80ets_start_traffic()
81{
82	local dst_mac=$(mac_get $h2)
83	local i=$1; shift
84
85	start_traffic $h1.1$i $(sip $i) $(dip $i) $dst_mac
86}
87
88ETS_CHANGE_QDISC=
89
90priomap_mode()
91{
92	echo "Running in priomap mode"
93	ets_delete_qdisc
94	ETS_CHANGE_QDISC=ets_change_qdisc_priomap
95}
96
97classifier_mode()
98{
99	echo "Running in classifier mode"
100	ets_delete_qdisc
101	ETS_CHANGE_QDISC=ets_change_qdisc_classifier
102}
103
104ets_change_qdisc_priomap()
105{
106	local dev=$1; shift
107	local nstrict=$1; shift
108	local priomap=$1; shift
109	local quanta=("${@}")
110
111	local op=$(if [[ -n $QDISC_DEV ]]; then echo change; else echo add; fi)
112
113	tc qdisc $op dev $dev $PARENT handle 10: ets			       \
114		$(if ((nstrict)); then echo strict $nstrict; fi)	       \
115		$(if ((${#quanta[@]})); then echo quanta ${quanta[@]}; fi)     \
116		priomap $priomap
117	QDISC_DEV=$dev
118}
119
120ets_change_qdisc_classifier()
121{
122	local dev=$1; shift
123	local nstrict=$1; shift
124	local priomap=$1; shift
125	local quanta=("${@}")
126
127	local op=$(if [[ -n $QDISC_DEV ]]; then echo change; else echo add; fi)
128
129	tc qdisc $op dev $dev $PARENT handle 10: ets			       \
130		$(if ((nstrict)); then echo strict $nstrict; fi)	       \
131		$(if ((${#quanta[@]})); then echo quanta ${quanta[@]}; fi)
132
133	if [[ $op == add ]]; then
134		local prio=0
135		local band
136
137		for band in $priomap; do
138			tc filter add dev $dev parent 10: basic \
139				match "meta(priority eq $prio)" \
140				flowid 10:$((band + 1))
141			((prio++))
142		done
143	fi
144	QDISC_DEV=$dev
145}
146
147# Callback from sch_ets_tests.sh
148ets_change_qdisc()
149{
150	if [[ -z "$ETS_CHANGE_QDISC" ]]; then
151		exit 1
152	fi
153	$ETS_CHANGE_QDISC "$@"
154}
155
156ets_delete_qdisc()
157{
158	if [[ -n $QDISC_DEV ]]; then
159		tc qdisc del dev $QDISC_DEV $PARENT
160		QDISC_DEV=
161	fi
162}
163
164h1_create()
165{
166	local i;
167
168	simple_if_init $h1
169	defer simple_if_fini $h1
170
171	mtu_set $h1 9900
172	defer mtu_restore $h1
173
174	for i in {0..2}; do
175		vlan_create $h1 1$i v$h1 $(sip $i)/28
176		defer vlan_destroy $h1 1$i
177		ip link set dev $h1.1$i type vlan egress 0:$i
178	done
179}
180
181h2_create()
182{
183	local i
184
185	simple_if_init $h2
186	defer simple_if_fini $h2
187
188	mtu_set $h2 9900
189	defer mtu_restore $h2
190
191	for i in {0..2}; do
192		vlan_create $h2 1$i v$h2 $(dip $i)/28
193		defer vlan_destroy $h2 1$i
194	done
195}
196
197ets_switch_create()
198{
199	local i
200
201	ip link set dev $swp1 up
202	defer ip link set dev $swp1 down
203
204	mtu_set $swp1 9900
205	defer mtu_restore $swp1
206
207	ip link set dev $swp2 up
208	defer ip link set dev $swp2 down
209
210	mtu_set $swp2 9900
211	defer mtu_restore $swp2
212
213	for i in {0..2}; do
214		vlan_create $swp1 1$i
215		defer vlan_destroy $swp1 1$i
216		ip link set dev $swp1.1$i type vlan ingress 0:0 1:1 2:2
217
218		vlan_create $swp2 1$i
219		defer vlan_destroy $swp2 1$i
220
221		ip link add dev br1$i type bridge
222		defer ip link del dev br1$i
223
224		ip link set dev $swp1.1$i master br1$i
225		defer ip link set dev $swp1.1$i nomaster
226
227		ip link set dev $swp2.1$i master br1$i
228		defer ip link set dev $swp2.1$i nomaster
229
230		ip link set dev br1$i up
231		defer ip link set dev br1$i down
232
233		ip link set dev $swp1.1$i up
234		defer ip link set dev $swp1.1$i down
235
236		ip link set dev $swp2.1$i up
237		defer ip link set dev $swp2.1$i down
238	done
239
240	defer ets_delete_qdisc
241}
242
243setup_prepare()
244{
245	h1=${NETIFS[p1]}
246	swp1=${NETIFS[p2]}
247
248	swp2=${NETIFS[p3]}
249	h2=${NETIFS[p4]}
250
251	put=$swp2
252	hut=$h2
253
254	vrf_prepare
255	defer vrf_cleanup
256
257	h1_create
258	h2_create
259	switch_create
260}
261
262ping_ipv4()
263{
264	ping_test $h1.10 $(dip 0) " vlan 10"
265	ping_test $h1.11 $(dip 1) " vlan 11"
266	ping_test $h1.12 $(dip 2) " vlan 12"
267}
268
269ets_run()
270{
271	trap cleanup EXIT
272
273	setup_prepare
274	setup_wait
275
276	tests_run
277
278	exit $EXIT_STATUS
279}
280