1# SPDX-License-Identifier: GPL-2.0
2
3# This test sends a stream of traffic from H1 through a switch, to H2. On the
4# egress port from the switch ($swp2), a shaper is installed. The test verifies
5# that the rates on the port match the configured shaper.
6#
7# In order to test per-class shaping, $swp2 actually contains TBF under PRIO or
8# ETS, with two different configurations. Traffic is prioritized using 802.1p.
9#
10# +-------------------------------------------+
11# | H1                                        |
12# |     + $h1.10                  $h1.11 +    |
13# |     | 192.0.2.1/28     192.0.2.17/28 |    |
14# |     |                                |    |
15# |     \______________    _____________/     |
16# |                    \ /                    |
17# |                     + $h1                 |
18# +---------------------|---------------------+
19#                       |
20# +---------------------|---------------------+
21# | SW                  + $swp1               |
22# |     _______________/ \_______________     |
23# |    /                                 \    |
24# |  +-|--------------+   +--------------|-+  |
25# |  | + $swp1.10     |   |     $swp1.11 + |  |
26# |  |                |   |                |  |
27# |  |     BR10       |   |       BR11     |  |
28# |  |                |   |                |  |
29# |  | + $swp2.10     |   |     $swp2.11 + |  |
30# |  +-|--------------+   +--------------|-+  |
31# |    \_______________   ______________/     |
32# |                    \ /                    |
33# |                     + $swp2               |
34# +---------------------|---------------------+
35#                       |
36# +---------------------|---------------------+
37# | H2                  + $h2                 |
38# |      ______________/ \______________      |
39# |     /                               \     |
40# |     |                               |     |
41# |     + $h2.10                 $h2.11 +     |
42# |       192.0.2.2/28    192.0.2.18/28       |
43# +-------------------------------------------+
44
45NUM_NETIFS=4
46CHECK_TC="yes"
47source $lib_dir/lib.sh
48
49ipaddr()
50{
51	local host=$1; shift
52	local vlan=$1; shift
53
54	echo 192.0.2.$((16 * (vlan - 10) + host))
55}
56
57host_create()
58{
59	local dev=$1; shift
60	local host=$1; shift
61
62	simple_if_init $dev
63	mtu_set $dev 10000
64
65	vlan_create $dev 10 v$dev $(ipaddr $host 10)/28
66	ip link set dev $dev.10 type vlan egress 0:0
67
68	vlan_create $dev 11 v$dev $(ipaddr $host 11)/28
69	ip link set dev $dev.11 type vlan egress 0:1
70}
71
72host_destroy()
73{
74	local dev=$1; shift
75
76	vlan_destroy $dev 11
77	vlan_destroy $dev 10
78	mtu_restore $dev
79	simple_if_fini $dev
80}
81
82h1_create()
83{
84	host_create $h1 1
85}
86
87h1_destroy()
88{
89	host_destroy $h1
90}
91
92h2_create()
93{
94	host_create $h2 2
95
96	tc qdisc add dev $h2 clsact
97	tc filter add dev $h2 ingress pref 1010 prot 802.1q \
98	   flower $TCFLAGS vlan_id 10 action pass
99	tc filter add dev $h2 ingress pref 1011 prot 802.1q \
100	   flower $TCFLAGS vlan_id 11 action pass
101}
102
103h2_destroy()
104{
105	tc qdisc del dev $h2 clsact
106	host_destroy $h2
107}
108
109switch_create()
110{
111	local intf
112	local vlan
113
114	ip link add dev br10 type bridge
115	ip link add dev br11 type bridge
116
117	for intf in $swp1 $swp2; do
118		ip link set dev $intf up
119		mtu_set $intf 10000
120
121		for vlan in 10 11; do
122			vlan_create $intf $vlan
123			ip link set dev $intf.$vlan master br$vlan
124			ip link set dev $intf.$vlan up
125		done
126	done
127
128	for vlan in 10 11; do
129		ip link set dev $swp1.$vlan type vlan ingress 0:0 1:1
130	done
131
132	ip link set dev br10 up
133	ip link set dev br11 up
134}
135
136switch_destroy()
137{
138	local intf
139	local vlan
140
141	# A test may have been interrupted mid-run, with Qdisc installed. Delete
142	# it here.
143	tc qdisc del dev $swp2 root 2>/dev/null
144
145	ip link set dev br11 down
146	ip link set dev br10 down
147
148	for intf in $swp2 $swp1; do
149		for vlan in 11 10; do
150			ip link set dev $intf.$vlan down
151			ip link set dev $intf.$vlan nomaster
152			vlan_destroy $intf $vlan
153		done
154
155		mtu_restore $intf
156		ip link set dev $intf down
157	done
158
159	ip link del dev br11
160	ip link del dev br10
161}
162
163setup_prepare()
164{
165	h1=${NETIFS[p1]}
166	swp1=${NETIFS[p2]}
167
168	swp2=${NETIFS[p3]}
169	h2=${NETIFS[p4]}
170
171	swp3=${NETIFS[p5]}
172	h3=${NETIFS[p6]}
173
174	swp4=${NETIFS[p7]}
175	swp5=${NETIFS[p8]}
176
177	h2_mac=$(mac_get $h2)
178
179	vrf_prepare
180
181	h1_create
182	h2_create
183	switch_create
184}
185
186cleanup()
187{
188	pre_cleanup
189
190	switch_destroy
191	h2_destroy
192	h1_destroy
193
194	vrf_cleanup
195}
196
197ping_ipv4()
198{
199	ping_test $h1.10 $(ipaddr 2 10) " vlan 10"
200	ping_test $h1.11 $(ipaddr 2 11) " vlan 11"
201}
202
203tbf_get_counter()
204{
205	local vlan=$1; shift
206
207	tc_rule_stats_get $h2 10$vlan ingress .bytes
208}
209
210do_tbf_test()
211{
212	local vlan=$1; shift
213	local mbit=$1; shift
214
215	start_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 2 $vlan) $h2_mac
216	sleep 5 # Wait for the burst to dwindle
217
218	local t2=$(busywait_for_counter 1000 +1 tbf_get_counter $vlan)
219	sleep 10
220	local t3=$(tbf_get_counter $vlan)
221	stop_traffic
222
223	RET=0
224
225	# Note: TBF uses 10^6 Mbits, not 2^20 ones.
226	local er=$((mbit * 1000 * 1000))
227	local nr=$(rate $t2 $t3 10)
228	local nr_pct=$((100 * (nr - er) / er))
229	((-5 <= nr_pct && nr_pct <= 5))
230	check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-5%."
231
232	log_test "TC $((vlan - 10)): TBF rate ${mbit}Mbit"
233}
234