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" 12NUM_NETIFS=2 13source $lib_dir/tc_common.sh 14source $lib_dir/lib.sh 15 16tcflags="skip_hw" 17 18h1_create() 19{ 20 simple_if_init $h1 192.0.2.1/24 198.51.100.1/24 21} 22 23h1_destroy() 24{ 25 simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24 26} 27 28h2_create() 29{ 30 simple_if_init $h2 192.0.2.2/24 198.51.100.2/24 31 tc qdisc add dev $h2 clsact 32} 33 34h2_destroy() 35{ 36 tc qdisc del dev $h2 clsact 37 simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24 38} 39 40single_mask_test() 41{ 42 # When only a single mask is required, the device uses the master 43 # mask and not the eRP table. Verify that under this mode the right 44 # filter is matched 45 46 RET=0 47 48 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 49 $tcflags dst_ip 192.0.2.2 action drop 50 51 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 52 -t ip -q 53 54 tc_check_packets "dev $h2 ingress" 101 1 55 check_err $? "Single filter - did not match" 56 57 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 58 $tcflags dst_ip 198.51.100.2 action drop 59 60 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 61 -t ip -q 62 63 tc_check_packets "dev $h2 ingress" 101 2 64 check_err $? "Two filters - did not match highest priority" 65 66 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 67 -t ip -q 68 69 tc_check_packets "dev $h2 ingress" 102 1 70 check_err $? "Two filters - did not match lowest priority" 71 72 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 73 74 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ 75 -t ip -q 76 77 tc_check_packets "dev $h2 ingress" 102 2 78 check_err $? "Single filter - did not match after delete" 79 80 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 81 82 log_test "single mask test ($tcflags)" 83} 84 85identical_filters_test() 86{ 87 # When two filters that only differ in their priority are used, 88 # one needs to be inserted into the C-TCAM. This test verifies 89 # that filters are correctly spilled to C-TCAM and that the right 90 # filter is matched 91 92 RET=0 93 94 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 95 $tcflags dst_ip 192.0.2.2 action drop 96 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 97 $tcflags dst_ip 192.0.2.2 action drop 98 99 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 100 -t ip -q 101 102 tc_check_packets "dev $h2 ingress" 101 1 103 check_err $? "Did not match A-TCAM filter" 104 105 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 106 107 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 108 -t ip -q 109 110 tc_check_packets "dev $h2 ingress" 102 1 111 check_err $? "Did not match C-TCAM filter after A-TCAM delete" 112 113 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 114 $tcflags dst_ip 192.0.2.2 action drop 115 116 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 117 -t ip -q 118 119 tc_check_packets "dev $h2 ingress" 102 2 120 check_err $? "Did not match C-TCAM filter after A-TCAM add" 121 122 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 123 124 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 125 -t ip -q 126 127 tc_check_packets "dev $h2 ingress" 103 1 128 check_err $? "Did not match A-TCAM filter after C-TCAM delete" 129 130 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 131 132 log_test "identical filters test ($tcflags)" 133} 134 135two_masks_test() 136{ 137 # When more than one mask is required, the eRP table is used. This 138 # test verifies that the eRP table is correctly allocated and used 139 140 RET=0 141 142 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 143 $tcflags dst_ip 192.0.2.2 action drop 144 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 145 $tcflags dst_ip 192.0.0.0/16 action drop 146 147 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 148 -t ip -q 149 150 tc_check_packets "dev $h2 ingress" 101 1 151 check_err $? "Two filters - did not match highest priority" 152 153 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 154 155 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 156 -t ip -q 157 158 tc_check_packets "dev $h2 ingress" 103 1 159 check_err $? "Single filter - did not match" 160 161 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 162 $tcflags dst_ip 192.0.2.0/24 action drop 163 164 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 165 -t ip -q 166 167 tc_check_packets "dev $h2 ingress" 102 1 168 check_err $? "Two filters - did not match highest priority after add" 169 170 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 171 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 172 173 log_test "two masks test ($tcflags)" 174} 175 176multiple_masks_test() 177{ 178 # The number of masks in a region is limited. Once the maximum 179 # number of masks has been reached filters that require new 180 # masks are spilled to the C-TCAM. This test verifies that 181 # spillage is performed correctly and that the right filter is 182 # matched 183 184 local index 185 186 RET=0 187 188 NUM_MASKS=32 189 BASE_INDEX=100 190 191 for i in $(eval echo {1..$NUM_MASKS}); do 192 index=$((BASE_INDEX - i)) 193 194 tc filter add dev $h2 ingress protocol ip pref $index \ 195 handle $index \ 196 flower $tcflags dst_ip 192.0.2.2/${i} src_ip 192.0.2.1 \ 197 action drop 198 199 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ 200 -B 192.0.2.2 -t ip -q 201 202 tc_check_packets "dev $h2 ingress" $index 1 203 check_err $? "$i filters - did not match highest priority (add)" 204 done 205 206 for i in $(eval echo {$NUM_MASKS..1}); do 207 index=$((BASE_INDEX - i)) 208 209 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ 210 -B 192.0.2.2 -t ip -q 211 212 tc_check_packets "dev $h2 ingress" $index 2 213 check_err $? "$i filters - did not match highest priority (del)" 214 215 tc filter del dev $h2 ingress protocol ip pref $index \ 216 handle $index flower 217 done 218 219 log_test "multiple masks test ($tcflags)" 220} 221 222ctcam_two_atcam_masks_test() 223{ 224 RET=0 225 226 # First case: C-TCAM is disabled when there are two A-TCAM masks. 227 # We push a filter into the C-TCAM by using two identical filters 228 # as in identical_filters_test() 229 230 # Filter goes into A-TCAM 231 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 232 $tcflags dst_ip 192.0.2.2 action drop 233 # Filter goes into C-TCAM 234 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 235 $tcflags dst_ip 192.0.2.2 action drop 236 # Filter goes into A-TCAM 237 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ 238 $tcflags dst_ip 192.0.2.0/24 action drop 239 240 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 241 -t ip -q 242 243 tc_check_packets "dev $h2 ingress" 101 1 244 check_err $? "Did not match A-TCAM filter" 245 246 # Delete both A-TCAM and C-TCAM filters and make sure the remaining 247 # A-TCAM filter still works 248 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 249 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 250 251 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 252 -t ip -q 253 254 tc_check_packets "dev $h2 ingress" 103 1 255 check_err $? "Did not match A-TCAM filter" 256 257 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower 258 259 log_test "ctcam with two atcam masks test ($tcflags)" 260} 261 262ctcam_one_atcam_mask_test() 263{ 264 RET=0 265 266 # Second case: C-TCAM is disabled when there is one A-TCAM mask. 267 # The test is similar to identical_filters_test() 268 269 # Filter goes into A-TCAM 270 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 271 $tcflags dst_ip 192.0.2.2 action drop 272 # Filter goes into C-TCAM 273 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 274 $tcflags dst_ip 192.0.2.2 action drop 275 276 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 277 -t ip -q 278 279 tc_check_packets "dev $h2 ingress" 101 1 280 check_err $? "Did not match C-TCAM filter" 281 282 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 283 284 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 285 -t ip -q 286 287 tc_check_packets "dev $h2 ingress" 102 1 288 check_err $? "Did not match A-TCAM filter" 289 290 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 291 292 log_test "ctcam with one atcam mask test ($tcflags)" 293} 294 295ctcam_no_atcam_masks_test() 296{ 297 RET=0 298 299 # Third case: C-TCAM is disabled when there are no A-TCAM masks 300 # This test exercises the code path that transitions the eRP table 301 # to its initial state after deleting the last C-TCAM mask 302 303 # Filter goes into A-TCAM 304 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 305 $tcflags dst_ip 192.0.2.2 action drop 306 # Filter goes into C-TCAM 307 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ 308 $tcflags dst_ip 192.0.2.2 action drop 309 310 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 311 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower 312 313 log_test "ctcam with no atcam masks test ($tcflags)" 314} 315 316ctcam_edge_cases_test() 317{ 318 # When the C-TCAM is disabled after deleting the last C-TCAM 319 # mask, we want to make sure the eRP state machine is put in 320 # the correct state 321 322 ctcam_two_atcam_masks_test 323 ctcam_one_atcam_mask_test 324 ctcam_no_atcam_masks_test 325} 326 327setup_prepare() 328{ 329 h1=${NETIFS[p1]} 330 h2=${NETIFS[p2]} 331 h1mac=$(mac_get $h1) 332 h2mac=$(mac_get $h2) 333 334 vrf_prepare 335 336 h1_create 337 h2_create 338} 339 340cleanup() 341{ 342 pre_cleanup 343 344 h2_destroy 345 h1_destroy 346 347 vrf_cleanup 348} 349 350trap cleanup EXIT 351 352setup_prepare 353setup_wait 354 355tests_run 356 357if ! tc_offload_check; then 358 check_err 1 "Could not test offloaded functionality" 359 log_test "mlxsw-specific tests for tc flower" 360 exit 361else 362 tcflags="skip_sw" 363 tests_run 364fi 365 366exit $EXIT_STATUS 367