1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for "tc action mirred egress mirror" when the underlay route points at a
5# team device.
6#
7# +----------------------+                             +----------------------+
8# | H1                   |                             |                   H2 |
9# |    + $h1.333         |                             |        $h1.555 +     |
10# |    | 192.0.2.1/28    |                             |  192.0.2.18/28 |     |
11# +----|-----------------+                             +----------------|-----+
12#      |                                $h1                             |
13#      +---------------------------------+------------------------------+
14#                                        |
15# +--------------------------------------|------------------------------------+
16# | SW                                   o---> mirror                         |
17# |                                      |                                    |
18# |   +----------------------------------+------------------------------+     |
19# |   |                                $swp1                            |     |
20# |   + $swp1.333                                             $swp1.555 +     |
21# |     192.0.2.2/28                                      192.0.2.17/28       |
22# |                                                                           |
23# |                                                                           |
24# |   + gt4 (gretap)      ,-> + lag1 (team)                                   |
25# |     loc=192.0.2.129   |   | 192.0.2.129/28                                |
26# |     rem=192.0.2.130 --'   |                                               |
27# |     ttl=100               |                                               |
28# |     tos=inherit           |                                               |
29# |      _____________________|______________________                         |
30# |     /                                            \                        |
31# |    /                                              \                       |
32# |   + $swp3                                          + $swp4                |
33# +---|------------------------------------------------|----------------------+
34#     |                                                |
35# +---|------------------------------------------------|----------------------+
36# |   + $h3                                            + $h4               H3 |
37# |    \                                              /                       |
38# |     \____________________________________________/                        |
39# |                           |                                               |
40# |                           + lag2 (team)                                   |
41# |                             192.0.2.130/28                                |
42# |                                                                           |
43# +---------------------------------------------------------------------------+
44
45ALL_TESTS="
46	test_mirror_gretap_first
47	test_mirror_gretap_second
48"
49
50NUM_NETIFS=6
51source lib.sh
52source mirror_lib.sh
53source mirror_gre_lib.sh
54
55require_command $ARPING
56
57vlan_host_create()
58{
59	local if_name=$1; shift
60	local vid=$1; shift
61	local vrf_name=$1; shift
62	local ips=("${@}")
63
64	vrf_create $vrf_name
65	ip link set dev $vrf_name up
66	vlan_create $if_name $vid $vrf_name "${ips[@]}"
67}
68
69vlan_host_destroy()
70{
71	local if_name=$1; shift
72	local vid=$1; shift
73	local vrf_name=$1; shift
74
75	vlan_destroy $if_name $vid
76	ip link set dev $vrf_name down
77	vrf_destroy $vrf_name
78}
79
80h1_create()
81{
82	vlan_host_create $h1 333 vrf-h1 192.0.2.1/28
83	ip -4 route add 192.0.2.16/28 vrf vrf-h1 nexthop via 192.0.2.2
84}
85
86h1_destroy()
87{
88	ip -4 route del 192.0.2.16/28 vrf vrf-h1
89	vlan_host_destroy $h1 333 vrf-h1
90}
91
92h2_create()
93{
94	vlan_host_create $h1 555 vrf-h2 192.0.2.18/28
95	ip -4 route add 192.0.2.0/28 vrf vrf-h2 nexthop via 192.0.2.17
96}
97
98h2_destroy()
99{
100	ip -4 route del 192.0.2.0/28 vrf vrf-h2
101	vlan_host_destroy $h1 555 vrf-h2
102}
103
104h3_create_team()
105{
106	team_create lag2 lacp $h3 $h4
107	__simple_if_init lag2 vrf-h3 192.0.2.130/32
108	ip -4 route add vrf vrf-h3 192.0.2.129/32 dev lag2
109}
110
111h3_destroy_team()
112{
113	ip -4 route del vrf vrf-h3 192.0.2.129/32 dev lag2
114	__simple_if_fini lag2 192.0.2.130/32
115	team_destroy lag2
116
117	ip link set dev $h3 down
118	ip link set dev $h4 down
119}
120
121h3_create()
122{
123	vrf_create vrf-h3
124	ip link set dev vrf-h3 up
125	tc qdisc add dev $h3 clsact
126	tc qdisc add dev $h4 clsact
127	h3_create_team
128}
129
130h3_destroy()
131{
132	h3_destroy_team
133	tc qdisc del dev $h4 clsact
134	tc qdisc del dev $h3 clsact
135	ip link set dev vrf-h3 down
136	vrf_destroy vrf-h3
137}
138
139switch_create()
140{
141	ip link set dev $swp1 up
142	tc qdisc add dev $swp1 clsact
143	vlan_create $swp1 333 "" 192.0.2.2/28
144	vlan_create $swp1 555 "" 192.0.2.17/28
145
146	tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \
147		      ttl 100 tos inherit
148
149	ip link set dev $swp3 up
150	ip link set dev $swp4 up
151	team_create lag1 lacp $swp3 $swp4
152	__addr_add_del lag1 add 192.0.2.129/32
153	ip -4 route add 192.0.2.130/32 dev lag1
154}
155
156switch_destroy()
157{
158	ip -4 route del 192.0.2.130/32 dev lag1
159	__addr_add_del lag1 del 192.0.2.129/32
160	team_destroy lag1
161
162	ip link set dev $swp4 down
163	ip link set dev $swp3 down
164
165	tunnel_destroy gt4
166
167	vlan_destroy $swp1 555
168	vlan_destroy $swp1 333
169	tc qdisc del dev $swp1 clsact
170	ip link set dev $swp1 down
171}
172
173setup_prepare()
174{
175	h1=${NETIFS[p1]}
176	swp1=${NETIFS[p2]}
177
178	swp3=${NETIFS[p3]}
179	h3=${NETIFS[p4]}
180
181	swp4=${NETIFS[p5]}
182	h4=${NETIFS[p6]}
183
184	vrf_prepare
185
186	ip link set dev $h1 up
187	h1_create
188	h2_create
189	h3_create
190	switch_create
191
192	trap_install $h3 ingress
193	trap_install $h4 ingress
194}
195
196cleanup()
197{
198	pre_cleanup
199
200	trap_uninstall $h4 ingress
201	trap_uninstall $h3 ingress
202
203	switch_destroy
204	h3_destroy
205	h2_destroy
206	h1_destroy
207	ip link set dev $h1 down
208
209	vrf_cleanup
210}
211
212test_lag_slave()
213{
214	local up_dev=$1; shift
215	local down_dev=$1; shift
216	local what=$1; shift
217
218	RET=0
219
220	mirror_install $swp1 ingress gt4 \
221		       "proto 802.1q flower vlan_id 333 $tcflags"
222
223	# Move $down_dev away from the team. That will prompt change in
224	# txability of the connected device, without changing its upness. The
225	# driver should notice the txability change and move the traffic to the
226	# other slave.
227	ip link set dev $down_dev nomaster
228	sleep 2
229	mirror_test vrf-h1 192.0.2.1 192.0.2.18 $up_dev 1 10
230
231	# Test lack of connectivity when neither slave is txable.
232	ip link set dev $up_dev nomaster
233	sleep 2
234	mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h3 1 0
235	mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h4 1 0
236	mirror_uninstall $swp1 ingress
237
238	# Recreate H3's team device, because mlxsw, which this test is
239	# predominantly mean to test, requires a bottom-up construction and
240	# doesn't allow enslavement to a device that already has an upper.
241	h3_destroy_team
242	h3_create_team
243	# Wait for ${h,swp}{3,4}.
244	setup_wait
245
246	log_test "$what ($tcflags)"
247}
248
249test_mirror_gretap_first()
250{
251	test_lag_slave $h3 $h4 "mirror to gretap: LAG first slave"
252}
253
254test_mirror_gretap_second()
255{
256	test_lag_slave $h4 $h3 "mirror to gretap: LAG second slave"
257}
258
259test_all()
260{
261	slow_path_trap_install $swp1 ingress
262	slow_path_trap_install $swp1 egress
263
264	tests_run
265
266	slow_path_trap_uninstall $swp1 egress
267	slow_path_trap_uninstall $swp1 ingress
268}
269
270trap cleanup EXIT
271
272setup_prepare
273setup_wait
274
275tcflags="skip_hw"
276test_all
277
278if ! tc_offload_check; then
279	echo "WARN: Could not test offloaded functionality"
280else
281	tcflags="skip_sw"
282	test_all
283fi
284
285exit $EXIT_STATUS
286