xref: /linux/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test devlink-trap tunnel drops and exceptions functionality over mlxsw.
5# Check all traps to make sure they are triggered under the right
6# conditions.
7
8# +--------------------+
9# | H1 (vrf)           |
10# |    + $h1           |
11# |    | 192.0.2.1/28  |
12# +----|---------------+
13#      |
14# +----|----------------------------------------------------------------------+
15# | SW |                                                                      |
16# | +--|--------------------------------------------------------------------+ |
17# | |  + $swp1                   BR1 (802.1d)                               | |
18# | |                                                                       | |
19# | |  + vx1 (vxlan)                                                        | |
20# | |    local 192.0.2.17                                                   | |
21# | |    id 1000 dstport $VXPORT                                            | |
22# | +-----------------------------------------------------------------------+ |
23# |                                                                           |
24# |    + $rp1                                                                 |
25# |    | 192.0.2.17/28                                                        |
26# +----|----------------------------------------------------------------------+
27#      |
28# +----|--------------------------------------------------------+
29# |    |                                             VRF2       |
30# |    + $rp2                                                   |
31# |      192.0.2.18/28                                          |
32# |                                                             |
33# +-------------------------------------------------------------+
34
35lib_dir=$(dirname $0)/../../../net/forwarding
36
37ALL_TESTS="
38	decap_error_test
39	overlay_smac_is_mc_test
40"
41
42NUM_NETIFS=4
43source $lib_dir/lib.sh
44source $lib_dir/tc_common.sh
45source $lib_dir/devlink_lib.sh
46
47: ${VXPORT:=4789}
48export VXPORT
49
50h1_create()
51{
52	simple_if_init $h1 192.0.2.1/28
53}
54
55h1_destroy()
56{
57	simple_if_fini $h1 192.0.2.1/28
58}
59
60switch_create()
61{
62	ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0
63	# Make sure the bridge uses the MAC address of the local port and not
64	# that of the VxLAN's device.
65	ip link set dev br1 address $(mac_get $swp1)
66	ip link set dev br1 up
67
68	tc qdisc add dev $swp1 clsact
69	ip link set dev $swp1 master br1
70	ip link set dev $swp1 up
71
72	ip link add name vx1 type vxlan id 1000 local 192.0.2.17 \
73		dstport "$VXPORT" nolearning noudpcsum tos inherit ttl 100
74	ip link set dev vx1 master br1
75	ip link set dev vx1 up
76
77	ip address add dev $rp1 192.0.2.17/28
78	ip link set dev $rp1 up
79}
80
81switch_destroy()
82{
83	ip link set dev $rp1 down
84	ip address del dev $rp1 192.0.2.17/28
85
86	ip link set dev vx1 down
87	ip link set dev vx1 nomaster
88	ip link del dev vx1
89
90	ip link set dev $swp1 down
91	ip link set dev $swp1 nomaster
92	tc qdisc del dev $swp1 clsact
93
94	ip link set dev br1 down
95	ip link del dev br1
96}
97
98vrf2_create()
99{
100	simple_if_init $rp2 192.0.2.18/28
101}
102
103vrf2_destroy()
104{
105	simple_if_fini $rp2 192.0.2.18/28
106}
107
108setup_prepare()
109{
110	h1=${NETIFS[p1]}
111	swp1=${NETIFS[p2]}
112
113	rp1=${NETIFS[p3]}
114	rp2=${NETIFS[p4]}
115
116	vrf_prepare
117	forwarding_enable
118	h1_create
119	switch_create
120	vrf2_create
121}
122
123cleanup()
124{
125	pre_cleanup
126
127	vrf2_destroy
128	switch_destroy
129	h1_destroy
130	forwarding_restore
131	vrf_cleanup
132}
133
134ecn_payload_get()
135{
136	dest_mac=$(mac_get $h1)
137	p=$(:
138		)"08:"$(                      : VXLAN flags
139		)"00:00:00:"$(                : VXLAN reserved
140		)"00:03:e8:"$(                : VXLAN VNI : 1000
141		)"00:"$(                      : VXLAN reserved
142		)"$dest_mac:"$(               : ETH daddr
143		)"00:00:00:00:00:00:"$(       : ETH saddr
144		)"08:00:"$(                   : ETH type
145		)"45:"$(                      : IP version + IHL
146		)"00:"$(                      : IP TOS
147		)"00:14:"$(                   : IP total length
148		)"00:00:"$(                   : IP identification
149		)"20:00:"$(                   : IP flags + frag off
150		)"40:"$(                      : IP TTL
151		)"00:"$(                      : IP proto
152		)"D6:E5:"$(                   : IP header csum
153		)"c0:00:02:03:"$(             : IP saddr: 192.0.2.3
154		)"c0:00:02:01:"$(             : IP daddr: 192.0.2.1
155		)
156	echo $p
157}
158
159ecn_decap_test()
160{
161	local trap_name="decap_error"
162	local desc=$1; shift
163	local ecn_desc=$1; shift
164	local outer_tos=$1; shift
165	local mz_pid
166
167	RET=0
168
169	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
170		flower src_ip 192.0.2.3 dst_ip 192.0.2.1 action pass
171
172	rp1_mac=$(mac_get $rp1)
173	payload=$(ecn_payload_get)
174
175	ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac -B 192.0.2.17 \
176		-t udp sp=12345,dp=$VXPORT,tos=$outer_tos,p=$payload -q &
177	mz_pid=$!
178
179	devlink_trap_exception_test $trap_name
180
181	tc_check_packets "dev $swp1 egress" 101 0
182	check_err $? "Packets were not dropped"
183
184	log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc"
185
186	kill $mz_pid && wait $mz_pid &> /dev/null
187	tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
188}
189
190reserved_bits_payload_get()
191{
192	dest_mac=$(mac_get $h1)
193	p=$(:
194		)"08:"$(                      : VXLAN flags
195		)"01:00:00:"$(                : VXLAN reserved
196		)"00:03:e8:"$(                : VXLAN VNI : 1000
197		)"00:"$(                      : VXLAN reserved
198		)"$dest_mac:"$(               : ETH daddr
199		)"00:00:00:00:00:00:"$(       : ETH saddr
200		)"08:00:"$(                   : ETH type
201		)"45:"$(                      : IP version + IHL
202		)"00:"$(                      : IP TOS
203		)"00:14:"$(                   : IP total length
204		)"00:00:"$(                   : IP identification
205		)"20:00:"$(                   : IP flags + frag off
206		)"40:"$(                      : IP TTL
207		)"00:"$(                      : IP proto
208		)"00:00:"$(                   : IP header csum
209		)"c0:00:02:03:"$(             : IP saddr: 192.0.2.3
210		)"c0:00:02:01:"$(             : IP daddr: 192.0.2.1
211		)
212	echo $p
213}
214
215short_payload_get()
216{
217        dest_mac=$(mac_get $h1)
218        p=$(:
219		)"08:"$(                      : VXLAN flags
220		)"00:00:00:"$(                : VXLAN reserved
221		)"00:03:e8:"$(                : VXLAN VNI : 1000
222		)"00:"$(                      : VXLAN reserved
223		)"$dest_mac:"$(               : ETH daddr
224		)"00:00:00:00:00:00:"$(       : ETH saddr
225		)
226        echo $p
227}
228
229corrupted_packet_test()
230{
231	local trap_name="decap_error"
232	local desc=$1; shift
233	local payload_get=$1; shift
234	local mz_pid
235
236	RET=0
237
238	# In case of too short packet, there is no any inner packet,
239	# so the matching will always succeed
240	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
241		flower skip_hw src_ip 192.0.2.3 dst_ip 192.0.2.1 action pass
242
243	rp1_mac=$(mac_get $rp1)
244	payload=$($payload_get)
245	ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac \
246		-B 192.0.2.17 -t udp sp=12345,dp=$VXPORT,p=$payload -q &
247	mz_pid=$!
248
249	devlink_trap_exception_test $trap_name
250
251	tc_check_packets "dev $swp1 egress" 101 0
252	check_err $? "Packets were not dropped"
253
254	log_test "$desc"
255
256	kill $mz_pid && wait $mz_pid &> /dev/null
257	tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
258}
259
260decap_error_test()
261{
262	ecn_decap_test "Decap error" "ECT(1)" 01
263	ecn_decap_test "Decap error" "ECT(0)" 02
264	ecn_decap_test "Decap error" "CE" 03
265
266	corrupted_packet_test "Decap error: Reserved bits in use" \
267		"reserved_bits_payload_get"
268	corrupted_packet_test "Decap error: Too short inner packet" \
269		"short_payload_get"
270}
271
272mc_smac_payload_get()
273{
274	dest_mac=$(mac_get $h1)
275	source_mac=01:02:03:04:05:06
276	p=$(:
277		)"08:"$(                      : VXLAN flags
278		)"00:00:00:"$(                : VXLAN reserved
279		)"00:03:e8:"$(                : VXLAN VNI : 1000
280		)"00:"$(                      : VXLAN reserved
281		)"$dest_mac:"$(               : ETH daddr
282		)"$source_mac:"$(             : ETH saddr
283		)"08:00:"$(                   : ETH type
284		)"45:"$(                      : IP version + IHL
285		)"00:"$(                      : IP TOS
286		)"00:14:"$(                   : IP total length
287		)"00:00:"$(                   : IP identification
288		)"20:00:"$(                   : IP flags + frag off
289		)"40:"$(                      : IP TTL
290		)"00:"$(                      : IP proto
291		)"00:00:"$(                   : IP header csum
292		)"c0:00:02:03:"$(             : IP saddr: 192.0.2.3
293		)"c0:00:02:01:"$(             : IP daddr: 192.0.2.1
294		)
295	echo $p
296}
297
298overlay_smac_is_mc_test()
299{
300	local trap_name="overlay_smac_is_mc"
301	local mz_pid
302
303	RET=0
304
305	# The matching will be checked on devlink_trap_drop_test()
306	# and the filter will be removed on devlink_trap_drop_cleanup()
307	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
308		flower src_mac 01:02:03:04:05:06 action pass
309
310	rp1_mac=$(mac_get $rp1)
311	payload=$(mc_smac_payload_get)
312
313	ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac \
314		-B 192.0.2.17 -t udp sp=12345,dp=$VXPORT,p=$payload -q &
315	mz_pid=$!
316
317	devlink_trap_drop_test $trap_name $swp1 101
318
319	log_test "Overlay source MAC is multicast"
320
321	devlink_trap_drop_cleanup $mz_pid $swp1 "ip" 1 101
322}
323
324trap cleanup EXIT
325
326setup_prepare
327setup_wait
328tests_run
329
330exit $EXIT_STATUS
331