697 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03#4# Test devlink-trap L3 drops functionality over mlxsw. Each registered L3 drop5# packet trap is tested to make sure it is triggered under the right6# 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 40lib_dir=$(dirname $0)/../../../net/forwarding41 42ALL_TESTS="43 non_ip_test44 uc_dip_over_mc_dmac_test45 dip_is_loopback_test46 sip_is_mc_test47 sip_is_loopback_test48 ip_header_corrupted_test49 ipv4_sip_is_limited_bc_test50 ipv6_mc_dip_reserved_scope_test51 ipv6_mc_dip_interface_local_scope_test52 blackhole_route_test53 irif_disabled_test54 erif_disabled_test55 blackhole_nexthop_test56"57 58NUM_NETIFS=459source $lib_dir/lib.sh60source $lib_dir/tc_common.sh61source $lib_dir/devlink_lib.sh62 63h1_create()64{65 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/6466 67 ip -4 route add default vrf v$h1 nexthop via 192.0.2.268 ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::269}70 71h1_destroy()72{73 ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::274 ip -4 route del default vrf v$h1 nexthop via 192.0.2.275 76 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/6477}78 79h2_create()80{81 simple_if_init $h2 $h2_ipv4/24 $h2_ipv6/6482 83 ip -4 route add default vrf v$h2 nexthop via 198.51.100.284 ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::285}86 87h2_destroy()88{89 ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::290 ip -4 route del default vrf v$h2 nexthop via 198.51.100.291 92 simple_if_fini $h2 $h2_ipv4/24 $h2_ipv6/6493}94 95router_create()96{97 ip link set dev $rp1 up98 ip link set dev $rp2 up99 100 tc qdisc add dev $rp2 clsact101 102 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64103 __addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64104}105 106router_destroy()107{108 __addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64109 __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64110 111 tc qdisc del dev $rp2 clsact112 113 ip link set dev $rp2 down114 ip link set dev $rp1 down115}116 117setup_prepare()118{119 h1=${NETIFS[p1]}120 rp1=${NETIFS[p2]}121 122 rp2=${NETIFS[p3]}123 h2=${NETIFS[p4]}124 125 h1mac=$(mac_get $h1)126 rp1mac=$(mac_get $rp1)127 128 h1_ipv4=192.0.2.1129 h2_ipv4=198.51.100.1130 h1_ipv6=2001:db8:1::1131 h2_ipv6=2001:db8:2::1132 133 vrf_prepare134 forwarding_enable135 136 h1_create137 h2_create138 139 router_create140}141 142cleanup()143{144 pre_cleanup145 146 router_destroy147 148 h2_destroy149 h1_destroy150 151 forwarding_restore152 vrf_cleanup153}154 155ping_check()156{157 trap_name=$1; shift158 159 devlink_trap_action_set $trap_name "trap"160 ping_do $h1 $h2_ipv4161 check_err $? "Packets that should not be trapped were trapped"162 devlink_trap_action_set $trap_name "drop"163}164 165non_ip_test()166{167 local trap_name="non_ip"168 local mz_pid169 170 RET=0171 172 ping_check $trap_name173 174 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \175 flower dst_ip $h2_ipv4 action drop176 177 # Generate non-IP packets to the router178 $MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \179 00:00 de:ad:be:ef" &180 mz_pid=$!181 182 devlink_trap_drop_test $trap_name $rp2 101183 184 log_test "Non IP"185 186 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101187}188 189__uc_dip_over_mc_dmac_test()190{191 local desc=$1; shift192 local proto=$1; shift193 local dip=$1; shift194 local flags=${1:-""}; shift195 local trap_name="uc_dip_over_mc_dmac"196 local dmac=01:02:03:04:05:06197 local mz_pid198 199 RET=0200 201 ping_check $trap_name202 203 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \204 flower ip_proto udp src_port 54321 dst_port 12345 action drop205 206 # Generate IP packets with a unicast IP and a multicast destination MAC207 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $dmac \208 -B $dip -d 1msec -q &209 mz_pid=$!210 211 devlink_trap_drop_test $trap_name $rp2 101212 213 log_test "Unicast destination IP over multicast destination MAC: $desc"214 215 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101216}217 218uc_dip_over_mc_dmac_test()219{220 __uc_dip_over_mc_dmac_test "IPv4" "ip" $h2_ipv4221 __uc_dip_over_mc_dmac_test "IPv6" "ipv6" $h2_ipv6 "-6"222}223 224__sip_is_loopback_test()225{226 local desc=$1; shift227 local proto=$1; shift228 local sip=$1; shift229 local dip=$1; shift230 local flags=${1:-""}; shift231 local trap_name="sip_is_loopback_address"232 local mz_pid233 234 RET=0235 236 ping_check $trap_name237 238 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \239 flower src_ip $sip action drop240 241 # Generate packets with loopback source IP242 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \243 -b $rp1mac -B $dip -d 1msec -q &244 mz_pid=$!245 246 devlink_trap_drop_test $trap_name $rp2 101247 248 log_test "Source IP is loopback address: $desc"249 250 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101251}252 253sip_is_loopback_test()254{255 __sip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" $h2_ipv4256 __sip_is_loopback_test "IPv6" "ipv6" "::1" $h2_ipv6 "-6"257}258 259__dip_is_loopback_test()260{261 local desc=$1; shift262 local proto=$1; shift263 local dip=$1; shift264 local flags=${1:-""}; shift265 local trap_name="dip_is_loopback_address"266 local mz_pid267 268 RET=0269 270 ping_check $trap_name271 272 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \273 flower dst_ip $dip action drop274 275 # Generate packets with loopback destination IP276 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \277 -B $dip -d 1msec -q &278 mz_pid=$!279 280 devlink_trap_drop_test $trap_name $rp2 101281 282 log_test "Destination IP is loopback address: $desc"283 284 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101285}286 287dip_is_loopback_test()288{289 __dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8"290 __dip_is_loopback_test "IPv6" "ipv6" "::1" "-6"291}292 293__sip_is_mc_test()294{295 local desc=$1; shift296 local proto=$1; shift297 local sip=$1; shift298 local dip=$1; shift299 local flags=${1:-""}; shift300 local trap_name="sip_is_mc"301 local mz_pid302 303 RET=0304 305 ping_check $trap_name306 307 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \308 flower src_ip $sip action drop309 310 # Generate packets with multicast source IP311 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \312 -b $rp1mac -B $dip -d 1msec -q &313 mz_pid=$!314 315 devlink_trap_drop_test $trap_name $rp2 101316 317 log_test "Source IP is multicast: $desc"318 319 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101320}321 322sip_is_mc_test()323{324 __sip_is_mc_test "IPv4" "ip" "239.1.1.1" $h2_ipv4325 __sip_is_mc_test "IPv6" "ipv6" "FF02::2" $h2_ipv6 "-6"326}327 328ipv4_sip_is_limited_bc_test()329{330 local trap_name="ipv4_sip_is_limited_bc"331 local sip=255.255.255.255332 local mz_pid333 334 RET=0335 336 ping_check $trap_name337 338 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \339 flower src_ip $sip action drop340 341 # Generate packets with limited broadcast source IP342 $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip -b $rp1mac \343 -B $h2_ipv4 -d 1msec -q &344 mz_pid=$!345 346 devlink_trap_drop_test $trap_name $rp2 101347 348 log_test "IPv4 source IP is limited broadcast"349 350 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101351}352 353ipv4_payload_get()354{355 local ipver=$1; shift356 local ihl=$1; shift357 local checksum=$1; shift358 359 p=$(:360 )"08:00:"$( : ETH type361 )"$ipver"$( : IP version362 )"$ihl:"$( : IHL363 )"00:"$( : IP TOS364 )"00:F4:"$( : IP total length365 )"00:00:"$( : IP identification366 )"20:00:"$( : IP flags + frag off367 )"30:"$( : IP TTL368 )"01:"$( : IP proto369 )"$checksum:"$( : IP header csum370 )"$h1_ipv4:"$( : IP saddr371 )"$h2_ipv4:"$( : IP daddr372 )373 echo $p374}375 376__ipv4_header_corrupted_test()377{378 local desc=$1; shift379 local ipver=$1; shift380 local ihl=$1; shift381 local checksum=$1; shift382 local trap_name="ip_header_corrupted"383 local payload384 local mz_pid385 386 RET=0387 388 ping_check $trap_name389 390 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \391 flower dst_ip $h2_ipv4 action drop392 393 payload=$(ipv4_payload_get $ipver $ihl $checksum)394 395 # Generate packets with corrupted IP header396 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &397 mz_pid=$!398 399 devlink_trap_drop_test $trap_name $rp2 101400 401 log_test "IP header corrupted: $desc: IPv4"402 403 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101404}405 406ipv6_payload_get()407{408 local ipver=$1; shift409 410 p=$(:411 )"86:DD:"$( : ETH type412 )"$ipver"$( : IP version413 )"0:0:"$( : Traffic class414 )"0:00:00:"$( : Flow label415 )"00:00:"$( : Payload length416 )"01:"$( : Next header417 )"04:"$( : Hop limit418 )"$h1_ipv6:"$( : IP saddr419 )"$h2_ipv6:"$( : IP daddr420 )421 echo $p422}423 424__ipv6_header_corrupted_test()425{426 local desc=$1; shift427 local ipver=$1; shift428 local trap_name="ip_header_corrupted"429 local payload430 local mz_pid431 432 RET=0433 434 ping_check $trap_name435 436 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \437 flower dst_ip $h2_ipv4 action drop438 439 payload=$(ipv6_payload_get $ipver)440 441 # Generate packets with corrupted IP header442 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &443 mz_pid=$!444 445 devlink_trap_drop_test $trap_name $rp2 101446 447 log_test "IP header corrupted: $desc: IPv6"448 449 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101450}451 452ip_header_corrupted_test()453{454 # Each test uses one wrong value. The three values below are correct.455 local ipv="4"456 local ihl="5"457 local checksum="00:F4"458 459 __ipv4_header_corrupted_test "wrong IP version" 5 $ihl $checksum460 __ipv4_header_corrupted_test "wrong IHL" $ipv 4 $checksum461 __ipv4_header_corrupted_test "wrong checksum" $ipv $ihl "00:00"462 __ipv6_header_corrupted_test "wrong IP version" 5463}464 465ipv6_mc_dip_reserved_scope_test()466{467 local trap_name="ipv6_mc_dip_reserved_scope"468 local dip=FF00::469 local mz_pid470 471 RET=0472 473 ping_check $trap_name474 475 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \476 flower dst_ip $dip action drop477 478 # Generate packets with reserved scope destination IP479 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \480 "33:33:00:00:00:00" -B $dip -d 1msec -q &481 mz_pid=$!482 483 devlink_trap_drop_test $trap_name $rp2 101484 485 log_test "IPv6 multicast destination IP reserved scope"486 487 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101488}489 490ipv6_mc_dip_interface_local_scope_test()491{492 local trap_name="ipv6_mc_dip_interface_local_scope"493 local dip=FF01::494 local mz_pid495 496 RET=0497 498 ping_check $trap_name499 500 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \501 flower dst_ip $dip action drop502 503 # Generate packets with interface local scope destination IP504 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \505 "33:33:00:00:00:00" -B $dip -d 1msec -q &506 mz_pid=$!507 508 devlink_trap_drop_test $trap_name $rp2 101509 510 log_test "IPv6 multicast destination IP interface-local scope"511 512 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101513}514 515__blackhole_route_test()516{517 local flags=$1; shift518 local subnet=$1; shift519 local proto=$1; shift520 local dip=$1; shift521 local ip_proto=${1:-"icmp"}; shift522 local trap_name="blackhole_route"523 local mz_pid524 525 RET=0526 527 ping_check $trap_name528 529 ip -$flags route add blackhole $subnet530 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \531 flower skip_hw dst_ip $dip ip_proto $ip_proto action drop532 533 # Generate packets to the blackhole route534 $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \535 -B $dip -d 1msec -q &536 mz_pid=$!537 538 devlink_trap_drop_test $trap_name $rp2 101539 log_test "Blackhole route: IPv$flags"540 541 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101542 ip -$flags route del blackhole $subnet543}544 545blackhole_route_test()546{547 __blackhole_route_test "4" "198.51.100.0/30" "ip" $h2_ipv4548 __blackhole_route_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 "icmpv6"549}550 551irif_disabled_test()552{553 local trap_name="irif_disabled"554 local t0_packets t0_bytes555 local t1_packets t1_bytes556 local mz_pid557 558 RET=0559 560 ping_check $trap_name561 562 devlink_trap_action_set $trap_name "trap"563 564 # When RIF of a physical port ("Sub-port RIF") is destroyed, we first565 # block the STP of the {Port, VLAN} so packets cannot get into the RIF.566 # Using bridge enables us to see this trap because when bridge is567 # destroyed, there is a small time window that packets can go into the568 # RIF, while it is disabled.569 ip link add dev br0 type bridge570 ip link set dev $rp1 master br0571 ip address flush dev $rp1572 __addr_add_del br0 add 192.0.2.2/24573 ip li set dev br0 up574 575 t0_packets=$(devlink_trap_rx_packets_get $trap_name)576 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)577 578 # Generate packets to h2 through br0 RIF that will be removed later579 $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp1mac \580 -B $h2_ipv4 -q &581 mz_pid=$!582 583 # Wait before removing br0 RIF to allow packets to go into the bridge.584 sleep 1585 586 # Flushing address will dismantle the RIF587 ip address flush dev br0588 589 t1_packets=$(devlink_trap_rx_packets_get $trap_name)590 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)591 592 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then593 check_err 1 "Trap stats idle when packets should be trapped"594 fi595 596 log_test "Ingress RIF disabled"597 598 kill $mz_pid && wait $mz_pid &> /dev/null599 ip link set dev $rp1 nomaster600 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64601 ip link del dev br0 type bridge602 devlink_trap_action_set $trap_name "drop"603}604 605erif_disabled_test()606{607 local trap_name="erif_disabled"608 local t0_packets t0_bytes609 local t1_packets t1_bytes610 local mz_pid611 612 RET=0613 614 ping_check $trap_name615 616 devlink_trap_action_set $trap_name "trap"617 ip link add dev br0 type bridge618 ip add flush dev $rp1619 ip link set dev $rp1 master br0620 __addr_add_del br0 add 192.0.2.2/24621 ip link set dev br0 up622 623 t0_packets=$(devlink_trap_rx_packets_get $trap_name)624 t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)625 626 rp2mac=$(mac_get $rp2)627 628 # Generate packets that should go out through br0 RIF that will be629 # removed later630 $MZ $h2 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp2mac \631 -B 192.0.2.1 -q &632 mz_pid=$!633 634 sleep 5635 # Unlinking the port from the bridge will disable the RIF associated636 # with br0 as it is no longer an upper of any mlxsw port.637 ip link set dev $rp1 nomaster638 639 t1_packets=$(devlink_trap_rx_packets_get $trap_name)640 t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)641 642 if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then643 check_err 1 "Trap stats idle when packets should be trapped"644 fi645 646 log_test "Egress RIF disabled"647 648 kill $mz_pid && wait $mz_pid &> /dev/null649 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64650 ip link del dev br0 type bridge651 devlink_trap_action_set $trap_name "drop"652}653 654__blackhole_nexthop_test()655{656 local flags=$1; shift657 local subnet=$1; shift658 local proto=$1; shift659 local dip=$1; shift660 local trap_name="blackhole_nexthop"661 local mz_pid662 663 RET=0664 665 ip -$flags nexthop add id 1 blackhole666 ip -$flags route add $subnet nhid 1667 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \668 flower skip_hw dst_ip $dip ip_proto udp action drop669 670 # Generate packets to the blackhole nexthop671 $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \672 -B $dip -d 1msec -q &673 mz_pid=$!674 675 devlink_trap_drop_test $trap_name $rp2 101676 log_test "Blackhole nexthop: IPv$flags"677 678 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101679 ip -$flags route del $subnet680 ip -$flags nexthop del id 1681}682 683blackhole_nexthop_test()684{685 __blackhole_nexthop_test "4" "198.51.100.0/30" "ip" $h2_ipv4686 __blackhole_nexthop_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6687}688 689trap cleanup EXIT690 691setup_prepare692setup_wait693 694tests_run695 696exit $EXIT_STATUS697