1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test devlink-trap L2 drops functionality over mlxsw. Each registered L2 drop 5# packet trap is tested to make sure it is triggered under the right 6# conditions. 7 8lib_dir=$(dirname $0)/../../../net/forwarding 9 10ALL_TESTS=" 11 source_mac_is_multicast_test 12 vlan_tag_mismatch_test 13 ingress_vlan_filter_test 14 ingress_stp_filter_test 15 port_list_is_empty_test 16 port_loopback_filter_test 17 locked_port_test 18" 19NUM_NETIFS=4 20source $lib_dir/tc_common.sh 21source $lib_dir/lib.sh 22source $lib_dir/devlink_lib.sh 23 24h1_create() 25{ 26 simple_if_init $h1 27} 28 29h1_destroy() 30{ 31 simple_if_fini $h1 32} 33 34h2_create() 35{ 36 simple_if_init $h2 37} 38 39h2_destroy() 40{ 41 simple_if_fini $h2 42} 43 44switch_create() 45{ 46 ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 47 48 ip link set dev $swp1 master br0 49 ip link set dev $swp2 master br0 50 51 ip link set dev br0 up 52 ip link set dev $swp1 up 53 ip link set dev $swp2 up 54 55 tc qdisc add dev $swp2 clsact 56} 57 58switch_destroy() 59{ 60 tc qdisc del dev $swp2 clsact 61 62 ip link set dev $swp2 down 63 ip link set dev $swp1 down 64 65 ip link del dev br0 66} 67 68setup_prepare() 69{ 70 h1=${NETIFS[p1]} 71 swp1=${NETIFS[p2]} 72 73 swp2=${NETIFS[p3]} 74 h2=${NETIFS[p4]} 75 76 vrf_prepare 77 78 h1_create 79 h2_create 80 81 switch_create 82} 83 84cleanup() 85{ 86 pre_cleanup 87 88 switch_destroy 89 90 h2_destroy 91 h1_destroy 92 93 vrf_cleanup 94} 95 96source_mac_is_multicast_test() 97{ 98 local trap_name="source_mac_is_multicast" 99 local smac=01:02:03:04:05:06 100 local mz_pid 101 102 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 103 flower src_mac $smac action drop 104 105 $MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -d 1msec -q & 106 mz_pid=$! 107 108 RET=0 109 110 devlink_trap_drop_test $trap_name $swp2 101 111 112 log_test "Source MAC is multicast" 113 114 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 115} 116 117__vlan_tag_mismatch_test() 118{ 119 local trap_name="vlan_tag_mismatch" 120 local dmac=de:ad:be:ef:13:37 121 local opt=$1; shift 122 local mz_pid 123 124 # Remove PVID flag. This should prevent untagged and prio-tagged 125 # packets from entering the bridge. 126 bridge vlan add vid 1 dev $swp1 untagged master 127 128 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 129 flower dst_mac $dmac action drop 130 131 $MZ $h1 "$opt" -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & 132 mz_pid=$! 133 134 devlink_trap_drop_test $trap_name $swp2 101 135 136 # Add PVID and make sure packets are no longer dropped. 137 bridge vlan add vid 1 dev $swp1 pvid untagged master 138 devlink_trap_action_set $trap_name "trap" 139 140 devlink_trap_stats_idle_test $trap_name 141 check_err $? "Trap stats not idle when packets should not be dropped" 142 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 143 check_err $? "Trap group stats not idle with when packets should not be dropped" 144 145 tc_check_packets "dev $swp2 egress" 101 0 146 check_fail $? "Packets not forwarded when should" 147 148 devlink_trap_action_set $trap_name "drop" 149 150 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 151} 152 153vlan_tag_mismatch_untagged_test() 154{ 155 RET=0 156 157 __vlan_tag_mismatch_test 158 159 log_test "VLAN tag mismatch - untagged packets" 160} 161 162vlan_tag_mismatch_vid_0_test() 163{ 164 RET=0 165 166 __vlan_tag_mismatch_test "-Q 0" 167 168 log_test "VLAN tag mismatch - prio-tagged packets" 169} 170 171vlan_tag_mismatch_test() 172{ 173 vlan_tag_mismatch_untagged_test 174 vlan_tag_mismatch_vid_0_test 175} 176 177ingress_vlan_filter_test() 178{ 179 local trap_name="ingress_vlan_filter" 180 local dmac=de:ad:be:ef:13:37 181 local mz_pid 182 local vid=10 183 184 bridge vlan add vid $vid dev $swp2 master 185 186 RET=0 187 188 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 189 flower dst_mac $dmac action drop 190 191 $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & 192 mz_pid=$! 193 194 devlink_trap_drop_test $trap_name $swp2 101 195 196 # Add the VLAN on the bridge port and make sure packets are no longer 197 # dropped. 198 bridge vlan add vid $vid dev $swp1 master 199 devlink_trap_action_set $trap_name "trap" 200 201 devlink_trap_stats_idle_test $trap_name 202 check_err $? "Trap stats not idle when packets should not be dropped" 203 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 204 check_err $? "Trap group stats not idle with when packets should not be dropped" 205 206 tc_check_packets "dev $swp2 egress" 101 0 207 check_fail $? "Packets not forwarded when should" 208 209 devlink_trap_action_set $trap_name "drop" 210 211 log_test "Ingress VLAN filter" 212 213 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 214 215 bridge vlan del vid $vid dev $swp1 master 216 bridge vlan del vid $vid dev $swp2 master 217} 218 219__ingress_stp_filter_test() 220{ 221 local trap_name="ingress_spanning_tree_filter" 222 local dmac=de:ad:be:ef:13:37 223 local state=$1; shift 224 local mz_pid 225 local vid=20 226 227 bridge vlan add vid $vid dev $swp2 master 228 bridge vlan add vid $vid dev $swp1 master 229 ip link set dev $swp1 type bridge_slave state $state 230 231 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 232 flower dst_mac $dmac action drop 233 234 $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & 235 mz_pid=$! 236 237 devlink_trap_drop_test $trap_name $swp2 101 238 239 # Change STP state to forwarding and make sure packets are no longer 240 # dropped. 241 ip link set dev $swp1 type bridge_slave state 3 242 devlink_trap_action_set $trap_name "trap" 243 244 devlink_trap_stats_idle_test $trap_name 245 check_err $? "Trap stats not idle when packets should not be dropped" 246 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 247 check_err $? "Trap group stats not idle with when packets should not be dropped" 248 249 tc_check_packets "dev $swp2 egress" 101 0 250 check_fail $? "Packets not forwarded when should" 251 252 devlink_trap_action_set $trap_name "drop" 253 254 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 255 256 bridge vlan del vid $vid dev $swp1 master 257 bridge vlan del vid $vid dev $swp2 master 258} 259 260ingress_stp_filter_listening_test() 261{ 262 local state=$1; shift 263 264 RET=0 265 266 __ingress_stp_filter_test $state 267 268 log_test "Ingress STP filter - listening state" 269} 270 271ingress_stp_filter_learning_test() 272{ 273 local state=$1; shift 274 275 RET=0 276 277 __ingress_stp_filter_test $state 278 279 log_test "Ingress STP filter - learning state" 280} 281 282ingress_stp_filter_test() 283{ 284 ingress_stp_filter_listening_test 1 285 ingress_stp_filter_learning_test 2 286} 287 288port_list_is_empty_uc_test() 289{ 290 local trap_name="port_list_is_empty" 291 local dmac=de:ad:be:ef:13:37 292 local mz_pid 293 294 # Disable unicast flooding on both ports, so that packets cannot egress 295 # any port. 296 ip link set dev $swp1 type bridge_slave flood off 297 ip link set dev $swp2 type bridge_slave flood off 298 299 RET=0 300 301 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 302 flower dst_mac $dmac action drop 303 304 $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & 305 mz_pid=$! 306 307 devlink_trap_drop_test $trap_name $swp2 101 308 309 # Allow packets to be flooded to one port. 310 ip link set dev $swp2 type bridge_slave flood on 311 devlink_trap_action_set $trap_name "trap" 312 313 devlink_trap_stats_idle_test $trap_name 314 check_err $? "Trap stats not idle when packets should not be dropped" 315 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 316 check_err $? "Trap group stats not idle with when packets should not be dropped" 317 318 tc_check_packets "dev $swp2 egress" 101 0 319 check_fail $? "Packets not forwarded when should" 320 321 devlink_trap_action_set $trap_name "drop" 322 323 log_test "Port list is empty - unicast" 324 325 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 326 327 ip link set dev $swp1 type bridge_slave flood on 328} 329 330port_list_is_empty_mc_test() 331{ 332 local trap_name="port_list_is_empty" 333 local dmac=01:00:5e:00:00:01 334 local dip=239.0.0.1 335 local mz_pid 336 337 # Disable multicast flooding on both ports, so that packets cannot 338 # egress any port. We also need to flush IP addresses from the bridge 339 # in order to prevent packets from being flooded to the router port. 340 ip link set dev $swp1 type bridge_slave mcast_flood off 341 ip link set dev $swp2 type bridge_slave mcast_flood off 342 ip address flush dev br0 343 344 RET=0 345 346 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 347 flower dst_mac $dmac action drop 348 349 $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -B $dip -d 1msec -q & 350 mz_pid=$! 351 352 devlink_trap_drop_test $trap_name $swp2 101 353 354 # Allow packets to be flooded to one port. 355 ip link set dev $swp2 type bridge_slave mcast_flood on 356 devlink_trap_action_set $trap_name "trap" 357 358 devlink_trap_stats_idle_test $trap_name 359 check_err $? "Trap stats not idle when packets should not be dropped" 360 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 361 check_err $? "Trap group stats not idle with when packets should not be dropped" 362 363 tc_check_packets "dev $swp2 egress" 101 0 364 check_fail $? "Packets not forwarded when should" 365 366 devlink_trap_action_set $trap_name "drop" 367 368 log_test "Port list is empty - multicast" 369 370 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 371 372 ip link set dev $swp1 type bridge_slave mcast_flood on 373} 374 375port_list_is_empty_test() 376{ 377 port_list_is_empty_uc_test 378 port_list_is_empty_mc_test 379} 380 381port_loopback_filter_uc_test() 382{ 383 local trap_name="port_loopback_filter" 384 local dmac=de:ad:be:ef:13:37 385 local mz_pid 386 387 # Make sure packets can only egress the input port. 388 ip link set dev $swp2 type bridge_slave flood off 389 390 RET=0 391 392 tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ 393 flower dst_mac $dmac action drop 394 395 $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & 396 mz_pid=$! 397 398 devlink_trap_drop_test $trap_name $swp2 101 399 400 # Allow packets to be flooded. 401 ip link set dev $swp2 type bridge_slave flood on 402 devlink_trap_action_set $trap_name "trap" 403 404 devlink_trap_stats_idle_test $trap_name 405 check_err $? "Trap stats not idle when packets should not be dropped" 406 devlink_trap_group_stats_idle_test $(devlink_trap_group_get $trap_name) 407 check_err $? "Trap group stats not idle with when packets should not be dropped" 408 409 tc_check_packets "dev $swp2 egress" 101 0 410 check_fail $? "Packets not forwarded when should" 411 412 devlink_trap_action_set $trap_name "drop" 413 414 log_test "Port loopback filter - unicast" 415 416 devlink_trap_drop_cleanup $mz_pid $swp2 ip 1 101 417} 418 419port_loopback_filter_test() 420{ 421 port_loopback_filter_uc_test 422} 423 424locked_port_miss_test() 425{ 426 local trap_name="locked_port" 427 local smac=00:11:22:33:44:55 428 429 bridge link set dev $swp1 learning off 430 bridge link set dev $swp1 locked on 431 432 RET=0 433 434 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 435 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 436 check_fail $? "Trap stats increased before setting action to \"trap\"" 437 438 devlink_trap_action_set $trap_name "trap" 439 440 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 441 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 442 check_err $? "Trap stats did not increase when should" 443 444 devlink_trap_action_set $trap_name "drop" 445 446 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 447 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 448 check_fail $? "Trap stats increased after setting action to \"drop\"" 449 450 devlink_trap_action_set $trap_name "trap" 451 452 bridge fdb replace $smac dev $swp1 master static vlan 1 453 454 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 455 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 456 check_fail $? "Trap stats increased after adding an FDB entry" 457 458 bridge fdb del $smac dev $swp1 master static vlan 1 459 bridge link set dev $swp1 locked off 460 461 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 462 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 463 check_fail $? "Trap stats increased after unlocking port" 464 465 log_test "Locked port - FDB miss" 466 467 devlink_trap_action_set $trap_name "drop" 468 bridge link set dev $swp1 learning on 469} 470 471locked_port_mismatch_test() 472{ 473 local trap_name="locked_port" 474 local smac=00:11:22:33:44:55 475 476 bridge link set dev $swp1 learning off 477 bridge link set dev $swp1 locked on 478 479 RET=0 480 481 bridge fdb replace $smac dev $swp2 master static vlan 1 482 483 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 484 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 485 check_fail $? "Trap stats increased before setting action to \"trap\"" 486 487 devlink_trap_action_set $trap_name "trap" 488 489 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 490 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 491 check_err $? "Trap stats did not increase when should" 492 493 devlink_trap_action_set $trap_name "drop" 494 495 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 496 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 497 check_fail $? "Trap stats increased after setting action to \"drop\"" 498 499 devlink_trap_action_set $trap_name "trap" 500 bridge link set dev $swp1 locked off 501 502 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 503 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 504 check_fail $? "Trap stats increased after unlocking port" 505 506 bridge link set dev $swp1 locked on 507 bridge fdb replace $smac dev $swp1 master static vlan 1 508 509 devlink_trap_stats_check $trap_name $MZ $h1 -c 1 \ 510 -a $smac -b $(mac_get $h2) -A 192.0.2.1 -B 192.0.2.2 -p 100 -q 511 check_fail $? "Trap stats increased after replacing an FDB entry" 512 513 bridge fdb del $smac dev $swp1 master static vlan 1 514 devlink_trap_action_set $trap_name "drop" 515 516 log_test "Locked port - FDB mismatch" 517 518 bridge link set dev $swp1 locked off 519 bridge link set dev $swp1 learning on 520} 521 522locked_port_test() 523{ 524 locked_port_miss_test 525 locked_port_mismatch_test 526} 527 528trap cleanup EXIT 529 530setup_prepare 531setup_wait 532 533tests_run 534 535exit $EXIT_STATUS 536