selftests: mlxsw: Do not hard code trap group name
[linux-2.6-microblaze.git] / tools / testing / selftests / drivers / net / mlxsw / devlink_trap_l3_drops.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Test devlink-trap L3 drops functionality over mlxsw. Each registered L3 drop
5 # packet trap is tested to make sure it is triggered under the right
6 # conditions.
7
8 # +---------------------------------+
9 # | H1 (vrf)                        |
10 # |    + $h1                        |
11 # |    | 192.0.2.1/24               |
12 # |    | 2001:db8:1::1/64           |
13 # |    |                            |
14 # |    |  default via 192.0.2.2     |
15 # |    |  default via 2001:db8:1::2 |
16 # +----|----------------------------+
17 #      |
18 # +----|----------------------------------------------------------------------+
19 # | SW |                                                                      |
20 # |    + $rp1                                                                 |
21 # |        192.0.2.2/24                                                       |
22 # |        2001:db8:1::2/64                                                   |
23 # |                                                                           |
24 # |        2001:db8:2::2/64                                                   |
25 # |        198.51.100.2/24                                                    |
26 # |    + $rp2                                                                 |
27 # |    |                                                                      |
28 # +----|----------------------------------------------------------------------+
29 #      |
30 # +----|----------------------------+
31 # |    |  default via 198.51.100.2  |
32 # |    |  default via 2001:db8:2::2 |
33 # |    |                            |
34 # |    | 2001:db8:2::1/64           |
35 # |    | 198.51.100.1/24            |
36 # |    + $h2                        |
37 # | H2 (vrf)                        |
38 # +---------------------------------+
39
40 lib_dir=$(dirname $0)/../../../net/forwarding
41
42 ALL_TESTS="
43         non_ip_test
44         uc_dip_over_mc_dmac_test
45         dip_is_loopback_test
46         sip_is_mc_test
47         sip_is_loopback_test
48         ip_header_corrupted_test
49         ipv4_sip_is_limited_bc_test
50         ipv6_mc_dip_reserved_scope_test
51         ipv6_mc_dip_interface_local_scope_test
52         blackhole_route_test
53         irif_disabled_test
54         erif_disabled_test
55 "
56
57 NUM_NETIFS=4
58 source $lib_dir/lib.sh
59 source $lib_dir/tc_common.sh
60 source $lib_dir/devlink_lib.sh
61
62 h1_create()
63 {
64         simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
65
66         ip -4 route add default vrf v$h1 nexthop via 192.0.2.2
67         ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::2
68 }
69
70 h1_destroy()
71 {
72         ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::2
73         ip -4 route del default vrf v$h1 nexthop via 192.0.2.2
74
75         simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
76 }
77
78 h2_create()
79 {
80         simple_if_init $h2 $h2_ipv4/24 $h2_ipv6/64
81
82         ip -4 route add default vrf v$h2 nexthop via 198.51.100.2
83         ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::2
84 }
85
86 h2_destroy()
87 {
88         ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::2
89         ip -4 route del default vrf v$h2 nexthop via 198.51.100.2
90
91         simple_if_fini $h2 $h2_ipv4/24 $h2_ipv6/64
92 }
93
94 router_create()
95 {
96         ip link set dev $rp1 up
97         ip link set dev $rp2 up
98
99         tc qdisc add dev $rp2 clsact
100
101         __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
102         __addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64
103 }
104
105 router_destroy()
106 {
107         __addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64
108         __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
109
110         tc qdisc del dev $rp2 clsact
111 }
112
113 setup_prepare()
114 {
115         h1=${NETIFS[p1]}
116         rp1=${NETIFS[p2]}
117
118         rp2=${NETIFS[p3]}
119         h2=${NETIFS[p4]}
120
121         h1mac=$(mac_get $h1)
122         rp1mac=$(mac_get $rp1)
123
124         h1_ipv4=192.0.2.1
125         h2_ipv4=198.51.100.1
126         h1_ipv6=2001:db8:1::1
127         h2_ipv6=2001:db8:2::1
128
129         vrf_prepare
130         forwarding_enable
131
132         h1_create
133         h2_create
134
135         router_create
136 }
137
138 cleanup()
139 {
140         pre_cleanup
141
142         router_destroy
143
144         h2_destroy
145         h1_destroy
146
147         forwarding_restore
148         vrf_cleanup
149 }
150
151 ping_check()
152 {
153         trap_name=$1; shift
154
155         devlink_trap_action_set $trap_name "trap"
156         ping_do $h1 $h2_ipv4
157         check_err $? "Packets that should not be trapped were trapped"
158         devlink_trap_action_set $trap_name "drop"
159 }
160
161 non_ip_test()
162 {
163         local trap_name="non_ip"
164         local mz_pid
165
166         RET=0
167
168         ping_check $trap_name
169
170         tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
171                 flower dst_ip $h2_ipv4 action drop
172
173         # Generate non-IP packets to the router
174         $MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \
175                 00:00 de:ad:be:ef" &
176         mz_pid=$!
177
178         devlink_trap_drop_test $trap_name $rp2 101
179
180         log_test "Non IP"
181
182         devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
183 }
184
185 __uc_dip_over_mc_dmac_test()
186 {
187         local desc=$1; shift
188         local proto=$1; shift
189         local dip=$1; shift
190         local flags=${1:-""}; shift
191         local trap_name="uc_dip_over_mc_dmac"
192         local dmac=01:02:03:04:05:06
193         local mz_pid
194
195         RET=0
196
197         ping_check $trap_name
198
199         tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
200                 flower ip_proto udp src_port 54321 dst_port 12345 action drop
201
202         # Generate IP packets with a unicast IP and a multicast destination MAC
203         $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $dmac \
204                 -B $dip -d 1msec -q &
205         mz_pid=$!
206
207         devlink_trap_drop_test $trap_name $rp2 101
208
209         log_test "Unicast destination IP over multicast destination MAC: $desc"
210
211         devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
212 }
213
214 uc_dip_over_mc_dmac_test()
215 {
216         __uc_dip_over_mc_dmac_test "IPv4" "ip" $h2_ipv4
217         __uc_dip_over_mc_dmac_test "IPv6" "ipv6" $h2_ipv6 "-6"
218 }
219
220 __sip_is_loopback_test()
221 {
222         local desc=$1; shift
223         local proto=$1; shift
224         local sip=$1; shift
225         local dip=$1; shift
226         local flags=${1:-""}; shift
227         local trap_name="sip_is_loopback_address"
228         local mz_pid
229
230         RET=0
231
232         ping_check $trap_name
233
234         tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
235                 flower src_ip $sip action drop
236
237         # Generate packets with loopback source IP
238         $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
239                 -b $rp1mac -B $dip -d 1msec -q &
240         mz_pid=$!
241
242         devlink_trap_drop_test $trap_name $rp2 101
243
244         log_test "Source IP is loopback address: $desc"
245
246         devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
247 }
248
249 sip_is_loopback_test()
250 {
251         __sip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" $h2_ipv4
252         __sip_is_loopback_test "IPv6" "ipv6" "::1" $h2_ipv6 "-6"
253 }
254
255 __dip_is_loopback_test()
256 {
257         local desc=$1; shift
258         local proto=$1; shift
259         local dip=$1; shift
260         local flags=${1:-""}; shift
261         local trap_name="dip_is_loopback_address"
262         local mz_pid
263
264         RET=0
265
266         ping_check $trap_name
267
268         tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
269                 flower dst_ip $dip action drop
270
271         # Generate packets with loopback destination IP
272         $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
273                 -B $dip -d 1msec -q &
274         mz_pid=$!
275
276         devlink_trap_drop_test $trap_name $rp2 101
277
278         log_test "Destination IP is loopback address: $desc"
279
280         devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
281 }
282
283 dip_is_loopback_test()
284 {
285         __dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8"
286         __dip_is_loopback_test "IPv6" "ipv6" "::1" "-6"
287 }
288
289 __sip_is_mc_test()
290 {
291         local desc=$1; shift
292         local proto=$1; shift
293         local sip=$1; shift
294         local dip=$1; shift
295         local flags=${1:-""}; shift
296         local trap_name="sip_is_mc"
297         local mz_pid
298
299         RET=0
300
301         ping_check $trap_name
302
303         tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
304                 flower src_ip $sip action drop
305
306         # Generate packets with multicast source IP
307         $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
308                 -b $rp1mac -B $dip -d 1msec -q &
309         mz_pid=$!
310
311         devlink_trap_drop_test $trap_name $rp2 101
312
313         log_test "Source IP is multicast: $desc"
314
315         devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
316 }
317
318 sip_is_mc_test()
319 {
320         __sip_is_mc_test "IPv4" "ip" "239.1.1.1" $h2_ipv4
321         __sip_is_mc_test "IPv6" "ipv6" "FF02::2" $h2_ipv6 "-6"
322 }
323
324 ipv4_sip_is_limited_bc_test()
325 {
326         local trap_name="ipv4_sip_is_limited_bc"
327         local sip=255.255.255.255
328         local mz_pid
329
330         RET=0
331
332         ping_check $trap_name
333
334         tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
335                 flower src_ip $sip action drop
336
337         # Generate packets with limited broadcast source IP
338         $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip -b $rp1mac \
339                 -B $h2_ipv4 -d 1msec -q &
340         mz_pid=$!
341
342         devlink_trap_drop_test $trap_name $rp2 101
343
344         log_test "IPv4 source IP is limited broadcast"
345
346         devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
347 }
348
349 ipv4_payload_get()
350 {
351         local ipver=$1; shift
352         local ihl=$1; shift
353         local checksum=$1; shift
354
355         p=$(:
356                 )"08:00:"$(                   : ETH type
357                 )"$ipver"$(                   : IP version
358                 )"$ihl:"$(                    : IHL
359                 )"00:"$(                      : IP TOS
360                 )"00:F4:"$(                   : IP total length
361                 )"00:00:"$(                   : IP identification
362                 )"20:00:"$(                   : IP flags + frag off
363                 )"30:"$(                      : IP TTL
364                 )"01:"$(                      : IP proto
365                 )"$checksum:"$(               : IP header csum
366                 )"$h1_ipv4:"$(                : IP saddr
367                 )"$h2_ipv4:"$(                : IP daddr
368                 )
369         echo $p
370 }
371
372 __ipv4_header_corrupted_test()
373 {
374         local desc=$1; shift
375         local ipver=$1; shift
376         local ihl=$1; shift
377         local checksum=$1; shift
378         local trap_name="ip_header_corrupted"
379         local payload
380         local mz_pid
381
382         RET=0
383
384         ping_check $trap_name
385
386         tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
387                 flower dst_ip $h2_ipv4 action drop
388
389         payload=$(ipv4_payload_get $ipver $ihl $checksum)
390
391         # Generate packets with corrupted IP header
392         $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
393         mz_pid=$!
394
395         devlink_trap_drop_test $trap_name $rp2 101
396
397         log_test "IP header corrupted: $desc: IPv4"
398
399         devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
400 }
401
402 ipv6_payload_get()
403 {
404         local ipver=$1; shift
405
406         p=$(:
407                 )"86:DD:"$(                  : ETH type
408                 )"$ipver"$(                  : IP version
409                 )"0:0:"$(                    : Traffic class
410                 )"0:00:00:"$(                : Flow label
411                 )"00:00:"$(                  : Payload length
412                 )"01:"$(                     : Next header
413                 )"04:"$(                     : Hop limit
414                 )"$h1_ipv6:"$(               : IP saddr
415                 )"$h2_ipv6:"$(               : IP daddr
416                 )
417         echo $p
418 }
419
420 __ipv6_header_corrupted_test()
421 {
422         local desc=$1; shift
423         local ipver=$1; shift
424         local trap_name="ip_header_corrupted"
425         local payload
426         local mz_pid
427
428         RET=0
429
430         ping_check $trap_name
431
432         tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
433                 flower dst_ip $h2_ipv4 action drop
434
435         payload=$(ipv6_payload_get $ipver)
436
437         # Generate packets with corrupted IP header
438         $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
439         mz_pid=$!
440
441         devlink_trap_drop_test $trap_name $rp2 101
442
443         log_test "IP header corrupted: $desc: IPv6"
444
445         devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
446 }
447
448 ip_header_corrupted_test()
449 {
450         # Each test uses one wrong value. The three values below are correct.
451         local ipv="4"
452         local ihl="5"
453         local checksum="00:F4"
454
455         __ipv4_header_corrupted_test "wrong IP version" 5 $ihl $checksum
456         __ipv4_header_corrupted_test "wrong IHL" $ipv 4 $checksum
457         __ipv4_header_corrupted_test "wrong checksum" $ipv $ihl "00:00"
458         __ipv6_header_corrupted_test "wrong IP version" 5
459 }
460
461 ipv6_mc_dip_reserved_scope_test()
462 {
463         local trap_name="ipv6_mc_dip_reserved_scope"
464         local dip=FF00::
465         local mz_pid
466
467         RET=0
468
469         ping_check $trap_name
470
471         tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
472                 flower dst_ip $dip action drop
473
474         # Generate packets with reserved scope destination IP
475         $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
476                 "33:33:00:00:00:00" -B $dip -d 1msec -q &
477         mz_pid=$!
478
479         devlink_trap_drop_test $trap_name $rp2 101
480
481         log_test "IPv6 multicast destination IP reserved scope"
482
483         devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
484 }
485
486 ipv6_mc_dip_interface_local_scope_test()
487 {
488         local trap_name="ipv6_mc_dip_interface_local_scope"
489         local dip=FF01::
490         local mz_pid
491
492         RET=0
493
494         ping_check $trap_name
495
496         tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
497                 flower dst_ip $dip action drop
498
499         # Generate packets with interface local scope destination IP
500         $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
501                 "33:33:00:00:00:00" -B $dip -d 1msec -q &
502         mz_pid=$!
503
504         devlink_trap_drop_test $trap_name $rp2 101
505
506         log_test "IPv6 multicast destination IP interface-local scope"
507
508         devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
509 }
510
511 __blackhole_route_test()
512 {
513         local flags=$1; shift
514         local subnet=$1; shift
515         local proto=$1; shift
516         local dip=$1; shift
517         local ip_proto=${1:-"icmp"}; shift
518         local trap_name="blackhole_route"
519         local mz_pid
520
521         RET=0
522
523         ping_check $trap_name
524
525         ip -$flags route add blackhole $subnet
526         tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
527                 flower skip_hw dst_ip $dip ip_proto $ip_proto action drop
528
529         # Generate packets to the blackhole route
530         $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
531                 -B $dip -d 1msec -q &
532         mz_pid=$!
533
534         devlink_trap_drop_test $trap_name $rp2 101
535         log_test "Blackhole route: IPv$flags"
536
537         devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
538         ip -$flags route del blackhole $subnet
539 }
540
541 blackhole_route_test()
542 {
543         __blackhole_route_test "4" "198.51.100.0/30" "ip" $h2_ipv4
544         __blackhole_route_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 "icmpv6"
545 }
546
547 irif_disabled_test()
548 {
549         local trap_name="irif_disabled"
550         local t0_packets t0_bytes
551         local t1_packets t1_bytes
552         local mz_pid
553
554         RET=0
555
556         ping_check $trap_name
557
558         devlink_trap_action_set $trap_name "trap"
559
560         # When RIF of a physical port ("Sub-port RIF") is destroyed, we first
561         # block the STP of the {Port, VLAN} so packets cannot get into the RIF.
562         # Using bridge enables us to see this trap because when bridge is
563         # destroyed, there is a small time window that packets can go into the
564         # RIF, while it is disabled.
565         ip link add dev br0 type bridge
566         ip link set dev $rp1 master br0
567         ip address flush dev $rp1
568         __addr_add_del br0 add 192.0.2.2/24
569         ip li set dev br0 up
570
571         t0_packets=$(devlink_trap_rx_packets_get $trap_name)
572         t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
573
574         # Generate packets to h2 through br0 RIF that will be removed later
575         $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp1mac \
576                 -B $h2_ipv4 -q &
577         mz_pid=$!
578
579         # Wait before removing br0 RIF to allow packets to go into the bridge.
580         sleep 1
581
582         # Flushing address will dismantle the RIF
583         ip address flush dev br0
584
585         t1_packets=$(devlink_trap_rx_packets_get $trap_name)
586         t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
587
588         if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
589                 check_err 1 "Trap stats idle when packets should be trapped"
590         fi
591
592         log_test "Ingress RIF disabled"
593
594         kill $mz_pid && wait $mz_pid &> /dev/null
595         ip link set dev $rp1 nomaster
596         __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
597         ip link del dev br0 type bridge
598         devlink_trap_action_set $trap_name "drop"
599 }
600
601 erif_disabled_test()
602 {
603         local trap_name="erif_disabled"
604         local t0_packets t0_bytes
605         local t1_packets t1_bytes
606         local mz_pid
607
608         RET=0
609
610         ping_check $trap_name
611
612         devlink_trap_action_set $trap_name "trap"
613         ip link add dev br0 type bridge
614         ip add flush dev $rp1
615         ip link set dev $rp1 master br0
616         __addr_add_del br0 add 192.0.2.2/24
617         ip link set dev br0 up
618
619         t0_packets=$(devlink_trap_rx_packets_get $trap_name)
620         t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
621
622         rp2mac=$(mac_get $rp2)
623
624         # Generate packets that should go out through br0 RIF that will be
625         # removed later
626         $MZ $h2 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp2mac \
627                 -B 192.0.2.1 -q &
628         mz_pid=$!
629
630         sleep 5
631         # Unlinking the port from the bridge will disable the RIF associated
632         # with br0 as it is no longer an upper of any mlxsw port.
633         ip link set dev $rp1 nomaster
634
635         t1_packets=$(devlink_trap_rx_packets_get $trap_name)
636         t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
637
638         if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
639                 check_err 1 "Trap stats idle when packets should be trapped"
640         fi
641
642         log_test "Egress RIF disabled"
643
644         kill $mz_pid && wait $mz_pid &> /dev/null
645         __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
646         ip link del dev br0 type bridge
647         devlink_trap_action_set $trap_name "drop"
648 }
649
650 trap cleanup EXIT
651
652 setup_prepare
653 setup_wait
654
655 tests_run
656
657 exit $EXIT_STATUS