xref: /linux/tools/testing/selftests/net/forwarding/tc_flower.sh (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="match_dst_mac_test match_src_mac_test match_dst_ip_test \
5	match_src_ip_test match_ip_flags_test match_pcp_test match_vlan_test \
6	match_ip_tos_test match_indev_test match_ip_ttl_test
7	match_mpls_label_test \
8	match_mpls_tc_test match_mpls_bos_test match_mpls_ttl_test \
9	match_mpls_lse_test"
10NUM_NETIFS=2
11source tc_common.sh
12source lib.sh
13
14tcflags="skip_hw"
15
16h1_create()
17{
18	simple_if_init $h1 192.0.2.1/24 198.51.100.1/24
19}
20
21h1_destroy()
22{
23	simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24
24}
25
26h2_create()
27{
28	simple_if_init $h2 192.0.2.2/24 198.51.100.2/24
29	tc qdisc add dev $h2 clsact
30}
31
32h2_destroy()
33{
34	tc qdisc del dev $h2 clsact
35	simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24
36}
37
38match_dst_mac_test()
39{
40	local dummy_mac=de:ad:be:ef:aa:aa
41
42	RET=0
43
44	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
45		$tcflags dst_mac $dummy_mac action drop
46	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
47		$tcflags dst_mac $h2mac action drop
48
49	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
50		-t ip -q
51
52	tc_check_packets "dev $h2 ingress" 101 1
53	check_fail $? "Matched on a wrong filter"
54
55	tc_check_packets "dev $h2 ingress" 102 0
56	check_fail $? "Did not match on correct filter"
57
58	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
59	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
60
61	log_test "dst_mac match ($tcflags)"
62}
63
64match_src_mac_test()
65{
66	local dummy_mac=de:ad:be:ef:aa:aa
67
68	RET=0
69
70	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
71		$tcflags src_mac $dummy_mac action drop
72	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
73		$tcflags src_mac $h1mac action drop
74
75	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
76		-t ip -q
77
78	tc_check_packets "dev $h2 ingress" 101 1
79	check_fail $? "Matched on a wrong filter"
80
81	tc_check_packets "dev $h2 ingress" 102 0
82	check_fail $? "Did not match on correct filter"
83
84	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
85	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
86
87	log_test "src_mac match ($tcflags)"
88}
89
90match_dst_ip_test()
91{
92	RET=0
93
94	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
95		$tcflags dst_ip 198.51.100.2 action drop
96	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
97		$tcflags dst_ip 192.0.2.2 action drop
98	tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
99		$tcflags dst_ip 192.0.2.0/24 action drop
100
101	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
102		-t ip -q
103
104	tc_check_packets "dev $h2 ingress" 101 1
105	check_fail $? "Matched on a wrong filter"
106
107	tc_check_packets "dev $h2 ingress" 102 1
108	check_err $? "Did not match on correct filter"
109
110	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
111
112	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
113		-t ip -q
114
115	tc_check_packets "dev $h2 ingress" 103 1
116	check_err $? "Did not match on correct filter with mask"
117
118	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
119	tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
120
121	log_test "dst_ip match ($tcflags)"
122}
123
124match_src_ip_test()
125{
126	RET=0
127
128	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
129		$tcflags src_ip 198.51.100.1 action drop
130	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
131		$tcflags src_ip 192.0.2.1 action drop
132	tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
133		$tcflags src_ip 192.0.2.0/24 action drop
134
135	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
136		-t ip -q
137
138	tc_check_packets "dev $h2 ingress" 101 1
139	check_fail $? "Matched on a wrong filter"
140
141	tc_check_packets "dev $h2 ingress" 102 1
142	check_err $? "Did not match on correct filter"
143
144	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
145
146	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
147		-t ip -q
148
149	tc_check_packets "dev $h2 ingress" 103 1
150	check_err $? "Did not match on correct filter with mask"
151
152	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
153	tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
154
155	log_test "src_ip match ($tcflags)"
156}
157
158match_ip_flags_test()
159{
160	RET=0
161
162	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
163		$tcflags ip_flags frag action continue
164	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
165		$tcflags ip_flags firstfrag action continue
166	tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
167		$tcflags ip_flags nofirstfrag action continue
168	tc filter add dev $h2 ingress protocol ip pref 4 handle 104 flower \
169		$tcflags ip_flags nofrag action drop
170
171	$MZ $h1 -c 1 -p 1000 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
172		-t ip "frag=0" -q
173
174	tc_check_packets "dev $h2 ingress" 101 1
175	check_fail $? "Matched on wrong frag filter (nofrag)"
176
177	tc_check_packets "dev $h2 ingress" 102 1
178	check_fail $? "Matched on wrong firstfrag filter (nofrag)"
179
180	tc_check_packets "dev $h2 ingress" 103 1
181	check_err $? "Did not match on nofirstfrag filter (nofrag) "
182
183	tc_check_packets "dev $h2 ingress" 104 1
184	check_err $? "Did not match on nofrag filter (nofrag)"
185
186	$MZ $h1 -c 1 -p 1000 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
187		-t ip "frag=0,mf" -q
188
189	tc_check_packets "dev $h2 ingress" 101 1
190	check_err $? "Did not match on frag filter (1stfrag)"
191
192	tc_check_packets "dev $h2 ingress" 102 1
193	check_err $? "Did not match fistfrag filter (1stfrag)"
194
195	tc_check_packets "dev $h2 ingress" 103 1
196	check_err $? "Matched on wrong nofirstfrag filter (1stfrag)"
197
198	tc_check_packets "dev $h2 ingress" 104 1
199	check_err $? "Match on wrong nofrag filter (1stfrag)"
200
201	$MZ $h1 -c 1 -p 1000 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
202		-t ip "frag=256,mf" -q
203	$MZ $h1 -c 1 -p 1000 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
204		-t ip "frag=256" -q
205
206	tc_check_packets "dev $h2 ingress" 101 3
207	check_err $? "Did not match on frag filter (no1stfrag)"
208
209	tc_check_packets "dev $h2 ingress" 102 1
210	check_err $? "Matched on wrong firstfrag filter (no1stfrag)"
211
212	tc_check_packets "dev $h2 ingress" 103 3
213	check_err $? "Did not match on nofirstfrag filter (no1stfrag)"
214
215	tc_check_packets "dev $h2 ingress" 104 1
216	check_err $? "Matched on nofrag filter (no1stfrag)"
217
218	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
219	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
220	tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
221	tc filter del dev $h2 ingress protocol ip pref 4 handle 104 flower
222
223	log_test "ip_flags match ($tcflags)"
224}
225
226match_pcp_test()
227{
228	RET=0
229
230	vlan_create $h2 85 v$h2 192.0.2.11/24
231
232	tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 101 \
233		flower vlan_prio 6 $tcflags dst_mac $h2mac action drop
234	tc filter add dev $h2 ingress protocol 802.1q pref 2 handle 102 \
235		flower vlan_prio 7 $tcflags dst_mac $h2mac action drop
236
237	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -B 192.0.2.11 -Q 7:85 -t ip -q
238	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -B 192.0.2.11 -Q 0:85 -t ip -q
239
240	tc_check_packets "dev $h2 ingress" 101 0
241	check_err $? "Matched on specified PCP when should not"
242
243	tc_check_packets "dev $h2 ingress" 102 1
244	check_err $? "Did not match on specified PCP"
245
246	tc filter del dev $h2 ingress protocol 802.1q pref 2 handle 102 flower
247	tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 101 flower
248
249	vlan_destroy $h2 85
250
251	log_test "PCP match ($tcflags)"
252}
253
254match_vlan_test()
255{
256	RET=0
257
258	vlan_create $h2 85 v$h2 192.0.2.11/24
259	vlan_create $h2 75 v$h2 192.0.2.10/24
260
261	tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 101 \
262		flower vlan_id 75 $tcflags action drop
263	tc filter add dev $h2 ingress protocol 802.1q pref 2 handle 102 \
264		flower vlan_id 85 $tcflags action drop
265
266	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -B 192.0.2.11 -Q 0:85 -t ip -q
267
268	tc_check_packets "dev $h2 ingress" 101 0
269	check_err $? "Matched on specified VLAN when should not"
270
271	tc_check_packets "dev $h2 ingress" 102 1
272	check_err $? "Did not match on specified VLAN"
273
274	tc filter del dev $h2 ingress protocol 802.1q pref 2 handle 102 flower
275	tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 101 flower
276
277	vlan_destroy $h2 75
278	vlan_destroy $h2 85
279
280	log_test "VLAN match ($tcflags)"
281}
282
283match_ip_tos_test()
284{
285	RET=0
286
287	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
288		$tcflags dst_ip 192.0.2.2 ip_tos 0x20 action drop
289	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
290		$tcflags dst_ip 192.0.2.2 ip_tos 0x18 action drop
291
292	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
293		-t ip tos=18 -q
294
295	tc_check_packets "dev $h2 ingress" 101 1
296	check_fail $? "Matched on a wrong filter (0x18)"
297
298	tc_check_packets "dev $h2 ingress" 102 1
299	check_err $? "Did not match on correct filter (0x18)"
300
301	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
302		-t ip tos=20 -q
303
304	tc_check_packets "dev $h2 ingress" 102 2
305	check_fail $? "Matched on a wrong filter (0x20)"
306
307	tc_check_packets "dev $h2 ingress" 101 1
308	check_err $? "Did not match on correct filter (0x20)"
309
310	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
311	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
312
313	log_test "ip_tos match ($tcflags)"
314}
315
316match_ip_ttl_test()
317{
318	RET=0
319
320	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
321		$tcflags dst_ip 192.0.2.2 ip_ttl 63 action drop
322	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
323		$tcflags dst_ip 192.0.2.2 action drop
324
325	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
326		-t ip "ttl=63" -q
327
328	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
329		-t ip "ttl=63,mf,frag=256" -q
330
331	tc_check_packets "dev $h2 ingress" 102 1
332	check_fail $? "Matched on the wrong filter (no check on ttl)"
333
334	tc_check_packets "dev $h2 ingress" 101 2
335	check_err $? "Did not match on correct filter (ttl=63)"
336
337	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
338		-t ip "ttl=255" -q
339
340	tc_check_packets "dev $h2 ingress" 101 3
341	check_fail $? "Matched on a wrong filter (ttl=63)"
342
343	tc_check_packets "dev $h2 ingress" 102 1
344	check_err $? "Did not match on correct filter (no check on ttl)"
345
346	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
347	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
348
349	log_test "ip_ttl match ($tcflags)"
350}
351
352match_indev_test()
353{
354	RET=0
355
356	tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
357		$tcflags indev $h1 dst_mac $h2mac action drop
358	tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
359		$tcflags indev $h2 dst_mac $h2mac action drop
360
361	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
362		-t ip -q
363
364	tc_check_packets "dev $h2 ingress" 101 1
365	check_fail $? "Matched on a wrong filter"
366
367	tc_check_packets "dev $h2 ingress" 102 1
368	check_err $? "Did not match on correct filter"
369
370	tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
371	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
372
373	log_test "indev match ($tcflags)"
374}
375
376# Unfortunately, mausezahn can't build MPLS headers when used in L2
377# mode, so we have this function to build Label Stack Entries.
378mpls_lse()
379{
380	local label=$1
381	local tc=$2
382	local bos=$3
383	local ttl=$4
384
385	printf "%02x %02x %02x %02x"                        \
386		$((label >> 12))                            \
387		$((label >> 4 & 0xff))                      \
388		$((((label & 0xf) << 4) + (tc << 1) + bos)) \
389		$ttl
390}
391
392match_mpls_label_test()
393{
394	local ethtype="88 47"; readonly ethtype
395	local pkt
396
397	RET=0
398
399	check_tc_mpls_support $h2 || return 0
400
401	tc filter add dev $h2 ingress protocol mpls_uc pref 1 handle 101 \
402		flower $tcflags mpls_label 0 action drop
403	tc filter add dev $h2 ingress protocol mpls_uc pref 2 handle 102 \
404		flower $tcflags mpls_label 1048575 action drop
405
406	pkt="$ethtype $(mpls_lse 1048575 0 1 255)"
407	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
408
409	tc_check_packets "dev $h2 ingress" 101 1
410	check_fail $? "Matched on a wrong filter (1048575)"
411
412	tc_check_packets "dev $h2 ingress" 102 1
413	check_err $? "Did not match on correct filter (1048575)"
414
415	pkt="$ethtype $(mpls_lse 0 0 1 255)"
416	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
417
418	tc_check_packets "dev $h2 ingress" 102 2
419	check_fail $? "Matched on a wrong filter (0)"
420
421	tc_check_packets "dev $h2 ingress" 101 1
422	check_err $? "Did not match on correct filter (0)"
423
424	tc filter del dev $h2 ingress protocol mpls_uc pref 2 handle 102 flower
425	tc filter del dev $h2 ingress protocol mpls_uc pref 1 handle 101 flower
426
427	log_test "mpls_label match ($tcflags)"
428}
429
430match_mpls_tc_test()
431{
432	local ethtype="88 47"; readonly ethtype
433	local pkt
434
435	RET=0
436
437	check_tc_mpls_support $h2 || return 0
438
439	tc filter add dev $h2 ingress protocol mpls_uc pref 1 handle 101 \
440		flower $tcflags mpls_tc 0 action drop
441	tc filter add dev $h2 ingress protocol mpls_uc pref 2 handle 102 \
442		flower $tcflags mpls_tc 7 action drop
443
444	pkt="$ethtype $(mpls_lse 0 7 1 255)"
445	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
446
447	tc_check_packets "dev $h2 ingress" 101 1
448	check_fail $? "Matched on a wrong filter (7)"
449
450	tc_check_packets "dev $h2 ingress" 102 1
451	check_err $? "Did not match on correct filter (7)"
452
453	pkt="$ethtype $(mpls_lse 0 0 1 255)"
454	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
455
456	tc_check_packets "dev $h2 ingress" 102 2
457	check_fail $? "Matched on a wrong filter (0)"
458
459	tc_check_packets "dev $h2 ingress" 101 1
460	check_err $? "Did not match on correct filter (0)"
461
462	tc filter del dev $h2 ingress protocol mpls_uc pref 2 handle 102 flower
463	tc filter del dev $h2 ingress protocol mpls_uc pref 1 handle 101 flower
464
465	log_test "mpls_tc match ($tcflags)"
466}
467
468match_mpls_bos_test()
469{
470	local ethtype="88 47"; readonly ethtype
471	local pkt
472
473	RET=0
474
475	check_tc_mpls_support $h2 || return 0
476
477	tc filter add dev $h2 ingress protocol mpls_uc pref 1 handle 101 \
478		flower $tcflags mpls_bos 0 action drop
479	tc filter add dev $h2 ingress protocol mpls_uc pref 2 handle 102 \
480		flower $tcflags mpls_bos 1 action drop
481
482	pkt="$ethtype $(mpls_lse 0 0 1 255)"
483	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
484
485	tc_check_packets "dev $h2 ingress" 101 1
486	check_fail $? "Matched on a wrong filter (1)"
487
488	tc_check_packets "dev $h2 ingress" 102 1
489	check_err $? "Did not match on correct filter (1)"
490
491	# Need to add a second label to properly mark the Bottom of Stack
492	pkt="$ethtype $(mpls_lse 0 0 0 255) $(mpls_lse 0 0 1 255)"
493	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
494
495	tc_check_packets "dev $h2 ingress" 102 2
496	check_fail $? "Matched on a wrong filter (0)"
497
498	tc_check_packets "dev $h2 ingress" 101 1
499	check_err $? "Did not match on correct filter (0)"
500
501	tc filter del dev $h2 ingress protocol mpls_uc pref 2 handle 102 flower
502	tc filter del dev $h2 ingress protocol mpls_uc pref 1 handle 101 flower
503
504	log_test "mpls_bos match ($tcflags)"
505}
506
507match_mpls_ttl_test()
508{
509	local ethtype="88 47"; readonly ethtype
510	local pkt
511
512	RET=0
513
514	check_tc_mpls_support $h2 || return 0
515
516	tc filter add dev $h2 ingress protocol mpls_uc pref 1 handle 101 \
517		flower $tcflags mpls_ttl 0 action drop
518	tc filter add dev $h2 ingress protocol mpls_uc pref 2 handle 102 \
519		flower $tcflags mpls_ttl 255 action drop
520
521	pkt="$ethtype $(mpls_lse 0 0 1 255)"
522	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
523
524	tc_check_packets "dev $h2 ingress" 101 1
525	check_fail $? "Matched on a wrong filter (255)"
526
527	tc_check_packets "dev $h2 ingress" 102 1
528	check_err $? "Did not match on correct filter (255)"
529
530	pkt="$ethtype $(mpls_lse 0 0 1 0)"
531	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
532
533	tc_check_packets "dev $h2 ingress" 102 2
534	check_fail $? "Matched on a wrong filter (0)"
535
536	tc_check_packets "dev $h2 ingress" 101 1
537	check_err $? "Did not match on correct filter (0)"
538
539	tc filter del dev $h2 ingress protocol mpls_uc pref 2 handle 102 flower
540	tc filter del dev $h2 ingress protocol mpls_uc pref 1 handle 101 flower
541
542	log_test "mpls_ttl match ($tcflags)"
543}
544
545match_mpls_lse_test()
546{
547	local ethtype="88 47"; readonly ethtype
548	local pkt
549
550	RET=0
551
552	check_tc_mpls_lse_stats $h2 || return 0
553
554	# Match on first LSE (minimal values for each field)
555	tc filter add dev $h2 ingress protocol mpls_uc pref 1 handle 101 \
556		flower $tcflags mpls lse depth 1 label 0 action continue
557	tc filter add dev $h2 ingress protocol mpls_uc pref 2 handle 102 \
558		flower $tcflags mpls lse depth 1 tc 0 action continue
559	tc filter add dev $h2 ingress protocol mpls_uc pref 3 handle 103 \
560		flower $tcflags mpls lse depth 1 bos 0 action continue
561	tc filter add dev $h2 ingress protocol mpls_uc pref 4 handle 104 \
562		flower $tcflags mpls lse depth 1 ttl 0 action continue
563
564	# Match on second LSE (maximal values for each field)
565	tc filter add dev $h2 ingress protocol mpls_uc pref 5 handle 105 \
566		flower $tcflags mpls lse depth 2 label 1048575 action continue
567	tc filter add dev $h2 ingress protocol mpls_uc pref 6 handle 106 \
568		flower $tcflags mpls lse depth 2 tc 7 action continue
569	tc filter add dev $h2 ingress protocol mpls_uc pref 7 handle 107 \
570		flower $tcflags mpls lse depth 2 bos 1 action continue
571	tc filter add dev $h2 ingress protocol mpls_uc pref 8 handle 108 \
572		flower $tcflags mpls lse depth 2 ttl 255 action continue
573
574	# Match on LSE depth
575	tc filter add dev $h2 ingress protocol mpls_uc pref 9 handle 109 \
576		flower $tcflags mpls lse depth 1 action continue
577	tc filter add dev $h2 ingress protocol mpls_uc pref 10 handle 110 \
578		flower $tcflags mpls lse depth 2 action continue
579	tc filter add dev $h2 ingress protocol mpls_uc pref 11 handle 111 \
580		flower $tcflags mpls lse depth 3 action continue
581
582	# Base packet, matched by all filters (except for stack depth 3)
583	pkt="$ethtype $(mpls_lse 0 0 0 0) $(mpls_lse 1048575 7 1 255)"
584	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
585
586	# Make a variant of the above packet, with a non-matching value
587	# for each LSE field
588
589	# Wrong label at depth 1
590	pkt="$ethtype $(mpls_lse 1 0 0 0) $(mpls_lse 1048575 7 1 255)"
591	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
592
593	# Wrong TC at depth 1
594	pkt="$ethtype $(mpls_lse 0 1 0 0) $(mpls_lse 1048575 7 1 255)"
595	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
596
597	# Wrong BOS at depth 1 (not adding a second LSE here since BOS is set
598	# in the first label, so anything that'd follow wouldn't be considered)
599	pkt="$ethtype $(mpls_lse 0 0 1 0)"
600	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
601
602	# Wrong TTL at depth 1
603	pkt="$ethtype $(mpls_lse 0 0 0 1) $(mpls_lse 1048575 7 1 255)"
604	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
605
606	# Wrong label at depth 2
607	pkt="$ethtype $(mpls_lse 0 0 0 0) $(mpls_lse 1048574 7 1 255)"
608	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
609
610	# Wrong TC at depth 2
611	pkt="$ethtype $(mpls_lse 0 0 0 0) $(mpls_lse 1048575 6 1 255)"
612	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
613
614	# Wrong BOS at depth 2 (adding a third LSE here since BOS isn't set in
615	# the second label)
616	pkt="$ethtype $(mpls_lse 0 0 0 0) $(mpls_lse 1048575 7 0 255)"
617	pkt="$pkt $(mpls_lse 0 0 1 255)"
618	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
619
620	# Wrong TTL at depth 2
621	pkt="$ethtype $(mpls_lse 0 0 0 0) $(mpls_lse 1048575 7 1 254)"
622	$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac "$pkt" -q
623
624	# Filters working at depth 1 should match all packets but one
625
626	tc_check_packets "dev $h2 ingress" 101 8
627	check_err $? "Did not match on correct filter"
628
629	tc_check_packets "dev $h2 ingress" 102 8
630	check_err $? "Did not match on correct filter"
631
632	tc_check_packets "dev $h2 ingress" 103 8
633	check_err $? "Did not match on correct filter"
634
635	tc_check_packets "dev $h2 ingress" 104 8
636	check_err $? "Did not match on correct filter"
637
638	# Filters working at depth 2 should match all packets but two (because
639	# of the test packet where the label stack depth is just one)
640
641	tc_check_packets "dev $h2 ingress" 105 7
642	check_err $? "Did not match on correct filter"
643
644	tc_check_packets "dev $h2 ingress" 106 7
645	check_err $? "Did not match on correct filter"
646
647	tc_check_packets "dev $h2 ingress" 107 7
648	check_err $? "Did not match on correct filter"
649
650	tc_check_packets "dev $h2 ingress" 108 7
651	check_err $? "Did not match on correct filter"
652
653	# Finally, verify the filters that only match on LSE depth
654
655	tc_check_packets "dev $h2 ingress" 109 9
656	check_err $? "Did not match on correct filter"
657
658	tc_check_packets "dev $h2 ingress" 110 8
659	check_err $? "Did not match on correct filter"
660
661	tc_check_packets "dev $h2 ingress" 111 1
662	check_err $? "Did not match on correct filter"
663
664	tc filter del dev $h2 ingress protocol mpls_uc pref 11 handle 111 flower
665	tc filter del dev $h2 ingress protocol mpls_uc pref 10 handle 110 flower
666	tc filter del dev $h2 ingress protocol mpls_uc pref 9 handle 109 flower
667	tc filter del dev $h2 ingress protocol mpls_uc pref 8 handle 108 flower
668	tc filter del dev $h2 ingress protocol mpls_uc pref 7 handle 107 flower
669	tc filter del dev $h2 ingress protocol mpls_uc pref 6 handle 106 flower
670	tc filter del dev $h2 ingress protocol mpls_uc pref 5 handle 105 flower
671	tc filter del dev $h2 ingress protocol mpls_uc pref 4 handle 104 flower
672	tc filter del dev $h2 ingress protocol mpls_uc pref 3 handle 103 flower
673	tc filter del dev $h2 ingress protocol mpls_uc pref 2 handle 102 flower
674	tc filter del dev $h2 ingress protocol mpls_uc pref 1 handle 101 flower
675
676	log_test "mpls lse match ($tcflags)"
677}
678
679setup_prepare()
680{
681	h1=${NETIFS[p1]}
682	h2=${NETIFS[p2]}
683	h1mac=$(mac_get $h1)
684	h2mac=$(mac_get $h2)
685
686	vrf_prepare
687
688	h1_create
689	h2_create
690}
691
692cleanup()
693{
694	pre_cleanup
695
696	h2_destroy
697	h1_destroy
698
699	vrf_cleanup
700}
701
702trap cleanup EXIT
703
704setup_prepare
705setup_wait
706
707tests_run
708
709tc_offload_check
710if [[ $? -ne 0 ]]; then
711	log_info "Could not test offloaded functionality"
712else
713	tcflags="skip_sw"
714	tests_run
715fi
716
717exit $EXIT_STATUS
718