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 40lib_dir=$(dirname $0)/../../../net/forwarding 41 42ALL_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" 54 55NUM_NETIFS=4 56source $lib_dir/lib.sh 57source $lib_dir/tc_common.sh 58source $lib_dir/devlink_lib.sh 59 60h1_create() 61{ 62 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64 63 64 ip -4 route add default vrf v$h1 nexthop via 192.0.2.2 65 ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::2 66} 67 68h1_destroy() 69{ 70 ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::2 71 ip -4 route del default vrf v$h1 nexthop via 192.0.2.2 72 73 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64 74} 75 76h2_create() 77{ 78 simple_if_init $h2 $h2_ipv4/24 $h2_ipv6/64 79 80 ip -4 route add default vrf v$h2 nexthop via 198.51.100.2 81 ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::2 82} 83 84h2_destroy() 85{ 86 ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::2 87 ip -4 route del default vrf v$h2 nexthop via 198.51.100.2 88 89 simple_if_fini $h2 $h2_ipv4/24 $h2_ipv6/64 90} 91 92router_create() 93{ 94 ip link set dev $rp1 up 95 ip link set dev $rp2 up 96 97 tc qdisc add dev $rp2 clsact 98 99 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64 100 __addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64 101} 102 103router_destroy() 104{ 105 __addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64 106 __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64 107 108 tc qdisc del dev $rp2 clsact 109} 110 111setup_prepare() 112{ 113 h1=${NETIFS[p1]} 114 rp1=${NETIFS[p2]} 115 116 rp2=${NETIFS[p3]} 117 h2=${NETIFS[p4]} 118 119 h1mac=$(mac_get $h1) 120 rp1mac=$(mac_get $rp1) 121 122 h1_ipv4=192.0.2.1 123 h2_ipv4=198.51.100.1 124 h1_ipv6=2001:db8:1::1 125 h2_ipv6=2001:db8:2::1 126 127 vrf_prepare 128 forwarding_enable 129 130 h1_create 131 h2_create 132 133 router_create 134} 135 136cleanup() 137{ 138 pre_cleanup 139 140 router_destroy 141 142 h2_destroy 143 h1_destroy 144 145 forwarding_restore 146 vrf_cleanup 147} 148 149ping_check() 150{ 151 trap_name=$1; shift 152 153 devlink_trap_action_set $trap_name "trap" 154 ping_do $h1 $h2_ipv4 155 check_err $? "Packets that should not be trapped were trapped" 156 devlink_trap_action_set $trap_name "drop" 157} 158 159non_ip_test() 160{ 161 local trap_name="non_ip" 162 local group_name="l3_drops" 163 local mz_pid 164 165 RET=0 166 167 ping_check $trap_name 168 169 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 170 flower dst_ip $h2_ipv4 action drop 171 172 # Generate non-IP packets to the router 173 $MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \ 174 00:00 de:ad:be:ef" & 175 mz_pid=$! 176 177 devlink_trap_drop_test $trap_name $group_name $rp2 178 179 log_test "Non IP" 180 181 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 182} 183 184__uc_dip_over_mc_dmac_test() 185{ 186 local desc=$1; shift 187 local proto=$1; shift 188 local dip=$1; shift 189 local flags=${1:-""}; shift 190 local trap_name="uc_dip_over_mc_dmac" 191 local group_name="l3_drops" 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 $group_name $rp2 208 209 log_test "Unicast destination IP over multicast destination MAC: $desc" 210 211 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 212} 213 214uc_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 group_name="l3_drops" 229 local mz_pid 230 231 RET=0 232 233 ping_check $trap_name 234 235 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ 236 flower src_ip $sip action drop 237 238 # Generate packets with loopback source IP 239 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \ 240 -b $rp1mac -B $dip -d 1msec -q & 241 mz_pid=$! 242 243 devlink_trap_drop_test $trap_name $group_name $rp2 244 245 log_test "Source IP is loopback address: $desc" 246 247 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 248} 249 250sip_is_loopback_test() 251{ 252 __sip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" $h2_ipv4 253 __sip_is_loopback_test "IPv6" "ipv6" "::1" $h2_ipv6 "-6" 254} 255 256__dip_is_loopback_test() 257{ 258 local desc=$1; shift 259 local proto=$1; shift 260 local dip=$1; shift 261 local flags=${1:-""}; shift 262 local trap_name="dip_is_loopback_address" 263 local group_name="l3_drops" 264 local mz_pid 265 266 RET=0 267 268 ping_check $trap_name 269 270 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ 271 flower dst_ip $dip action drop 272 273 # Generate packets with loopback destination IP 274 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \ 275 -B $dip -d 1msec -q & 276 mz_pid=$! 277 278 devlink_trap_drop_test $trap_name $group_name $rp2 279 280 log_test "Destination IP is loopback address: $desc" 281 282 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 283} 284 285dip_is_loopback_test() 286{ 287 __dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" 288 __dip_is_loopback_test "IPv6" "ipv6" "::1" "-6" 289} 290 291__sip_is_mc_test() 292{ 293 local desc=$1; shift 294 local proto=$1; shift 295 local sip=$1; shift 296 local dip=$1; shift 297 local flags=${1:-""}; shift 298 local trap_name="sip_is_mc" 299 local group_name="l3_drops" 300 local mz_pid 301 302 RET=0 303 304 ping_check $trap_name 305 306 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ 307 flower src_ip $sip action drop 308 309 # Generate packets with multicast source IP 310 $MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \ 311 -b $rp1mac -B $dip -d 1msec -q & 312 mz_pid=$! 313 314 devlink_trap_drop_test $trap_name $group_name $rp2 315 316 log_test "Source IP is multicast: $desc" 317 318 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 319} 320 321sip_is_mc_test() 322{ 323 __sip_is_mc_test "IPv4" "ip" "239.1.1.1" $h2_ipv4 324 __sip_is_mc_test "IPv6" "ipv6" "FF02::2" $h2_ipv6 "-6" 325} 326 327ipv4_sip_is_limited_bc_test() 328{ 329 local trap_name="ipv4_sip_is_limited_bc" 330 local group_name="l3_drops" 331 local sip=255.255.255.255 332 local mz_pid 333 334 RET=0 335 336 ping_check $trap_name 337 338 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 339 flower src_ip $sip action drop 340 341 # Generate packets with limited broadcast source IP 342 $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 $group_name $rp2 347 348 log_test "IPv4 source IP is limited broadcast" 349 350 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 351} 352 353ipv4_payload_get() 354{ 355 local ipver=$1; shift 356 local ihl=$1; shift 357 local checksum=$1; shift 358 359 p=$(: 360 )"08:00:"$( : ETH type 361 )"$ipver"$( : IP version 362 )"$ihl:"$( : IHL 363 )"00:"$( : IP TOS 364 )"00:F4:"$( : IP total length 365 )"00:00:"$( : IP identification 366 )"20:00:"$( : IP flags + frag off 367 )"30:"$( : IP TTL 368 )"01:"$( : IP proto 369 )"$checksum:"$( : IP header csum 370 )"$h1_ipv4:"$( : IP saddr 371 )"$h2_ipv4:"$( : IP daddr 372 ) 373 echo $p 374} 375 376__ipv4_header_corrupted_test() 377{ 378 local desc=$1; shift 379 local ipver=$1; shift 380 local ihl=$1; shift 381 local checksum=$1; shift 382 local trap_name="ip_header_corrupted" 383 local group_name="l3_drops" 384 local payload 385 local mz_pid 386 387 RET=0 388 389 ping_check $trap_name 390 391 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 392 flower dst_ip $h2_ipv4 action drop 393 394 payload=$(ipv4_payload_get $ipver $ihl $checksum) 395 396 # Generate packets with corrupted IP header 397 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload & 398 mz_pid=$! 399 400 devlink_trap_drop_test $trap_name $group_name $rp2 401 402 log_test "IP header corrupted: $desc: IPv4" 403 404 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 405} 406 407ipv6_payload_get() 408{ 409 local ipver=$1; shift 410 411 p=$(: 412 )"86:DD:"$( : ETH type 413 )"$ipver"$( : IP version 414 )"0:0:"$( : Traffic class 415 )"0:00:00:"$( : Flow label 416 )"00:00:"$( : Payload length 417 )"01:"$( : Next header 418 )"04:"$( : Hop limit 419 )"$h1_ipv6:"$( : IP saddr 420 )"$h2_ipv6:"$( : IP daddr 421 ) 422 echo $p 423} 424 425__ipv6_header_corrupted_test() 426{ 427 local desc=$1; shift 428 local ipver=$1; shift 429 local trap_name="ip_header_corrupted" 430 local group_name="l3_drops" 431 local payload 432 local mz_pid 433 434 RET=0 435 436 ping_check $trap_name 437 438 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 439 flower dst_ip $h2_ipv4 action drop 440 441 payload=$(ipv6_payload_get $ipver) 442 443 # Generate packets with corrupted IP header 444 $MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload & 445 mz_pid=$! 446 447 devlink_trap_drop_test $trap_name $group_name $rp2 448 449 log_test "IP header corrupted: $desc: IPv6" 450 451 devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 452} 453 454ip_header_corrupted_test() 455{ 456 # Each test uses one wrong value. The three values below are correct. 457 local ipv="4" 458 local ihl="5" 459 local checksum="00:F4" 460 461 __ipv4_header_corrupted_test "wrong IP version" 5 $ihl $checksum 462 __ipv4_header_corrupted_test "wrong IHL" $ipv 4 $checksum 463 __ipv4_header_corrupted_test "wrong checksum" $ipv $ihl "00:00" 464 __ipv6_header_corrupted_test "wrong IP version" 5 465} 466 467ipv6_mc_dip_reserved_scope_test() 468{ 469 local trap_name="ipv6_mc_dip_reserved_scope" 470 local group_name="l3_drops" 471 local dip=FF00:: 472 local mz_pid 473 474 RET=0 475 476 ping_check $trap_name 477 478 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \ 479 flower dst_ip $dip action drop 480 481 # Generate packets with reserved scope destination IP 482 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \ 483 "33:33:00:00:00:00" -B $dip -d 1msec -q & 484 mz_pid=$! 485 486 devlink_trap_drop_test $trap_name $group_name $rp2 487 488 log_test "IPv6 multicast destination IP reserved scope" 489 490 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 491} 492 493ipv6_mc_dip_interface_local_scope_test() 494{ 495 local trap_name="ipv6_mc_dip_interface_local_scope" 496 local group_name="l3_drops" 497 local dip=FF01:: 498 local mz_pid 499 500 RET=0 501 502 ping_check $trap_name 503 504 tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \ 505 flower dst_ip $dip action drop 506 507 # Generate packets with interface local scope destination IP 508 $MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \ 509 "33:33:00:00:00:00" -B $dip -d 1msec -q & 510 mz_pid=$! 511 512 devlink_trap_drop_test $trap_name $group_name $rp2 513 514 log_test "IPv6 multicast destination IP interface-local scope" 515 516 devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 517} 518 519__blackhole_route_test() 520{ 521 local flags=$1; shift 522 local subnet=$1; shift 523 local proto=$1; shift 524 local dip=$1; shift 525 local ip_proto=${1:-"icmp"}; shift 526 local trap_name="blackhole_route" 527 local group_name="l3_drops" 528 local mz_pid 529 530 RET=0 531 532 ping_check $trap_name 533 534 ip -$flags route add blackhole $subnet 535 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ 536 flower skip_hw dst_ip $dip ip_proto $ip_proto action drop 537 538 # Generate packets to the blackhole route 539 $MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \ 540 -B $dip -d 1msec -q & 541 mz_pid=$! 542 543 devlink_trap_drop_test $trap_name $group_name $rp2 544 log_test "Blackhole route: IPv$flags" 545 546 devlink_trap_drop_cleanup $mz_pid $rp2 $proto 547 ip -$flags route del blackhole $subnet 548} 549 550blackhole_route_test() 551{ 552 __blackhole_route_test "4" "198.51.100.0/30" "ip" $h2_ipv4 553 __blackhole_route_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 "icmpv6" 554} 555 556trap cleanup EXIT 557 558setup_prepare 559setup_wait 560 561tests_run 562 563exit $EXIT_STATUS 564