cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tc_flower.sh (29721B)


      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