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"
168 ping_check $trap_name
170 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
171 flower dst_ip $h2_ipv4 action drop
173 # Generate non-IP packets to the router
174 $MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \
178 devlink_trap_drop_test $trap_name $rp2 101
182 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
185 __uc_dip_over_mc_dmac_test()
188 local proto=$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
197 ping_check $trap_name
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
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 &
207 devlink_trap_drop_test $trap_name $rp2 101
209 log_test "Unicast destination IP over multicast destination MAC: $desc"
211 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
214 uc_dip_over_mc_dmac_test()
216 __uc_dip_over_mc_dmac_test "IPv4" "ip" $h2_ipv4
217 __uc_dip_over_mc_dmac_test "IPv6" "ipv6" $h2_ipv6 "-6"
220 __sip_is_loopback_test()
223 local proto=$1; shift
226 local flags=${1:-""}; shift
227 local trap_name="sip_is_loopback_address"
232 ping_check $trap_name
234 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
235 flower src_ip $sip action drop
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 &
242 devlink_trap_drop_test $trap_name $rp2 101
244 log_test "Source IP is loopback address: $desc"
246 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
249 sip_is_loopback_test()
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"
255 __dip_is_loopback_test()
258 local proto=$1; shift
260 local flags=${1:-""}; shift
261 local trap_name="dip_is_loopback_address"
266 ping_check $trap_name
268 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
269 flower dst_ip $dip action drop
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 &
276 devlink_trap_drop_test $trap_name $rp2 101
278 log_test "Destination IP is loopback address: $desc"
280 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
283 dip_is_loopback_test()
285 __dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8"
286 __dip_is_loopback_test "IPv6" "ipv6" "::1" "-6"
292 local proto=$1; shift
295 local flags=${1:-""}; shift
296 local trap_name="sip_is_mc"
301 ping_check $trap_name
303 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
304 flower src_ip $sip action drop
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 &
311 devlink_trap_drop_test $trap_name $rp2 101
313 log_test "Source IP is multicast: $desc"
315 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
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"
324 ipv4_sip_is_limited_bc_test()
326 local trap_name="ipv4_sip_is_limited_bc"
327 local sip=255.255.255.255
332 ping_check $trap_name
334 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
335 flower src_ip $sip action drop
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 &
342 devlink_trap_drop_test $trap_name $rp2 101
344 log_test "IPv4 source IP is limited broadcast"
346 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
351 local ipver=$1; shift
353 local checksum=$1; shift
356 )"08:00:"$( : ETH type
357 )"$ipver"$( : IP version
360 )"00:F4:"$( : IP total length
361 )"00:00:"$( : IP identification
362 )"20:00:"$( : IP flags + frag off
365 )"$checksum:"$( : IP header csum
366 )"$h1_ipv4:"$( : IP saddr
367 )"$h2_ipv4:"$( : IP daddr
372 __ipv4_header_corrupted_test()
375 local ipver=$1; shift
377 local checksum=$1; shift
378 local trap_name="ip_header_corrupted"
384 ping_check $trap_name
386 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
387 flower dst_ip $h2_ipv4 action drop
389 payload=$(ipv4_payload_get $ipver $ihl $checksum)
391 # Generate packets with corrupted IP header
392 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
395 devlink_trap_drop_test $trap_name $rp2 101
397 log_test "IP header corrupted: $desc: IPv4"
399 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
404 local ipver=$1; shift
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
414 )"$h1_ipv6:"$( : IP saddr
415 )"$h2_ipv6:"$( : IP daddr
420 __ipv6_header_corrupted_test()
423 local ipver=$1; shift
424 local trap_name="ip_header_corrupted"
430 ping_check $trap_name
432 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
433 flower dst_ip $h2_ipv4 action drop
435 payload=$(ipv6_payload_get $ipver)
437 # Generate packets with corrupted IP header
438 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
441 devlink_trap_drop_test $trap_name $rp2 101
443 log_test "IP header corrupted: $desc: IPv6"
445 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
448 ip_header_corrupted_test()
450 # Each test uses one wrong value. The three values below are correct.
453 local checksum="00:F4"
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
461 ipv6_mc_dip_reserved_scope_test()
463 local trap_name="ipv6_mc_dip_reserved_scope"
469 ping_check $trap_name
471 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
472 flower dst_ip $dip action drop
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 &
479 devlink_trap_drop_test $trap_name $rp2 101
481 log_test "IPv6 multicast destination IP reserved scope"
483 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
486 ipv6_mc_dip_interface_local_scope_test()
488 local trap_name="ipv6_mc_dip_interface_local_scope"
494 ping_check $trap_name
496 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
497 flower dst_ip $dip action drop
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 &
504 devlink_trap_drop_test $trap_name $rp2 101
506 log_test "IPv6 multicast destination IP interface-local scope"
508 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
511 __blackhole_route_test()
513 local flags=$1; shift
514 local subnet=$1; shift
515 local proto=$1; shift
517 local ip_proto=${1:-"icmp"}; shift
518 local trap_name="blackhole_route"
523 ping_check $trap_name
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
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 &
534 devlink_trap_drop_test $trap_name $rp2 101
535 log_test "Blackhole route: IPv$flags"
537 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
538 ip -$flags route del blackhole $subnet
541 blackhole_route_test()
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"
549 local trap_name="irif_disabled"
550 local t0_packets t0_bytes
551 local t1_packets t1_bytes
556 ping_check $trap_name
558 devlink_trap_action_set $trap_name "trap"
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
571 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
572 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
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 \
579 # Wait before removing br0 RIF to allow packets to go into the bridge.
582 # Flushing address will dismantle the RIF
583 ip address flush dev br0
585 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
586 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
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"
592 log_test "Ingress RIF disabled"
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"
603 local trap_name="erif_disabled"
604 local t0_packets t0_bytes
605 local t1_packets t1_bytes
610 ping_check $trap_name
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
619 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
620 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
622 rp2mac=$(mac_get $rp2)
624 # Generate packets that should go out through br0 RIF that will be
626 $MZ $h2 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp2mac \
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
635 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
636 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
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"
642 log_test "Egress RIF disabled"
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"