1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This test is for checking the A-TCAM and C-TCAM operation in Spectrum-2. 5# It tries to exercise as many code paths in the eRP state machine as 6# possible. 7 8lib_dir=$(dirname $0)/../../../../net/forwarding 9 10ALL_TESTS="single_mask_test identical_filters_test two_masks_test \ 11 multiple_masks_test ctcam_edge_cases_test delta_simple_test \ 12 delta_two_masks_one_key_test delta_simple_rehash_test \ 13 bloom_simple_test bloom_complex_test bloom_delta_test" 14NUM_NETIFS=2 15source $lib_dir/tc_common.sh 16source $lib_dir/devlink_lib.sh 17 18tcflags="skip_hw" 19 20h1_create() 21{ 22 simple_if_init $h1 192.0.2.1/24 198.51.100.1/24 23} 24 25h1_destroy() 26{ 27 simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24 28} 29 30h2_create() 31{ 32 simple_if_init $h2 192.0.2.2/24 198.51.100.2/24 33 tc qdisc add dev $h2 clsact 34} 35 36h2_destroy() 37{ 38 tc qdisc del dev $h2 clsact 39 simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24 40} 41 42tp_record() 43{ 44 local tracepoint=$1 45 local cmd=$2 46 47 perf record -q -e $tracepoint $cmd 48 return $? 49} 50 51tp_record_all() 52{ 53 local tracepoint=$1 54 local seconds=$2 55 56 perf record -a -q -e $tracepoint sleep $seconds 57 return $? 58} 59 60__tp_hit_count() 61{ 62 local tracepoint=$1 63 64 local perf_output=`perf script -F trace:event,trace` 65 return `echo $perf_output | grep "$tracepoint:" | wc -l` 66} 67 68tp_check_hits() 69{ 70 local tracepoint=$1 71 local count=$2 72 73 __tp_hit_count $tracepoint 74 if [[ "$?" -ne "$count" ]]; then 75 return 1 76 fi 77 return 0 78} 79 80tp_check_hits_any() 81{ 82 local tracepoint=$1 83 84 __tp_hit_count $tracepoint 85 if [[ "$?" -eq "0" ]]; then 86 return 1 87 fi 88 return 0 89} 90 91single_mask_test() 92{ 93 # When only a single mask is required, the device uses the master 94 # mask and not the eRP table. Verify that under this mode the right 95 # filter is matched 96 97 RET=0 98 99 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 100 $tcflags dst_ip 192.0.2.2 action drop 101 102 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 103 -t ip -q 104 105 tc_check_packets "dev $h2 ingress" 101 1 106 check_err $? "Single filter - did not match" 107 108 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 109 $tcflags dst_ip 198.51.100.2 action drop 110 111 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 112 -t ip -q 113 114 tc_check_packets "dev $h2 ingress" 101 2 115 check_err $? "Two filters - did not match highest priority" 116 117 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 118 -t ip -q 119 120 tc_check_packets "dev $h2 ingress" 102 1 121 check_err $? "Two filters - did not match lowest priority" 122 123 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 124 125 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 126 -t ip -q 127 128 tc_check_packets "dev $h2 ingress" 102 2 129 check_err $? "Single filter - did not match after delete" 130 131 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 132 133 log_test "single mask test ($tcflags)" 134} 135 136identical_filters_test() 137{ 138 # When two filters that only differ in their priority are used, 139 # one needs to be inserted into the C-TCAM. This test verifies 140 # that filters are correctly spilled to C-TCAM and that the right 141 # filter is matched 142 143 RET=0 144 145 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 146 $tcflags dst_ip 192.0.2.2 action drop 147 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 148 $tcflags dst_ip 192.0.2.2 action drop 149 150 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 151 -t ip -q 152 153 tc_check_packets "dev $h2 ingress" 101 1 154 check_err $? "Did not match A-TCAM filter" 155 156 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 157 158 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 159 -t ip -q 160 161 tc_check_packets "dev $h2 ingress" 102 1 162 check_err $? "Did not match C-TCAM filter after A-TCAM delete" 163 164 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 165 $tcflags dst_ip 192.0.2.2 action drop 166 167 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 168 -t ip -q 169 170 tc_check_packets "dev $h2 ingress" 102 2 171 check_err $? "Did not match C-TCAM filter after A-TCAM add" 172 173 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 174 175 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 176 -t ip -q 177 178 tc_check_packets "dev $h2 ingress" 103 1 179 check_err $? "Did not match A-TCAM filter after C-TCAM delete" 180 181 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 182 183 log_test "identical filters test ($tcflags)" 184} 185 186two_masks_test() 187{ 188 # When more than one mask is required, the eRP table is used. This 189 # test verifies that the eRP table is correctly allocated and used 190 191 RET=0 192 193 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 194 $tcflags dst_ip 192.0.2.2 action drop 195 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 196 $tcflags dst_ip 192.0.0.0/8 action drop 197 198 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 199 -t ip -q 200 201 tc_check_packets "dev $h2 ingress" 101 1 202 check_err $? "Two filters - did not match highest priority" 203 204 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 205 206 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 207 -t ip -q 208 209 tc_check_packets "dev $h2 ingress" 103 1 210 check_err $? "Single filter - did not match" 211 212 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 213 $tcflags dst_ip 192.0.2.0/24 action drop 214 215 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 216 -t ip -q 217 218 tc_check_packets "dev $h2 ingress" 102 1 219 check_err $? "Two filters - did not match highest priority after add" 220 221 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 222 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 223 224 log_test "two masks test ($tcflags)" 225} 226 227multiple_masks_test() 228{ 229 # The number of masks in a region is limited. Once the maximum 230 # number of masks has been reached filters that require new 231 # masks are spilled to the C-TCAM. This test verifies that 232 # spillage is performed correctly and that the right filter is 233 # matched 234 235 if [[ "$tcflags" != "skip_sw" ]]; then 236 return 0; 237 fi 238 239 local index 240 241 RET=0 242 243 NUM_MASKS=32 244 NUM_ERPS=16 245 BASE_INDEX=100 246 247 for i in $(eval echo {1..$NUM_MASKS}); do 248 index=$((BASE_INDEX - i)) 249 250 if ((i > NUM_ERPS)); then 251 exp_hits=1 252 err_msg="$i filters - C-TCAM spill did not happen when it was expected" 253 else 254 exp_hits=0 255 err_msg="$i filters - C-TCAM spill happened when it should not" 256 fi 257 258 tp_record "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" \ 259 "tc filter add dev $h2 ingress protocol ip pref $index \ 260 handle $index \ 261 flower $tcflags \ 262 dst_ip 192.0.2.2/${i} src_ip 192.0.2.1/${i} \ 263 action drop" 264 tp_check_hits "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" \ 265 $exp_hits 266 check_err $? "$err_msg" 267 268 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ 269 -B 192.0.2.2 -t ip -q 270 271 tc_check_packets "dev $h2 ingress" $index 1 272 check_err $? "$i filters - did not match highest priority (add)" 273 done 274 275 for i in $(eval echo {$NUM_MASKS..1}); do 276 index=$((BASE_INDEX - i)) 277 278 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ 279 -B 192.0.2.2 -t ip -q 280 281 tc_check_packets "dev $h2 ingress" $index 2 282 check_err $? "$i filters - did not match highest priority (del)" 283 284 tc filter del dev $h2 ingress protocol ip pref $index \ 285 handle $index flower 286 done 287 288 log_test "multiple masks test ($tcflags)" 289} 290 291ctcam_two_atcam_masks_test() 292{ 293 RET=0 294 295 # First case: C-TCAM is disabled when there are two A-TCAM masks. 296 # We push a filter into the C-TCAM by using two identical filters 297 # as in identical_filters_test() 298 299 # Filter goes into A-TCAM 300 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 301 $tcflags dst_ip 192.0.2.2 action drop 302 # Filter goes into C-TCAM 303 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 304 $tcflags dst_ip 192.0.2.2 action drop 305 # Filter goes into A-TCAM 306 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 307 $tcflags dst_ip 192.0.0.0/16 action drop 308 309 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 310 -t ip -q 311 312 tc_check_packets "dev $h2 ingress" 101 1 313 check_err $? "Did not match A-TCAM filter" 314 315 # Delete both A-TCAM and C-TCAM filters and make sure the remaining 316 # A-TCAM filter still works 317 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 318 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 319 320 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 321 -t ip -q 322 323 tc_check_packets "dev $h2 ingress" 103 1 324 check_err $? "Did not match A-TCAM filter" 325 326 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 327 328 log_test "ctcam with two atcam masks test ($tcflags)" 329} 330 331ctcam_one_atcam_mask_test() 332{ 333 RET=0 334 335 # Second case: C-TCAM is disabled when there is one A-TCAM mask. 336 # The test is similar to identical_filters_test() 337 338 # Filter goes into A-TCAM 339 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 340 $tcflags dst_ip 192.0.2.2 action drop 341 # Filter goes into C-TCAM 342 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 343 $tcflags dst_ip 192.0.2.2 action drop 344 345 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 346 -t ip -q 347 348 tc_check_packets "dev $h2 ingress" 101 1 349 check_err $? "Did not match C-TCAM filter" 350 351 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 352 353 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 354 -t ip -q 355 356 tc_check_packets "dev $h2 ingress" 102 1 357 check_err $? "Did not match A-TCAM filter" 358 359 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 360 361 log_test "ctcam with one atcam mask test ($tcflags)" 362} 363 364ctcam_no_atcam_masks_test() 365{ 366 RET=0 367 368 # Third case: C-TCAM is disabled when there are no A-TCAM masks 369 # This test exercises the code path that transitions the eRP table 370 # to its initial state after deleting the last C-TCAM mask 371 372 # Filter goes into A-TCAM 373 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 374 $tcflags dst_ip 192.0.2.2 action drop 375 # Filter goes into C-TCAM 376 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 377 $tcflags dst_ip 192.0.2.2 action drop 378 379 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 380 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 381 382 log_test "ctcam with no atcam masks test ($tcflags)" 383} 384 385ctcam_edge_cases_test() 386{ 387 # When the C-TCAM is disabled after deleting the last C-TCAM 388 # mask, we want to make sure the eRP state machine is put in 389 # the correct state 390 391 ctcam_two_atcam_masks_test 392 ctcam_one_atcam_mask_test 393 ctcam_no_atcam_masks_test 394} 395 396delta_simple_test() 397{ 398 # The first filter will create eRP, the second filter will fit into 399 # the first eRP with delta. Remove the first rule then and check that 400 # the eRP stays (referenced by the second filter). 401 402 RET=0 403 404 if [[ "$tcflags" != "skip_sw" ]]; then 405 return 0; 406 fi 407 408 tp_record "objagg:*" "tc filter add dev $h2 ingress protocol ip \ 409 pref 1 handle 101 flower $tcflags dst_ip 192.0.0.0/24 \ 410 action drop" 411 tp_check_hits "objagg:objagg_obj_root_create" 1 412 check_err $? "eRP was not created" 413 414 tp_record "objagg:*" "tc filter add dev $h2 ingress protocol ip \ 415 pref 2 handle 102 flower $tcflags dst_ip 192.0.2.2 \ 416 action drop" 417 tp_check_hits "objagg:objagg_obj_root_create" 0 418 check_err $? "eRP was incorrectly created" 419 tp_check_hits "objagg:objagg_obj_parent_assign" 1 420 check_err $? "delta was not created" 421 422 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 423 -t ip -q 424 425 tc_check_packets "dev $h2 ingress" 101 1 426 check_fail $? "Matched a wrong filter" 427 428 tc_check_packets "dev $h2 ingress" 102 1 429 check_err $? "Did not match on correct filter" 430 431 tp_record "objagg:*" "tc filter del dev $h2 ingress protocol ip \ 432 pref 1 handle 101 flower" 433 tp_check_hits "objagg:objagg_obj_root_destroy" 0 434 check_err $? "eRP was incorrectly destroyed" 435 tp_check_hits "objagg:objagg_obj_parent_unassign" 0 436 check_err $? "delta was incorrectly destroyed" 437 438 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 439 -t ip -q 440 441 tc_check_packets "dev $h2 ingress" 102 2 442 check_err $? "Did not match on correct filter after the first was removed" 443 444 tp_record "objagg:*" "tc filter del dev $h2 ingress protocol ip \ 445 pref 2 handle 102 flower" 446 tp_check_hits "objagg:objagg_obj_parent_unassign" 1 447 check_err $? "delta was not destroyed" 448 tp_check_hits "objagg:objagg_obj_root_destroy" 1 449 check_err $? "eRP was not destroyed" 450 451 log_test "delta simple test ($tcflags)" 452} 453 454delta_two_masks_one_key_test() 455{ 456 # If 2 keys are the same and only differ in mask in a way that 457 # they belong under the same ERP (second is delta of the first), 458 # there should be no C-TCAM spill. 459 460 RET=0 461 462 if [[ "$tcflags" != "skip_sw" ]]; then 463 return 0; 464 fi 465 466 tp_record "mlxsw:*" "tc filter add dev $h2 ingress protocol ip \ 467 pref 1 handle 101 flower $tcflags dst_ip 192.0.2.0/24 \ 468 action drop" 469 tp_check_hits "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" 0 470 check_err $? "incorrect C-TCAM spill while inserting the first rule" 471 472 tp_record "mlxsw:*" "tc filter add dev $h2 ingress protocol ip \ 473 pref 2 handle 102 flower $tcflags dst_ip 192.0.2.2 \ 474 action drop" 475 tp_check_hits "mlxsw:mlxsw_sp_acl_atcam_entry_add_ctcam_spill" 0 476 check_err $? "incorrect C-TCAM spill while inserting the second rule" 477 478 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 479 -t ip -q 480 481 tc_check_packets "dev $h2 ingress" 101 1 482 check_err $? "Did not match on correct filter" 483 484 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 485 486 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 487 -t ip -q 488 489 tc_check_packets "dev $h2 ingress" 102 1 490 check_err $? "Did not match on correct filter" 491 492 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 493 494 log_test "delta two masks one key test ($tcflags)" 495} 496 497delta_simple_rehash_test() 498{ 499 RET=0 500 501 if [[ "$tcflags" != "skip_sw" ]]; then 502 return 0; 503 fi 504 505 devlink dev param set $DEVLINK_DEV \ 506 name acl_region_rehash_interval cmode runtime value 0 507 check_err $? "Failed to set ACL region rehash interval" 508 509 tp_record_all mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 7 510 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 511 check_fail $? "Rehash trace was hit even when rehash should be disabled" 512 513 devlink dev param set $DEVLINK_DEV \ 514 name acl_region_rehash_interval cmode runtime value 3000 515 check_err $? "Failed to set ACL region rehash interval" 516 517 sleep 1 518 519 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 520 $tcflags dst_ip 192.0.1.0/25 action drop 521 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 522 $tcflags dst_ip 192.0.2.2 action drop 523 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 524 $tcflags dst_ip 192.0.3.0/24 action drop 525 526 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 527 -t ip -q 528 529 tc_check_packets "dev $h2 ingress" 101 1 530 check_fail $? "Matched a wrong filter" 531 532 tc_check_packets "dev $h2 ingress" 103 1 533 check_fail $? "Matched a wrong filter" 534 535 tc_check_packets "dev $h2 ingress" 102 1 536 check_err $? "Did not match on correct filter" 537 538 tp_record_all mlxsw:* 3 539 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 540 check_err $? "Rehash trace was not hit" 541 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate 542 check_err $? "Migrate trace was not hit" 543 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate_end 544 check_err $? "Migrate end trace was not hit" 545 tp_record_all mlxsw:* 3 546 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 547 check_err $? "Rehash trace was not hit" 548 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate 549 check_fail $? "Migrate trace was hit when no migration should happen" 550 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate_end 551 check_fail $? "Migrate end trace was hit when no migration should happen" 552 553 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 554 -t ip -q 555 556 tc_check_packets "dev $h2 ingress" 101 1 557 check_fail $? "Matched a wrong filter after rehash" 558 559 tc_check_packets "dev $h2 ingress" 103 1 560 check_fail $? "Matched a wrong filter after rehash" 561 562 tc_check_packets "dev $h2 ingress" 102 2 563 check_err $? "Did not match on correct filter after rehash" 564 565 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 566 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 567 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 568 569 log_test "delta simple rehash test ($tcflags)" 570} 571 572delta_simple_ipv6_rehash_test() 573{ 574 RET=0 575 576 if [[ "$tcflags" != "skip_sw" ]]; then 577 return 0; 578 fi 579 580 devlink dev param set $DEVLINK_DEV \ 581 name acl_region_rehash_interval cmode runtime value 0 582 check_err $? "Failed to set ACL region rehash interval" 583 584 tp_record_all mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 7 585 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 586 check_fail $? "Rehash trace was hit even when rehash should be disabled" 587 588 devlink dev param set $DEVLINK_DEV \ 589 name acl_region_rehash_interval cmode runtime value 3000 590 check_err $? "Failed to set ACL region rehash interval" 591 592 sleep 1 593 594 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 101 flower \ 595 $tcflags dst_ip 2001:db8:1::0/121 action drop 596 tc filter add dev $h2 ingress protocol ipv6 pref 2 handle 102 flower \ 597 $tcflags dst_ip 2001:db8:2::2 action drop 598 tc filter add dev $h2 ingress protocol ipv6 pref 3 handle 103 flower \ 599 $tcflags dst_ip 2001:db8:3::0/120 action drop 600 601 $MZ $h1 -6 -c 1 -p 64 -a $h1mac -b $h2mac \ 602 -A 2001:db8:2::1 -B 2001:db8:2::2 -t udp -q 603 604 tc_check_packets "dev $h2 ingress" 101 1 605 check_fail $? "Matched a wrong filter" 606 607 tc_check_packets "dev $h2 ingress" 103 1 608 check_fail $? "Matched a wrong filter" 609 610 tc_check_packets "dev $h2 ingress" 102 1 611 check_err $? "Did not match on correct filter" 612 613 tp_record_all mlxsw:* 3 614 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 615 check_err $? "Rehash trace was not hit" 616 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate 617 check_err $? "Migrate trace was not hit" 618 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate_end 619 check_err $? "Migrate end trace was not hit" 620 tp_record_all mlxsw:* 3 621 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 622 check_err $? "Rehash trace was not hit" 623 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate 624 check_fail $? "Migrate trace was hit when no migration should happen" 625 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_migrate_end 626 check_fail $? "Migrate end trace was hit when no migration should happen" 627 628 $MZ $h1 -6 -c 1 -p 64 -a $h1mac -b $h2mac \ 629 -A 2001:db8:2::1 -B 2001:db8:2::2 -t udp -q 630 631 tc_check_packets "dev $h2 ingress" 101 1 632 check_fail $? "Matched a wrong filter after rehash" 633 634 tc_check_packets "dev $h2 ingress" 103 1 635 check_fail $? "Matched a wrong filter after rehash" 636 637 tc_check_packets "dev $h2 ingress" 102 2 638 check_err $? "Did not match on correct filter after rehash" 639 640 tc filter del dev $h2 ingress protocol ipv6 pref 3 handle 103 flower 641 tc filter del dev $h2 ingress protocol ipv6 pref 2 handle 102 flower 642 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 101 flower 643 644 log_test "delta simple IPv6 rehash test ($tcflags)" 645} 646 647TEST_RULE_BASE=256 648declare -a test_rules_inserted 649 650test_rule_add() 651{ 652 local iface=$1 653 local tcflags=$2 654 local index=$3 655 656 if ! [ ${test_rules_inserted[$index]} ] ; then 657 test_rules_inserted[$index]=false 658 fi 659 if ${test_rules_inserted[$index]} ; then 660 return 661 fi 662 663 local number=$(( $index + $TEST_RULE_BASE )) 664 printf -v hexnumber '%x' $number 665 666 batch="${batch}filter add dev $iface ingress protocol ipv6 pref 1 \ 667 handle $number flower $tcflags \ 668 src_ip 2001:db8:1::$hexnumber action drop\n" 669 test_rules_inserted[$index]=true 670} 671 672test_rule_del() 673{ 674 local iface=$1 675 local index=$2 676 677 if ! [ ${test_rules_inserted[$index]} ] ; then 678 test_rules_inserted[$index]=false 679 fi 680 if ! ${test_rules_inserted[$index]} ; then 681 return 682 fi 683 684 local number=$(( $index + $TEST_RULE_BASE )) 685 printf -v hexnumber '%x' $number 686 687 batch="${batch}filter del dev $iface ingress protocol ipv6 pref 1 \ 688 handle $number flower\n" 689 test_rules_inserted[$index]=false 690} 691 692test_rule_add_or_remove() 693{ 694 local iface=$1 695 local tcflags=$2 696 local index=$3 697 698 if ! [ ${test_rules_inserted[$index]} ] ; then 699 test_rules_inserted[$index]=false 700 fi 701 if ${test_rules_inserted[$index]} ; then 702 test_rule_del $iface $index 703 else 704 test_rule_add $iface $tcflags $index 705 fi 706} 707 708test_rule_add_or_remove_random_batch() 709{ 710 local iface=$1 711 local tcflags=$2 712 local total_count=$3 713 local skip=0 714 local count=0 715 local MAXSKIP=20 716 local MAXCOUNT=20 717 718 for ((i=1;i<=total_count;i++)); do 719 if (( $skip == 0 )) && (($count == 0)); then 720 ((skip=$RANDOM % $MAXSKIP + 1)) 721 ((count=$RANDOM % $MAXCOUNT + 1)) 722 fi 723 if (( $skip != 0 )); then 724 ((skip-=1)) 725 else 726 ((count-=1)) 727 test_rule_add_or_remove $iface $tcflags $i 728 fi 729 done 730} 731 732delta_massive_ipv6_rehash_test() 733{ 734 RET=0 735 736 if [[ "$tcflags" != "skip_sw" ]]; then 737 return 0; 738 fi 739 740 devlink dev param set $DEVLINK_DEV \ 741 name acl_region_rehash_interval cmode runtime value 0 742 check_err $? "Failed to set ACL region rehash interval" 743 744 tp_record_all mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 7 745 tp_check_hits_any mlxsw:mlxsw_sp_acl_tcam_vregion_rehash 746 check_fail $? "Rehash trace was hit even when rehash should be disabled" 747 748 RANDOM=4432897 749 declare batch="" 750 test_rule_add_or_remove_random_batch $h2 $tcflags 5000 751 752 echo -n -e $batch | tc -b - 753 754 declare batch="" 755 test_rule_add_or_remove_random_batch $h2 $tcflags 5000 756 757 devlink dev param set $DEVLINK_DEV \ 758 name acl_region_rehash_interval cmode runtime value 3000 759 check_err $? "Failed to set ACL region rehash interval" 760 761 sleep 1 762 763 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 101 flower \ 764 $tcflags dst_ip 2001:db8:1::0/121 action drop 765 tc filter add dev $h2 ingress protocol ipv6 pref 2 handle 102 flower \ 766 $tcflags dst_ip 2001:db8:2::2 action drop 767 tc filter add dev $h2 ingress protocol ipv6 pref 3 handle 103 flower \ 768 $tcflags dst_ip 2001:db8:3::0/120 action drop 769 770 $MZ $h1 -6 -c 1 -p 64 -a $h1mac -b $h2mac \ 771 -A 2001:db8:2::1 -B 2001:db8:2::2 -t udp -q 772 773 tc_check_packets "dev $h2 ingress" 101 1 774 check_fail $? "Matched a wrong filter" 775 776 tc_check_packets "dev $h2 ingress" 103 1 777 check_fail $? "Matched a wrong filter" 778 779 tc_check_packets "dev $h2 ingress" 102 1 780 check_err $? "Did not match on correct filter" 781 782 echo -n -e $batch | tc -b - 783 784 devlink dev param set $DEVLINK_DEV \ 785 name acl_region_rehash_interval cmode runtime value 0 786 check_err $? "Failed to set ACL region rehash interval" 787 788 $MZ $h1 -6 -c 1 -p 64 -a $h1mac -b $h2mac \ 789 -A 2001:db8:2::1 -B 2001:db8:2::2 -t udp -q 790 791 tc_check_packets "dev $h2 ingress" 101 1 792 check_fail $? "Matched a wrong filter after rehash" 793 794 tc_check_packets "dev $h2 ingress" 103 1 795 check_fail $? "Matched a wrong filter after rehash" 796 797 tc_check_packets "dev $h2 ingress" 102 2 798 check_err $? "Did not match on correct filter after rehash" 799 800 tc filter del dev $h2 ingress protocol ipv6 pref 3 handle 103 flower 801 tc filter del dev $h2 ingress protocol ipv6 pref 2 handle 102 flower 802 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 101 flower 803 804 declare batch="" 805 for i in {1..5000}; do 806 test_rule_del $h2 $tcflags $i 807 done 808 echo -e $batch | tc -b - 809 810 log_test "delta massive IPv6 rehash test ($tcflags)" 811} 812 813bloom_simple_test() 814{ 815 # Bloom filter requires that the eRP table is used. This test 816 # verifies that Bloom filter is not harming correctness of ACLs. 817 # First, make sure that eRP table is used and then set rule patterns 818 # which are distant enough and will result skipping a lookup after 819 # consulting the Bloom filter. Although some eRP lookups are skipped, 820 # the correct filter should be hit. 821 822 RET=0 823 824 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 825 $tcflags dst_ip 192.0.2.2 action drop 826 tc filter add dev $h2 ingress protocol ip pref 5 handle 104 flower \ 827 $tcflags dst_ip 198.51.100.2 action drop 828 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 829 $tcflags dst_ip 192.0.0.0/8 action drop 830 831 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 832 -t ip -q 833 834 tc_check_packets "dev $h2 ingress" 101 1 835 check_err $? "Two filters - did not match highest priority" 836 837 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 838 -t ip -q 839 840 tc_check_packets "dev $h2 ingress" 104 1 841 check_err $? "Single filter - did not match" 842 843 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 844 845 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 846 -t ip -q 847 848 tc_check_packets "dev $h2 ingress" 103 1 849 check_err $? "Low prio filter - did not match" 850 851 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 852 $tcflags dst_ip 198.0.0.0/8 action drop 853 854 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 855 -t ip -q 856 857 tc_check_packets "dev $h2 ingress" 102 1 858 check_err $? "Two filters - did not match highest priority after add" 859 860 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 861 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 862 tc filter del dev $h2 ingress protocol ip pref 5 handle 104 flower 863 864 log_test "bloom simple test ($tcflags)" 865} 866 867bloom_complex_test() 868{ 869 # Bloom filter index computation is affected from region ID, eRP 870 # ID and from the region key size. In order to excercise those parts 871 # of the Bloom filter code, use a series of regions, each with a 872 # different key size and send packet that should hit all of them. 873 local index 874 875 RET=0 876 NUM_CHAINS=4 877 BASE_INDEX=100 878 879 # Create chain with up to 2 key blocks (ip_proto only) 880 tc chain add dev $h2 ingress chain 1 protocol ip flower \ 881 ip_proto tcp &> /dev/null 882 # Create chain with 2-4 key blocks (ip_proto, src MAC) 883 tc chain add dev $h2 ingress chain 2 protocol ip flower \ 884 ip_proto tcp \ 885 src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null 886 # Create chain with 4-8 key blocks (ip_proto, src & dst MAC, IPv4 dest) 887 tc chain add dev $h2 ingress chain 3 protocol ip flower \ 888 ip_proto tcp \ 889 dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF \ 890 src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF \ 891 dst_ip 0.0.0.0/32 &> /dev/null 892 # Default chain contains all fields and therefore is 8-12 key blocks 893 tc chain add dev $h2 ingress chain 4 894 895 # We need at least 2 rules in every region to have eRP table active 896 # so create a dummy rule per chain using a different pattern 897 for i in $(eval echo {0..$NUM_CHAINS}); do 898 index=$((BASE_INDEX - 1 - i)) 899 tc filter add dev $h2 ingress chain $i protocol ip \ 900 pref 2 handle $index flower \ 901 $tcflags ip_proto tcp action drop 902 done 903 904 # Add rules to test Bloom filter, each in a different chain 905 index=$BASE_INDEX 906 tc filter add dev $h2 ingress protocol ip \ 907 pref 1 handle $((++index)) flower \ 908 $tcflags dst_ip 192.0.0.0/16 action goto chain 1 909 tc filter add dev $h2 ingress chain 1 protocol ip \ 910 pref 1 handle $((++index)) flower \ 911 $tcflags action goto chain 2 912 tc filter add dev $h2 ingress chain 2 protocol ip \ 913 pref 1 handle $((++index)) flower \ 914 $tcflags src_mac $h1mac action goto chain 3 915 tc filter add dev $h2 ingress chain 3 protocol ip \ 916 pref 1 handle $((++index)) flower \ 917 $tcflags dst_ip 192.0.0.0/8 action goto chain 4 918 tc filter add dev $h2 ingress chain 4 protocol ip \ 919 pref 1 handle $((++index)) flower \ 920 $tcflags src_ip 192.0.2.0/24 action drop 921 922 # Send a packet that is supposed to hit all chains 923 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 924 -t ip -q 925 926 for i in $(eval echo {0..$NUM_CHAINS}); do 927 index=$((BASE_INDEX + i + 1)) 928 tc_check_packets "dev $h2 ingress" $index 1 929 check_err $? "Did not match chain $i" 930 done 931 932 # Rules cleanup 933 for i in $(eval echo {$NUM_CHAINS..0}); do 934 index=$((BASE_INDEX - i - 1)) 935 tc filter del dev $h2 ingress chain $i \ 936 pref 2 handle $index flower 937 index=$((BASE_INDEX + i + 1)) 938 tc filter del dev $h2 ingress chain $i \ 939 pref 1 handle $index flower 940 done 941 942 # Chains cleanup 943 for i in $(eval echo {$NUM_CHAINS..1}); do 944 tc chain del dev $h2 ingress chain $i 945 done 946 947 log_test "bloom complex test ($tcflags)" 948} 949 950 951bloom_delta_test() 952{ 953 # When multiple masks are used, the eRP table is activated. When 954 # masks are close enough (delta) the masks reside on the same 955 # eRP table. This test verifies that the eRP table is correctly 956 # allocated and used in delta condition and that Bloom filter is 957 # still functional with delta. 958 959 RET=0 960 961 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 962 $tcflags dst_ip 192.1.0.0/16 action drop 963 964 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.1.2.1 -B 192.1.2.2 \ 965 -t ip -q 966 967 tc_check_packets "dev $h2 ingress" 103 1 968 check_err $? "Single filter - did not match" 969 970 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 971 $tcflags dst_ip 192.2.1.0/24 action drop 972 973 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.2.1.1 -B 192.2.1.2 \ 974 -t ip -q 975 976 tc_check_packets "dev $h2 ingress" 102 1 977 check_err $? "Delta filters - did not match second filter" 978 979 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 980 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 981 982 log_test "bloom delta test ($tcflags)" 983} 984 985setup_prepare() 986{ 987 h1=${NETIFS[p1]} 988 h2=${NETIFS[p2]} 989 h1mac=$(mac_get $h1) 990 h2mac=$(mac_get $h2) 991 992 vrf_prepare 993 994 h1_create 995 h2_create 996} 997 998cleanup() 999{ 1000 pre_cleanup 1001 1002 h2_destroy 1003 h1_destroy 1004 1005 vrf_cleanup 1006} 1007 1008trap cleanup EXIT 1009 1010setup_prepare 1011setup_wait 1012 1013tests_run 1014 1015if ! tc_offload_check; then 1016 check_err 1 "Could not test offloaded functionality" 1017 log_test "mlxsw-specific tests for tc flower" 1018 exit 1019else 1020 tcflags="skip_sw" 1021 tests_run 1022fi 1023 1024exit $EXIT_STATUS 1025