1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test devlink-trap tunnel exceptions functionality over mlxsw.
5# Check all exception traps to make sure they are triggered under the right
6# conditions.
7
8# +-------------------------+
9# | H1                      |
10# |               $h1 +     |
11# |      192.0.2.1/28 |     |
12# +-------------------|-----+
13#                     |
14# +-------------------|-----+
15# | SW1               |     |
16# |              $swp1 +    |
17# |      192.0.2.2/28       |
18# |                         |
19# |  + g1a (gre)            |
20# |    loc=192.0.2.65       |
21# |    rem=192.0.2.66       |
22# |    tos=inherit          |
23# |                         |
24# |  + $rp1                 |
25# |  |  198.51.100.1/28     |
26# +--|----------------------+
27#    |
28# +--|----------------------+
29# |  |                 VRF2 |
30# | + $rp2                  |
31# |   198.51.100.2/28       |
32# +-------------------------+
33
34lib_dir=$(dirname $0)/../../../net/forwarding
35
36ALL_TESTS="
37	decap_error_test
38"
39
40NUM_NETIFS=4
41source $lib_dir/lib.sh
42source $lib_dir/tc_common.sh
43source $lib_dir/devlink_lib.sh
44
45h1_create()
46{
47	simple_if_init $h1 192.0.2.1/28
48}
49
50h1_destroy()
51{
52	simple_if_fini $h1 192.0.2.1/28
53}
54
55vrf2_create()
56{
57	simple_if_init $rp2 198.51.100.2/28
58}
59
60vrf2_destroy()
61{
62	simple_if_fini $rp2 198.51.100.2/28
63}
64
65switch_create()
66{
67	__addr_add_del $swp1 add 192.0.2.2/28
68	tc qdisc add dev $swp1 clsact
69	ip link set dev $swp1 up
70
71	tunnel_create g1 gre 192.0.2.65 192.0.2.66 tos inherit
72	__addr_add_del g1 add 192.0.2.65/32
73	ip link set dev g1 up
74
75	__addr_add_del $rp1 add 198.51.100.1/28
76	ip link set dev $rp1 up
77}
78
79switch_destroy()
80{
81	ip link set dev $rp1 down
82	__addr_add_del $rp1 del 198.51.100.1/28
83
84	ip link set dev g1 down
85	__addr_add_del g1 del 192.0.2.65/32
86	tunnel_destroy g1
87
88	ip link set dev $swp1 down
89	tc qdisc del dev $swp1 clsact
90	__addr_add_del $swp1 del 192.0.2.2/28
91}
92
93setup_prepare()
94{
95	h1=${NETIFS[p1]}
96	swp1=${NETIFS[p2]}
97
98	rp1=${NETIFS[p3]}
99	rp2=${NETIFS[p4]}
100
101	forwarding_enable
102	vrf_prepare
103	h1_create
104	switch_create
105	vrf2_create
106}
107
108cleanup()
109{
110	pre_cleanup
111
112	vrf2_destroy
113	switch_destroy
114	h1_destroy
115	vrf_cleanup
116	forwarding_restore
117}
118
119ecn_payload_get()
120{
121	p=$(:
122		)"0"$(		              : GRE flags
123	        )"0:00:"$(                    : Reserved + version
124		)"08:00:"$(		      : ETH protocol type
125		)"4"$(	                      : IP version
126		)"5:"$(                       : IHL
127		)"00:"$(                      : IP TOS
128		)"00:14:"$(                   : IP total length
129		)"00:00:"$(                   : IP identification
130		)"20:00:"$(                   : IP flags + frag off
131		)"30:"$(                      : IP TTL
132		)"01:"$(                      : IP proto
133		)"E7:E6:"$(    	              : IP header csum
134		)"C0:00:01:01:"$(             : IP saddr : 192.0.1.1
135		)"C0:00:02:01:"$(             : IP daddr : 192.0.2.1
136		)
137	echo $p
138}
139
140ecn_decap_test()
141{
142	local trap_name="decap_error"
143	local group_name="tunnel_drops"
144	local desc=$1; shift
145	local ecn_desc=$1; shift
146	local outer_tos=$1; shift
147	local mz_pid
148
149	RET=0
150
151	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
152		flower src_ip 192.0.1.1 dst_ip 192.0.2.1 action pass
153
154	rp1_mac=$(mac_get $rp1)
155	rp2_mac=$(mac_get $rp2)
156	payload=$(ecn_payload_get)
157
158	ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -a $rp2_mac -b $rp1_mac \
159		-A 192.0.2.66 -B 192.0.2.65 -t ip \
160			len=48,tos=$outer_tos,proto=47,p=$payload -q &
161
162	mz_pid=$!
163
164	devlink_trap_exception_test $trap_name $group_name
165
166	tc_check_packets "dev $swp1 egress" 101 0
167	check_err $? "Packets were not dropped"
168
169	log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc"
170
171	kill $mz_pid && wait $mz_pid &> /dev/null
172	tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
173}
174
175ipip_payload_get()
176{
177	local flags=$1; shift
178	local key=$1; shift
179
180	p=$(:
181		)"$flags"$(		      : GRE flags
182	        )"0:00:"$(                    : Reserved + version
183		)"08:00:"$(		      : ETH protocol type
184		)"$key"$( 		      : Key
185		)"4"$(	                      : IP version
186		)"5:"$(                       : IHL
187		)"00:"$(                      : IP TOS
188		)"00:14:"$(                   : IP total length
189		)"00:00:"$(                   : IP identification
190		)"20:00:"$(                   : IP flags + frag off
191		)"30:"$(                      : IP TTL
192		)"01:"$(                      : IP proto
193		)"E7:E6:"$(    	              : IP header csum
194		)"C0:00:01:01:"$(             : IP saddr : 192.0.1.1
195		)"C0:00:02:01:"$(             : IP daddr : 192.0.2.1
196		)
197	echo $p
198}
199
200no_matching_tunnel_test()
201{
202	local trap_name="decap_error"
203	local group_name="tunnel_drops"
204	local desc=$1; shift
205	local sip=$1; shift
206	local mz_pid
207
208	RET=0
209
210	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
211		flower src_ip 192.0.1.1 dst_ip 192.0.2.1 action pass
212
213	rp1_mac=$(mac_get $rp1)
214	rp2_mac=$(mac_get $rp2)
215	payload=$(ipip_payload_get "$@")
216
217	ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -a $rp2_mac -b $rp1_mac \
218		-A $sip -B 192.0.2.65 -t ip len=48,proto=47,p=$payload -q &
219	mz_pid=$!
220
221	devlink_trap_exception_test $trap_name $group_name
222
223	tc_check_packets "dev $swp1 egress" 101 0
224	check_err $? "Packets were not dropped"
225
226	log_test "$desc"
227
228	kill $mz_pid && wait $mz_pid &> /dev/null
229	tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
230}
231
232decap_error_test()
233{
234	# Correct source IP - the remote address
235	local sip=192.0.2.66
236
237	ecn_decap_test "Decap error" "ECT(1)" 01
238	ecn_decap_test "Decap error" "ECT(0)" 02
239	ecn_decap_test "Decap error" "CE" 03
240
241	no_matching_tunnel_test "Decap error: Source IP check failed" \
242		192.0.2.68 "0"
243	no_matching_tunnel_test \
244		"Decap error: Key exists but was not expected" $sip "2" ":E9:"
245
246	# Destroy the tunnel and create new one with key
247	__addr_add_del g1 del 192.0.2.65/32
248	tunnel_destroy g1
249
250	tunnel_create g1 gre 192.0.2.65 192.0.2.66 tos inherit key 233
251	__addr_add_del g1 add 192.0.2.65/32
252
253	no_matching_tunnel_test \
254		"Decap error: Key does not exist but was expected" $sip "0"
255	no_matching_tunnel_test \
256		"Decap error: Packet has a wrong key field" $sip "2" "E8:"
257}
258
259trap cleanup EXIT
260
261setup_prepare
262setup_wait
263tests_run
264
265exit $EXIT_STATUS
266