GNU Linux-libre 4.19.264-gnu1
[releases.git] / tools / testing / selftests / drivers / net / mlxsw / spectrum-2 / tc_flower.sh
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
8 lib_dir=$(dirname $0)/../../../../net/forwarding
9
10 ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
11         multiple_masks_test ctcam_edge_cases_test"
12 NUM_NETIFS=2
13 source $lib_dir/tc_common.sh
14 source $lib_dir/lib.sh
15
16 tcflags="skip_hw"
17
18 h1_create()
19 {
20         simple_if_init $h1 192.0.2.1/24 198.51.100.1/24
21 }
22
23 h1_destroy()
24 {
25         simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24
26 }
27
28 h2_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
34 h2_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
40 single_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
85 identical_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
135 two_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
176 multiple_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
222 ctcam_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
262 ctcam_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
295 ctcam_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
316 ctcam_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
327 setup_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
340 cleanup()
341 {
342         pre_cleanup
343
344         h2_destroy
345         h1_destroy
346
347         vrf_cleanup
348 }
349
350 trap cleanup EXIT
351
352 setup_prepare
353 setup_wait
354
355 tests_run
356
357 if ! tc_offload_check; then
358         check_err 1 "Could not test offloaded functionality"
359         log_test "mlxsw-specific tests for tc flower"
360         exit
361 else
362         tcflags="skip_sw"
363         tests_run
364 fi
365
366 exit $EXIT_STATUS