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