2 # SPDX-License-Identifier: GPL-2.0
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
8 # +---------------------------------+
12 # | | 2001:db8:1::1/64 |
14 # | | default via 192.0.2.2 |
15 # | | default via 2001:db8:1::2 |
16 # +----|----------------------------+
18 # +----|----------------------------------------------------------------------+
22 # | 2001:db8:1::2/64 |
24 # | 2001:db8:2::2/64 |
28 # +----|----------------------------------------------------------------------+
30 # +----|----------------------------+
31 # | | default via 198.51.100.2 |
32 # | | default via 2001:db8:2::2 |
34 # | | 2001:db8:2::1/64 |
35 # | | 198.51.100.1/24 |
38 # +---------------------------------+
40 lib_dir=$(dirname $0)/../../../net/forwarding
44 uc_dip_over_mc_dmac_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
58 source $lib_dir/lib.sh
59 source $lib_dir/tc_common.sh
60 source $lib_dir/devlink_lib.sh
64 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
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
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
75 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
80 simple_if_init $h2 $h2_ipv4/24 $h2_ipv6/64
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
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
91 simple_if_fini $h2 $h2_ipv4/24 $h2_ipv6/64
96 ip link set dev $rp1 up
97 ip link set dev $rp2 up
99 tc qdisc add dev $rp2 clsact
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
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
110 tc qdisc del dev $rp2 clsact
122 rp1mac=$(mac_get $rp1)
126 h1_ipv6=2001:db8:1::1
127 h2_ipv6=2001:db8:2::1
155 devlink_trap_action_set $trap_name "trap"
157 check_err $? "Packets that should not be trapped were trapped"
158 devlink_trap_action_set $trap_name "drop"
163 local trap_name="non_ip"
164 local group_name="l3_drops"
169 ping_check $trap_name
171 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
172 flower dst_ip $h2_ipv4 action drop
174 # Generate non-IP packets to the router
175 $MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \
179 devlink_trap_drop_test $trap_name $group_name $rp2 101
183 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
186 __uc_dip_over_mc_dmac_test()
189 local proto=$1; shift
191 local flags=${1:-""}; shift
192 local trap_name="uc_dip_over_mc_dmac"
193 local group_name="l3_drops"
194 local dmac=01:02:03:04:05:06
199 ping_check $trap_name
201 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
202 flower ip_proto udp src_port 54321 dst_port 12345 action drop
204 # Generate IP packets with a unicast IP and a multicast destination MAC
205 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $dmac \
206 -B $dip -d 1msec -q &
209 devlink_trap_drop_test $trap_name $group_name $rp2 101
211 log_test "Unicast destination IP over multicast destination MAC: $desc"
213 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
216 uc_dip_over_mc_dmac_test()
218 __uc_dip_over_mc_dmac_test "IPv4" "ip" $h2_ipv4
219 __uc_dip_over_mc_dmac_test "IPv6" "ipv6" $h2_ipv6 "-6"
222 __sip_is_loopback_test()
225 local proto=$1; shift
228 local flags=${1:-""}; shift
229 local trap_name="sip_is_loopback_address"
230 local group_name="l3_drops"
235 ping_check $trap_name
237 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
238 flower src_ip $sip action drop
240 # Generate packets with loopback source IP
241 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
242 -b $rp1mac -B $dip -d 1msec -q &
245 devlink_trap_drop_test $trap_name $group_name $rp2 101
247 log_test "Source IP is loopback address: $desc"
249 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
252 sip_is_loopback_test()
254 __sip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" $h2_ipv4
255 __sip_is_loopback_test "IPv6" "ipv6" "::1" $h2_ipv6 "-6"
258 __dip_is_loopback_test()
261 local proto=$1; shift
263 local flags=${1:-""}; shift
264 local trap_name="dip_is_loopback_address"
265 local group_name="l3_drops"
270 ping_check $trap_name
272 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
273 flower dst_ip $dip action drop
275 # Generate packets with loopback destination IP
276 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
277 -B $dip -d 1msec -q &
280 devlink_trap_drop_test $trap_name $group_name $rp2 101
282 log_test "Destination IP is loopback address: $desc"
284 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
287 dip_is_loopback_test()
289 __dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8"
290 __dip_is_loopback_test "IPv6" "ipv6" "::1" "-6"
296 local proto=$1; shift
299 local flags=${1:-""}; shift
300 local trap_name="sip_is_mc"
301 local group_name="l3_drops"
306 ping_check $trap_name
308 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
309 flower src_ip $sip action drop
311 # Generate packets with multicast source IP
312 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
313 -b $rp1mac -B $dip -d 1msec -q &
316 devlink_trap_drop_test $trap_name $group_name $rp2 101
318 log_test "Source IP is multicast: $desc"
320 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
325 __sip_is_mc_test "IPv4" "ip" "239.1.1.1" $h2_ipv4
326 __sip_is_mc_test "IPv6" "ipv6" "FF02::2" $h2_ipv6 "-6"
329 ipv4_sip_is_limited_bc_test()
331 local trap_name="ipv4_sip_is_limited_bc"
332 local group_name="l3_drops"
333 local sip=255.255.255.255
338 ping_check $trap_name
340 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
341 flower src_ip $sip action drop
343 # Generate packets with limited broadcast source IP
344 $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip -b $rp1mac \
345 -B $h2_ipv4 -d 1msec -q &
348 devlink_trap_drop_test $trap_name $group_name $rp2 101
350 log_test "IPv4 source IP is limited broadcast"
352 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
357 local ipver=$1; shift
359 local checksum=$1; shift
362 )"08:00:"$( : ETH type
363 )"$ipver"$( : IP version
366 )"00:F4:"$( : IP total length
367 )"00:00:"$( : IP identification
368 )"20:00:"$( : IP flags + frag off
371 )"$checksum:"$( : IP header csum
372 )"$h1_ipv4:"$( : IP saddr
373 )"$h2_ipv4:"$( : IP daddr
378 __ipv4_header_corrupted_test()
381 local ipver=$1; shift
383 local checksum=$1; shift
384 local trap_name="ip_header_corrupted"
385 local group_name="l3_drops"
391 ping_check $trap_name
393 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
394 flower dst_ip $h2_ipv4 action drop
396 payload=$(ipv4_payload_get $ipver $ihl $checksum)
398 # Generate packets with corrupted IP header
399 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
402 devlink_trap_drop_test $trap_name $group_name $rp2 101
404 log_test "IP header corrupted: $desc: IPv4"
406 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
411 local ipver=$1; shift
414 )"86:DD:"$( : ETH type
415 )"$ipver"$( : IP version
416 )"0:0:"$( : Traffic class
417 )"0:00:00:"$( : Flow label
418 )"00:00:"$( : Payload length
419 )"01:"$( : Next header
421 )"$h1_ipv6:"$( : IP saddr
422 )"$h2_ipv6:"$( : IP daddr
427 __ipv6_header_corrupted_test()
430 local ipver=$1; shift
431 local trap_name="ip_header_corrupted"
432 local group_name="l3_drops"
438 ping_check $trap_name
440 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
441 flower dst_ip $h2_ipv4 action drop
443 payload=$(ipv6_payload_get $ipver)
445 # Generate packets with corrupted IP header
446 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
449 devlink_trap_drop_test $trap_name $group_name $rp2 101
451 log_test "IP header corrupted: $desc: IPv6"
453 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
456 ip_header_corrupted_test()
458 # Each test uses one wrong value. The three values below are correct.
461 local checksum="00:F4"
463 __ipv4_header_corrupted_test "wrong IP version" 5 $ihl $checksum
464 __ipv4_header_corrupted_test "wrong IHL" $ipv 4 $checksum
465 __ipv4_header_corrupted_test "wrong checksum" $ipv $ihl "00:00"
466 __ipv6_header_corrupted_test "wrong IP version" 5
469 ipv6_mc_dip_reserved_scope_test()
471 local trap_name="ipv6_mc_dip_reserved_scope"
472 local group_name="l3_drops"
478 ping_check $trap_name
480 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
481 flower dst_ip $dip action drop
483 # Generate packets with reserved scope destination IP
484 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
485 "33:33:00:00:00:00" -B $dip -d 1msec -q &
488 devlink_trap_drop_test $trap_name $group_name $rp2 101
490 log_test "IPv6 multicast destination IP reserved scope"
492 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
495 ipv6_mc_dip_interface_local_scope_test()
497 local trap_name="ipv6_mc_dip_interface_local_scope"
498 local group_name="l3_drops"
504 ping_check $trap_name
506 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
507 flower dst_ip $dip action drop
509 # Generate packets with interface local scope destination IP
510 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
511 "33:33:00:00:00:00" -B $dip -d 1msec -q &
514 devlink_trap_drop_test $trap_name $group_name $rp2 101
516 log_test "IPv6 multicast destination IP interface-local scope"
518 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
521 __blackhole_route_test()
523 local flags=$1; shift
524 local subnet=$1; shift
525 local proto=$1; shift
527 local ip_proto=${1:-"icmp"}; shift
528 local trap_name="blackhole_route"
529 local group_name="l3_drops"
534 ping_check $trap_name
536 ip -$flags route add blackhole $subnet
537 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
538 flower skip_hw dst_ip $dip ip_proto $ip_proto action drop
540 # Generate packets to the blackhole route
541 $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
542 -B $dip -d 1msec -q &
545 devlink_trap_drop_test $trap_name $group_name $rp2 101
546 log_test "Blackhole route: IPv$flags"
548 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
549 ip -$flags route del blackhole $subnet
552 blackhole_route_test()
554 __blackhole_route_test "4" "198.51.100.0/30" "ip" $h2_ipv4
555 __blackhole_route_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 "icmpv6"
560 local trap_name="irif_disabled"
561 local group_name="l3_drops"
562 local t0_packets t0_bytes
563 local t1_packets t1_bytes
568 ping_check $trap_name
570 devlink_trap_action_set $trap_name "trap"
572 # When RIF of a physical port ("Sub-port RIF") is destroyed, we first
573 # block the STP of the {Port, VLAN} so packets cannot get into the RIF.
574 # Using bridge enables us to see this trap because when bridge is
575 # destroyed, there is a small time window that packets can go into the
576 # RIF, while it is disabled.
577 ip link add dev br0 type bridge
578 ip link set dev $rp1 master br0
579 ip address flush dev $rp1
580 __addr_add_del br0 add 192.0.2.2/24
583 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
584 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
586 # Generate packets to h2 through br0 RIF that will be removed later
587 $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp1mac \
591 # Wait before removing br0 RIF to allow packets to go into the bridge.
594 # Flushing address will dismantle the RIF
595 ip address flush dev br0
597 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
598 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
600 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
601 check_err 1 "Trap stats idle when packets should be trapped"
604 log_test "Ingress RIF disabled"
606 kill $mz_pid && wait $mz_pid &> /dev/null
607 ip link set dev $rp1 nomaster
608 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
609 ip link del dev br0 type bridge
610 devlink_trap_action_set $trap_name "drop"
615 local trap_name="erif_disabled"
616 local group_name="l3_drops"
617 local t0_packets t0_bytes
618 local t1_packets t1_bytes
623 ping_check $trap_name
625 devlink_trap_action_set $trap_name "trap"
626 ip link add dev br0 type bridge
627 ip add flush dev $rp1
628 ip link set dev $rp1 master br0
629 __addr_add_del br0 add 192.0.2.2/24
630 ip link set dev br0 up
632 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
633 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
635 rp2mac=$(mac_get $rp2)
637 # Generate packets that should go out through br0 RIF that will be
639 $MZ $h2 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp2mac \
644 # Unlinking the port from the bridge will disable the RIF associated
645 # with br0 as it is no longer an upper of any mlxsw port.
646 ip link set dev $rp1 nomaster
648 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
649 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
651 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
652 check_err 1 "Trap stats idle when packets should be trapped"
655 log_test "Egress RIF disabled"
657 kill $mz_pid && wait $mz_pid &> /dev/null
658 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
659 ip link del dev br0 type bridge
660 devlink_trap_action_set $trap_name "drop"