1 | // SPDX-License-Identifier: BSD-3-Clause |
2 | /* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries. |
3 | * Microchip VCAP API kunit test suite |
4 | */ |
5 | |
6 | #include <kunit/test.h> |
7 | #include "vcap_api.h" |
8 | #include "vcap_api_client.h" |
9 | #include "vcap_model_kunit.h" |
10 | |
11 | /* First we have the test infrastructure that emulates the platform |
12 | * implementation |
13 | */ |
14 | #define TEST_BUF_CNT 100 |
15 | #define TEST_BUF_SZ 350 |
16 | #define STREAMWSIZE 64 |
17 | |
18 | static u32 test_updateaddr[STREAMWSIZE] = {}; |
19 | static int test_updateaddridx; |
20 | static int test_cache_erase_count; |
21 | static u32 test_init_start; |
22 | static u32 test_init_count; |
23 | static u32 test_hw_counter_id; |
24 | static struct vcap_cache_data test_hw_cache; |
25 | static struct net_device test_netdev = {}; |
26 | static int test_move_addr; |
27 | static int test_move_offset; |
28 | static int test_move_count; |
29 | |
30 | /* Callback used by the VCAP API */ |
31 | static enum vcap_keyfield_set test_val_keyset(struct net_device *ndev, |
32 | struct vcap_admin *admin, |
33 | struct vcap_rule *rule, |
34 | struct vcap_keyset_list *kslist, |
35 | u16 l3_proto) |
36 | { |
37 | int idx; |
38 | |
39 | if (kslist->cnt > 0) { |
40 | switch (admin->vtype) { |
41 | case VCAP_TYPE_IS0: |
42 | for (idx = 0; idx < kslist->cnt; idx++) { |
43 | if (kslist->keysets[idx] == VCAP_KFS_ETAG) |
44 | return kslist->keysets[idx]; |
45 | if (kslist->keysets[idx] == VCAP_KFS_PURE_5TUPLE_IP4) |
46 | return kslist->keysets[idx]; |
47 | if (kslist->keysets[idx] == VCAP_KFS_NORMAL_5TUPLE_IP4) |
48 | return kslist->keysets[idx]; |
49 | if (kslist->keysets[idx] == VCAP_KFS_NORMAL_7TUPLE) |
50 | return kslist->keysets[idx]; |
51 | } |
52 | break; |
53 | case VCAP_TYPE_IS2: |
54 | for (idx = 0; idx < kslist->cnt; idx++) { |
55 | if (kslist->keysets[idx] == VCAP_KFS_MAC_ETYPE) |
56 | return kslist->keysets[idx]; |
57 | if (kslist->keysets[idx] == VCAP_KFS_ARP) |
58 | return kslist->keysets[idx]; |
59 | if (kslist->keysets[idx] == VCAP_KFS_IP_7TUPLE) |
60 | return kslist->keysets[idx]; |
61 | } |
62 | break; |
63 | default: |
64 | pr_info("%s:%d: no validation for VCAP %d\n" , |
65 | __func__, __LINE__, admin->vtype); |
66 | break; |
67 | } |
68 | } |
69 | return -EINVAL; |
70 | } |
71 | |
72 | /* Callback used by the VCAP API */ |
73 | static void test_add_def_fields(struct net_device *ndev, |
74 | struct vcap_admin *admin, |
75 | struct vcap_rule *rule) |
76 | { |
77 | if (admin->vinst == 0 || admin->vinst == 2) |
78 | vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); |
79 | else |
80 | vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0); |
81 | } |
82 | |
83 | /* Callback used by the VCAP API */ |
84 | static void test_cache_erase(struct vcap_admin *admin) |
85 | { |
86 | if (test_cache_erase_count) { |
87 | memset(admin->cache.keystream, 0, test_cache_erase_count); |
88 | memset(admin->cache.maskstream, 0, test_cache_erase_count); |
89 | memset(admin->cache.actionstream, 0, test_cache_erase_count); |
90 | test_cache_erase_count = 0; |
91 | } |
92 | } |
93 | |
94 | /* Callback used by the VCAP API */ |
95 | static void test_cache_init(struct net_device *ndev, struct vcap_admin *admin, |
96 | u32 start, u32 count) |
97 | { |
98 | test_init_start = start; |
99 | test_init_count = count; |
100 | } |
101 | |
102 | /* Callback used by the VCAP API */ |
103 | static void test_cache_read(struct net_device *ndev, struct vcap_admin *admin, |
104 | enum vcap_selection sel, u32 start, u32 count) |
105 | { |
106 | u32 *keystr, *mskstr, *actstr; |
107 | int idx; |
108 | |
109 | pr_debug("%s:%d: %d %d\n" , __func__, __LINE__, start, count); |
110 | switch (sel) { |
111 | case VCAP_SEL_ENTRY: |
112 | keystr = &admin->cache.keystream[start]; |
113 | mskstr = &admin->cache.maskstream[start]; |
114 | for (idx = 0; idx < count; ++idx) { |
115 | pr_debug("%s:%d: keydata[%02d]: 0x%08x\n" , __func__, |
116 | __LINE__, start + idx, keystr[idx]); |
117 | } |
118 | for (idx = 0; idx < count; ++idx) { |
119 | /* Invert the mask before decoding starts */ |
120 | mskstr[idx] = ~mskstr[idx]; |
121 | pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n" , __func__, |
122 | __LINE__, start + idx, mskstr[idx]); |
123 | } |
124 | break; |
125 | case VCAP_SEL_ACTION: |
126 | actstr = &admin->cache.actionstream[start]; |
127 | for (idx = 0; idx < count; ++idx) { |
128 | pr_debug("%s:%d: actdata[%02d]: 0x%08x\n" , __func__, |
129 | __LINE__, start + idx, actstr[idx]); |
130 | } |
131 | break; |
132 | case VCAP_SEL_COUNTER: |
133 | pr_debug("%s:%d\n" , __func__, __LINE__); |
134 | test_hw_counter_id = start; |
135 | admin->cache.counter = test_hw_cache.counter; |
136 | admin->cache.sticky = test_hw_cache.sticky; |
137 | break; |
138 | case VCAP_SEL_ALL: |
139 | pr_debug("%s:%d\n" , __func__, __LINE__); |
140 | break; |
141 | } |
142 | } |
143 | |
144 | /* Callback used by the VCAP API */ |
145 | static void test_cache_write(struct net_device *ndev, struct vcap_admin *admin, |
146 | enum vcap_selection sel, u32 start, u32 count) |
147 | { |
148 | u32 *keystr, *mskstr, *actstr; |
149 | int idx; |
150 | |
151 | switch (sel) { |
152 | case VCAP_SEL_ENTRY: |
153 | keystr = &admin->cache.keystream[start]; |
154 | mskstr = &admin->cache.maskstream[start]; |
155 | for (idx = 0; idx < count; ++idx) { |
156 | pr_debug("%s:%d: keydata[%02d]: 0x%08x\n" , __func__, |
157 | __LINE__, start + idx, keystr[idx]); |
158 | } |
159 | for (idx = 0; idx < count; ++idx) { |
160 | /* Invert the mask before encoding starts */ |
161 | mskstr[idx] = ~mskstr[idx]; |
162 | pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n" , __func__, |
163 | __LINE__, start + idx, mskstr[idx]); |
164 | } |
165 | break; |
166 | case VCAP_SEL_ACTION: |
167 | actstr = &admin->cache.actionstream[start]; |
168 | for (idx = 0; idx < count; ++idx) { |
169 | pr_debug("%s:%d: actdata[%02d]: 0x%08x\n" , __func__, |
170 | __LINE__, start + idx, actstr[idx]); |
171 | } |
172 | break; |
173 | case VCAP_SEL_COUNTER: |
174 | pr_debug("%s:%d\n" , __func__, __LINE__); |
175 | test_hw_counter_id = start; |
176 | test_hw_cache.counter = admin->cache.counter; |
177 | test_hw_cache.sticky = admin->cache.sticky; |
178 | break; |
179 | case VCAP_SEL_ALL: |
180 | pr_err("%s:%d: cannot write all streams at once\n" , |
181 | __func__, __LINE__); |
182 | break; |
183 | } |
184 | } |
185 | |
186 | /* Callback used by the VCAP API */ |
187 | static void test_cache_update(struct net_device *ndev, struct vcap_admin *admin, |
188 | enum vcap_command cmd, |
189 | enum vcap_selection sel, u32 addr) |
190 | { |
191 | if (test_updateaddridx < ARRAY_SIZE(test_updateaddr)) |
192 | test_updateaddr[test_updateaddridx] = addr; |
193 | else |
194 | pr_err("%s:%d: overflow: %d\n" , __func__, __LINE__, test_updateaddridx); |
195 | test_updateaddridx++; |
196 | } |
197 | |
198 | static void test_cache_move(struct net_device *ndev, struct vcap_admin *admin, |
199 | u32 addr, int offset, int count) |
200 | { |
201 | test_move_addr = addr; |
202 | test_move_offset = offset; |
203 | test_move_count = count; |
204 | } |
205 | |
206 | /* Provide port information via a callback interface */ |
207 | static int vcap_test_port_info(struct net_device *ndev, |
208 | struct vcap_admin *admin, |
209 | struct vcap_output_print *out) |
210 | { |
211 | return 0; |
212 | } |
213 | |
214 | static struct vcap_operations test_callbacks = { |
215 | .validate_keyset = test_val_keyset, |
216 | .add_default_fields = test_add_def_fields, |
217 | .cache_erase = test_cache_erase, |
218 | .cache_write = test_cache_write, |
219 | .cache_read = test_cache_read, |
220 | .init = test_cache_init, |
221 | .update = test_cache_update, |
222 | .move = test_cache_move, |
223 | .port_info = vcap_test_port_info, |
224 | }; |
225 | |
226 | static struct vcap_control test_vctrl = { |
227 | .vcaps = kunit_test_vcaps, |
228 | .stats = &kunit_test_vcap_stats, |
229 | .ops = &test_callbacks, |
230 | }; |
231 | |
232 | static void vcap_test_api_init(struct vcap_admin *admin) |
233 | { |
234 | /* Initialize the shared objects */ |
235 | INIT_LIST_HEAD(list: &test_vctrl.list); |
236 | INIT_LIST_HEAD(list: &admin->list); |
237 | INIT_LIST_HEAD(list: &admin->rules); |
238 | INIT_LIST_HEAD(list: &admin->enabled); |
239 | mutex_init(&admin->lock); |
240 | list_add_tail(new: &admin->list, head: &test_vctrl.list); |
241 | memset(test_updateaddr, 0, sizeof(test_updateaddr)); |
242 | test_updateaddridx = 0; |
243 | } |
244 | |
245 | /* Helper function to create a rule of a specific size */ |
246 | static void test_vcap_xn_rule_creator(struct kunit *test, int cid, |
247 | enum vcap_user user, u16 priority, |
248 | int id, int size, int expected_addr) |
249 | { |
250 | struct vcap_rule *rule; |
251 | struct vcap_rule_internal *ri; |
252 | enum vcap_keyfield_set keyset = VCAP_KFS_NO_VALUE; |
253 | enum vcap_actionfield_set actionset = VCAP_AFS_NO_VALUE; |
254 | int ret; |
255 | |
256 | /* init before testing */ |
257 | memset(test_updateaddr, 0, sizeof(test_updateaddr)); |
258 | test_updateaddridx = 0; |
259 | test_move_addr = 0; |
260 | test_move_offset = 0; |
261 | test_move_count = 0; |
262 | |
263 | switch (size) { |
264 | case 2: |
265 | keyset = VCAP_KFS_ETAG; |
266 | actionset = VCAP_AFS_CLASS_REDUCED; |
267 | break; |
268 | case 3: |
269 | keyset = VCAP_KFS_PURE_5TUPLE_IP4; |
270 | actionset = VCAP_AFS_CLASSIFICATION; |
271 | break; |
272 | case 6: |
273 | keyset = VCAP_KFS_NORMAL_5TUPLE_IP4; |
274 | actionset = VCAP_AFS_CLASSIFICATION; |
275 | break; |
276 | case 12: |
277 | keyset = VCAP_KFS_NORMAL_7TUPLE; |
278 | actionset = VCAP_AFS_FULL; |
279 | break; |
280 | default: |
281 | break; |
282 | } |
283 | |
284 | /* Check that a valid size was used */ |
285 | KUNIT_ASSERT_NE(test, VCAP_KFS_NO_VALUE, keyset); |
286 | |
287 | /* Allocate the rule */ |
288 | rule = vcap_alloc_rule(&test_vctrl, &test_netdev, cid, user, priority, |
289 | id); |
290 | KUNIT_EXPECT_PTR_NE(test, NULL, rule); |
291 | |
292 | ri = (struct vcap_rule_internal *)rule; |
293 | |
294 | /* Override rule keyset */ |
295 | ret = vcap_set_rule_set_keyset(rule, keyset); |
296 | |
297 | /* Add rule actions : there must be at least one action */ |
298 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_ISDX_VAL, 0); |
299 | |
300 | /* Override rule actionset */ |
301 | ret = vcap_set_rule_set_actionset(rule, actionset); |
302 | |
303 | ret = vcap_val_rule(rule, ETH_P_ALL); |
304 | KUNIT_EXPECT_EQ(test, 0, ret); |
305 | KUNIT_EXPECT_EQ(test, keyset, rule->keyset); |
306 | KUNIT_EXPECT_EQ(test, actionset, rule->actionset); |
307 | KUNIT_EXPECT_EQ(test, size, ri->size); |
308 | |
309 | /* Add rule with write callback */ |
310 | ret = vcap_add_rule(rule); |
311 | KUNIT_EXPECT_EQ(test, 0, ret); |
312 | KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); |
313 | vcap_free_rule(rule); |
314 | } |
315 | |
316 | /* Prepare testing rule deletion */ |
317 | static void test_init_rule_deletion(void) |
318 | { |
319 | test_move_addr = 0; |
320 | test_move_offset = 0; |
321 | test_move_count = 0; |
322 | test_init_start = 0; |
323 | test_init_count = 0; |
324 | } |
325 | |
326 | /* Define the test cases. */ |
327 | |
328 | static void vcap_api_set_bit_1_test(struct kunit *test) |
329 | { |
330 | struct vcap_stream_iter iter = { |
331 | .offset = 35, |
332 | .sw_width = 52, |
333 | .reg_idx = 1, |
334 | .reg_bitpos = 20, |
335 | .tg = NULL, |
336 | }; |
337 | u32 stream[2] = {0}; |
338 | |
339 | vcap_set_bit(stream, itr: &iter, value: 1); |
340 | |
341 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]); |
342 | KUNIT_EXPECT_EQ(test, (u32)BIT(20), stream[1]); |
343 | } |
344 | |
345 | static void vcap_api_set_bit_0_test(struct kunit *test) |
346 | { |
347 | struct vcap_stream_iter iter = { |
348 | .offset = 35, |
349 | .sw_width = 52, |
350 | .reg_idx = 2, |
351 | .reg_bitpos = 11, |
352 | .tg = NULL, |
353 | }; |
354 | u32 stream[3] = {~0, ~0, ~0}; |
355 | |
356 | vcap_set_bit(stream, itr: &iter, value: 0); |
357 | |
358 | KUNIT_EXPECT_EQ(test, (u32)~0, stream[0]); |
359 | KUNIT_EXPECT_EQ(test, (u32)~0, stream[1]); |
360 | KUNIT_EXPECT_EQ(test, (u32)~BIT(11), stream[2]); |
361 | } |
362 | |
363 | static void vcap_api_iterator_init_test(struct kunit *test) |
364 | { |
365 | struct vcap_stream_iter iter; |
366 | struct vcap_typegroup typegroups[] = { |
367 | { .offset = 0, .width = 2, .value = 2, }, |
368 | { .offset = 156, .width = 1, .value = 0, }, |
369 | { .offset = 0, .width = 0, .value = 0, }, |
370 | }; |
371 | struct vcap_typegroup typegroups2[] = { |
372 | { .offset = 0, .width = 3, .value = 4, }, |
373 | { .offset = 49, .width = 2, .value = 0, }, |
374 | { .offset = 98, .width = 2, .value = 0, }, |
375 | }; |
376 | |
377 | vcap_iter_init(itr: &iter, sw_width: 52, tg: typegroups, offset: 86); |
378 | |
379 | KUNIT_EXPECT_EQ(test, 52, iter.sw_width); |
380 | KUNIT_EXPECT_EQ(test, 86 + 2, iter.offset); |
381 | KUNIT_EXPECT_EQ(test, 3, iter.reg_idx); |
382 | KUNIT_EXPECT_EQ(test, 4, iter.reg_bitpos); |
383 | |
384 | vcap_iter_init(itr: &iter, sw_width: 49, tg: typegroups2, offset: 134); |
385 | |
386 | KUNIT_EXPECT_EQ(test, 49, iter.sw_width); |
387 | KUNIT_EXPECT_EQ(test, 134 + 7, iter.offset); |
388 | KUNIT_EXPECT_EQ(test, 5, iter.reg_idx); |
389 | KUNIT_EXPECT_EQ(test, 11, iter.reg_bitpos); |
390 | } |
391 | |
392 | static void vcap_api_iterator_next_test(struct kunit *test) |
393 | { |
394 | struct vcap_stream_iter iter; |
395 | struct vcap_typegroup typegroups[] = { |
396 | { .offset = 0, .width = 4, .value = 8, }, |
397 | { .offset = 49, .width = 1, .value = 0, }, |
398 | { .offset = 98, .width = 2, .value = 0, }, |
399 | { .offset = 147, .width = 3, .value = 0, }, |
400 | { .offset = 196, .width = 2, .value = 0, }, |
401 | { .offset = 245, .width = 1, .value = 0, }, |
402 | }; |
403 | int idx; |
404 | |
405 | vcap_iter_init(itr: &iter, sw_width: 49, tg: typegroups, offset: 86); |
406 | |
407 | KUNIT_EXPECT_EQ(test, 49, iter.sw_width); |
408 | KUNIT_EXPECT_EQ(test, 86 + 5, iter.offset); |
409 | KUNIT_EXPECT_EQ(test, 3, iter.reg_idx); |
410 | KUNIT_EXPECT_EQ(test, 10, iter.reg_bitpos); |
411 | |
412 | vcap_iter_next(itr: &iter); |
413 | |
414 | KUNIT_EXPECT_EQ(test, 91 + 1, iter.offset); |
415 | KUNIT_EXPECT_EQ(test, 3, iter.reg_idx); |
416 | KUNIT_EXPECT_EQ(test, 11, iter.reg_bitpos); |
417 | |
418 | for (idx = 0; idx < 6; idx++) |
419 | vcap_iter_next(itr: &iter); |
420 | |
421 | KUNIT_EXPECT_EQ(test, 92 + 6 + 2, iter.offset); |
422 | KUNIT_EXPECT_EQ(test, 4, iter.reg_idx); |
423 | KUNIT_EXPECT_EQ(test, 2, iter.reg_bitpos); |
424 | } |
425 | |
426 | static void vcap_api_encode_typegroups_test(struct kunit *test) |
427 | { |
428 | u32 stream[12] = {0}; |
429 | struct vcap_typegroup typegroups[] = { |
430 | { .offset = 0, .width = 4, .value = 8, }, |
431 | { .offset = 49, .width = 1, .value = 1, }, |
432 | { .offset = 98, .width = 2, .value = 3, }, |
433 | { .offset = 147, .width = 3, .value = 5, }, |
434 | { .offset = 196, .width = 2, .value = 2, }, |
435 | { .offset = 245, .width = 5, .value = 27, }, |
436 | { .offset = 0, .width = 0, .value = 0, }, |
437 | }; |
438 | |
439 | vcap_encode_typegroups(stream, sw_width: 49, tg: typegroups, mask: false); |
440 | |
441 | KUNIT_EXPECT_EQ(test, (u32)0x8, stream[0]); |
442 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]); |
443 | KUNIT_EXPECT_EQ(test, (u32)0x1, stream[2]); |
444 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[3]); |
445 | KUNIT_EXPECT_EQ(test, (u32)0x3, stream[4]); |
446 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]); |
447 | KUNIT_EXPECT_EQ(test, (u32)0x5, stream[6]); |
448 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[7]); |
449 | KUNIT_EXPECT_EQ(test, (u32)0x2, stream[8]); |
450 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[9]); |
451 | KUNIT_EXPECT_EQ(test, (u32)27, stream[10]); |
452 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[11]); |
453 | } |
454 | |
455 | static void vcap_api_encode_bit_test(struct kunit *test) |
456 | { |
457 | struct vcap_stream_iter iter; |
458 | u32 stream[4] = {0}; |
459 | struct vcap_typegroup typegroups[] = { |
460 | { .offset = 0, .width = 4, .value = 8, }, |
461 | { .offset = 49, .width = 1, .value = 1, }, |
462 | { .offset = 98, .width = 2, .value = 3, }, |
463 | { .offset = 147, .width = 3, .value = 5, }, |
464 | { .offset = 196, .width = 2, .value = 2, }, |
465 | { .offset = 245, .width = 1, .value = 0, }, |
466 | }; |
467 | |
468 | vcap_iter_init(itr: &iter, sw_width: 49, tg: typegroups, offset: 44); |
469 | |
470 | KUNIT_EXPECT_EQ(test, 48, iter.offset); |
471 | KUNIT_EXPECT_EQ(test, 1, iter.reg_idx); |
472 | KUNIT_EXPECT_EQ(test, 16, iter.reg_bitpos); |
473 | |
474 | vcap_encode_bit(stream, itr: &iter, val: 1); |
475 | |
476 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]); |
477 | KUNIT_EXPECT_EQ(test, (u32)BIT(16), stream[1]); |
478 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]); |
479 | } |
480 | |
481 | static void vcap_api_encode_field_test(struct kunit *test) |
482 | { |
483 | struct vcap_stream_iter iter; |
484 | u32 stream[16] = {0}; |
485 | struct vcap_typegroup typegroups[] = { |
486 | { .offset = 0, .width = 4, .value = 8, }, |
487 | { .offset = 49, .width = 1, .value = 1, }, |
488 | { .offset = 98, .width = 2, .value = 3, }, |
489 | { .offset = 147, .width = 3, .value = 5, }, |
490 | { .offset = 196, .width = 2, .value = 2, }, |
491 | { .offset = 245, .width = 5, .value = 27, }, |
492 | { .offset = 0, .width = 0, .value = 0, }, |
493 | }; |
494 | struct vcap_field rf = { |
495 | .type = VCAP_FIELD_U32, |
496 | .offset = 86, |
497 | .width = 4, |
498 | }; |
499 | u8 value[] = {0x5}; |
500 | |
501 | vcap_iter_init(itr: &iter, sw_width: 49, tg: typegroups, offset: rf.offset); |
502 | |
503 | KUNIT_EXPECT_EQ(test, 91, iter.offset); |
504 | KUNIT_EXPECT_EQ(test, 3, iter.reg_idx); |
505 | KUNIT_EXPECT_EQ(test, 10, iter.reg_bitpos); |
506 | |
507 | vcap_encode_field(stream, itr: &iter, width: rf.width, value); |
508 | |
509 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]); |
510 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]); |
511 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]); |
512 | KUNIT_EXPECT_EQ(test, (u32)(0x5 << 10), stream[3]); |
513 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[4]); |
514 | |
515 | vcap_encode_typegroups(stream, sw_width: 49, tg: typegroups, mask: false); |
516 | |
517 | KUNIT_EXPECT_EQ(test, (u32)0x8, stream[0]); |
518 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[1]); |
519 | KUNIT_EXPECT_EQ(test, (u32)0x1, stream[2]); |
520 | KUNIT_EXPECT_EQ(test, (u32)(0x5 << 10), stream[3]); |
521 | KUNIT_EXPECT_EQ(test, (u32)0x3, stream[4]); |
522 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]); |
523 | KUNIT_EXPECT_EQ(test, (u32)0x5, stream[6]); |
524 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[7]); |
525 | KUNIT_EXPECT_EQ(test, (u32)0x2, stream[8]); |
526 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[9]); |
527 | KUNIT_EXPECT_EQ(test, (u32)27, stream[10]); |
528 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[11]); |
529 | } |
530 | |
531 | /* In this testcase the subword is smaller than a register */ |
532 | static void vcap_api_encode_short_field_test(struct kunit *test) |
533 | { |
534 | struct vcap_stream_iter iter; |
535 | int sw_width = 21; |
536 | u32 stream[6] = {0}; |
537 | struct vcap_typegroup tgt[] = { |
538 | { .offset = 0, .width = 3, .value = 7, }, |
539 | { .offset = 21, .width = 2, .value = 3, }, |
540 | { .offset = 42, .width = 1, .value = 1, }, |
541 | { .offset = 0, .width = 0, .value = 0, }, |
542 | }; |
543 | struct vcap_field rf = { |
544 | .type = VCAP_FIELD_U32, |
545 | .offset = 25, |
546 | .width = 4, |
547 | }; |
548 | u8 value[] = {0x5}; |
549 | |
550 | vcap_iter_init(itr: &iter, sw_width, tg: tgt, offset: rf.offset); |
551 | |
552 | KUNIT_EXPECT_EQ(test, 1, iter.regs_per_sw); |
553 | KUNIT_EXPECT_EQ(test, 21, iter.sw_width); |
554 | KUNIT_EXPECT_EQ(test, 25 + 3 + 2, iter.offset); |
555 | KUNIT_EXPECT_EQ(test, 1, iter.reg_idx); |
556 | KUNIT_EXPECT_EQ(test, 25 + 3 + 2 - sw_width, iter.reg_bitpos); |
557 | |
558 | vcap_encode_field(stream, itr: &iter, width: rf.width, value); |
559 | |
560 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]); |
561 | KUNIT_EXPECT_EQ(test, (u32)(0x5 << (25 + 3 + 2 - sw_width)), stream[1]); |
562 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[2]); |
563 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[3]); |
564 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[4]); |
565 | KUNIT_EXPECT_EQ(test, (u32)0x0, stream[5]); |
566 | |
567 | vcap_encode_typegroups(stream, sw_width, tg: tgt, mask: false); |
568 | |
569 | KUNIT_EXPECT_EQ(test, (u32)7, stream[0]); |
570 | KUNIT_EXPECT_EQ(test, (u32)((0x5 << (25 + 3 + 2 - sw_width)) + 3), stream[1]); |
571 | KUNIT_EXPECT_EQ(test, (u32)1, stream[2]); |
572 | KUNIT_EXPECT_EQ(test, (u32)0, stream[3]); |
573 | KUNIT_EXPECT_EQ(test, (u32)0, stream[4]); |
574 | KUNIT_EXPECT_EQ(test, (u32)0, stream[5]); |
575 | } |
576 | |
577 | static void vcap_api_encode_keyfield_test(struct kunit *test) |
578 | { |
579 | u32 keywords[16] = {0}; |
580 | u32 maskwords[16] = {0}; |
581 | struct vcap_admin admin = { |
582 | .vtype = VCAP_TYPE_IS2, |
583 | .cache = { |
584 | .keystream = keywords, |
585 | .maskstream = maskwords, |
586 | .actionstream = keywords, |
587 | }, |
588 | }; |
589 | struct vcap_rule_internal rule = { |
590 | .admin = &admin, |
591 | .data = { |
592 | .keyset = VCAP_KFS_MAC_ETYPE, |
593 | }, |
594 | .vctrl = &test_vctrl, |
595 | }; |
596 | struct vcap_client_keyfield ckf = { |
597 | .ctrl.list = {}, |
598 | .ctrl.key = VCAP_KF_ISDX_CLS, |
599 | .ctrl.type = VCAP_FIELD_U32, |
600 | .data.u32.value = 0xeef014a1, |
601 | .data.u32.mask = 0xfff, |
602 | }; |
603 | struct vcap_field rf = { |
604 | .type = VCAP_FIELD_U32, |
605 | .offset = 56, |
606 | .width = 12, |
607 | }; |
608 | struct vcap_typegroup tgt[] = { |
609 | { .offset = 0, .width = 2, .value = 2, }, |
610 | { .offset = 156, .width = 1, .value = 1, }, |
611 | { .offset = 0, .width = 0, .value = 0, }, |
612 | }; |
613 | |
614 | vcap_test_api_init(admin: &admin); |
615 | vcap_encode_keyfield(ri: &rule, kf: &ckf, rf: &rf, tgt); |
616 | |
617 | /* Key */ |
618 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[0]); |
619 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[1]); |
620 | KUNIT_EXPECT_EQ(test, (u32)(0x04a1 << 6), keywords[2]); |
621 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[3]); |
622 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[4]); |
623 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[5]); |
624 | KUNIT_EXPECT_EQ(test, (u32)0x0, keywords[6]); |
625 | |
626 | /* Mask */ |
627 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[0]); |
628 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[1]); |
629 | KUNIT_EXPECT_EQ(test, (u32)(0x0fff << 6), maskwords[2]); |
630 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[3]); |
631 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[4]); |
632 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[5]); |
633 | KUNIT_EXPECT_EQ(test, (u32)0x0, maskwords[6]); |
634 | } |
635 | |
636 | static void vcap_api_encode_max_keyfield_test(struct kunit *test) |
637 | { |
638 | int idx; |
639 | u32 keywords[6] = {0}; |
640 | u32 maskwords[6] = {0}; |
641 | struct vcap_admin admin = { |
642 | .vtype = VCAP_TYPE_IS2, |
643 | /* IS2 sw_width = 52 bit */ |
644 | .cache = { |
645 | .keystream = keywords, |
646 | .maskstream = maskwords, |
647 | .actionstream = keywords, |
648 | }, |
649 | }; |
650 | struct vcap_rule_internal rule = { |
651 | .admin = &admin, |
652 | .data = { |
653 | .keyset = VCAP_KFS_IP_7TUPLE, |
654 | }, |
655 | .vctrl = &test_vctrl, |
656 | }; |
657 | struct vcap_client_keyfield ckf = { |
658 | .ctrl.list = {}, |
659 | .ctrl.key = VCAP_KF_L3_IP6_DIP, |
660 | .ctrl.type = VCAP_FIELD_U128, |
661 | .data.u128.value = { 0xa1, 0xa2, 0xa3, 0xa4, 0, 0, 0x43, 0, |
662 | 0, 0, 0, 0, 0, 0, 0x78, 0x8e, }, |
663 | .data.u128.mask = { 0xff, 0xff, 0xff, 0xff, 0, 0, 0xff, 0, |
664 | 0, 0, 0, 0, 0, 0, 0xff, 0xff }, |
665 | }; |
666 | struct vcap_field rf = { |
667 | .type = VCAP_FIELD_U128, |
668 | .offset = 0, |
669 | .width = 128, |
670 | }; |
671 | struct vcap_typegroup tgt[] = { |
672 | { .offset = 0, .width = 2, .value = 2, }, |
673 | { .offset = 156, .width = 1, .value = 1, }, |
674 | { .offset = 0, .width = 0, .value = 0, }, |
675 | }; |
676 | u32 keyres[] = { |
677 | 0x928e8a84, |
678 | 0x000c0002, |
679 | 0x00000010, |
680 | 0x00000000, |
681 | 0x0239e000, |
682 | 0x00000000, |
683 | }; |
684 | u32 mskres[] = { |
685 | 0xfffffffc, |
686 | 0x000c0003, |
687 | 0x0000003f, |
688 | 0x00000000, |
689 | 0x03fffc00, |
690 | 0x00000000, |
691 | }; |
692 | |
693 | vcap_encode_keyfield(ri: &rule, kf: &ckf, rf: &rf, tgt); |
694 | |
695 | /* Key */ |
696 | for (idx = 0; idx < ARRAY_SIZE(keyres); ++idx) |
697 | KUNIT_EXPECT_EQ(test, keyres[idx], keywords[idx]); |
698 | /* Mask */ |
699 | for (idx = 0; idx < ARRAY_SIZE(mskres); ++idx) |
700 | KUNIT_EXPECT_EQ(test, mskres[idx], maskwords[idx]); |
701 | } |
702 | |
703 | static void vcap_api_encode_actionfield_test(struct kunit *test) |
704 | { |
705 | u32 actwords[16] = {0}; |
706 | int sw_width = 21; |
707 | struct vcap_admin admin = { |
708 | .vtype = VCAP_TYPE_ES2, /* act_width = 21 */ |
709 | .cache = { |
710 | .actionstream = actwords, |
711 | }, |
712 | }; |
713 | struct vcap_rule_internal rule = { |
714 | .admin = &admin, |
715 | .data = { |
716 | .actionset = VCAP_AFS_BASE_TYPE, |
717 | }, |
718 | .vctrl = &test_vctrl, |
719 | }; |
720 | struct vcap_client_actionfield caf = { |
721 | .ctrl.list = {}, |
722 | .ctrl.action = VCAP_AF_POLICE_IDX, |
723 | .ctrl.type = VCAP_FIELD_U32, |
724 | .data.u32.value = 0x67908032, |
725 | }; |
726 | struct vcap_field rf = { |
727 | .type = VCAP_FIELD_U32, |
728 | .offset = 35, |
729 | .width = 6, |
730 | }; |
731 | struct vcap_typegroup tgt[] = { |
732 | { .offset = 0, .width = 2, .value = 2, }, |
733 | { .offset = 21, .width = 1, .value = 1, }, |
734 | { .offset = 42, .width = 1, .value = 0, }, |
735 | { .offset = 0, .width = 0, .value = 0, }, |
736 | }; |
737 | |
738 | vcap_encode_actionfield(ri: &rule, af: &caf, rf: &rf, tgt); |
739 | |
740 | /* Action */ |
741 | KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[0]); |
742 | KUNIT_EXPECT_EQ(test, (u32)((0x32 << (35 + 2 + 1 - sw_width)) & 0x1fffff), actwords[1]); |
743 | KUNIT_EXPECT_EQ(test, (u32)((0x32 >> ((2 * sw_width) - 38 - 1))), actwords[2]); |
744 | KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[3]); |
745 | KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[4]); |
746 | KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[5]); |
747 | KUNIT_EXPECT_EQ(test, (u32)0x0, actwords[6]); |
748 | } |
749 | |
750 | static void vcap_api_keyfield_typegroup_test(struct kunit *test) |
751 | { |
752 | const struct vcap_typegroup *tg; |
753 | |
754 | tg = vcap_keyfield_typegroup(vctrl: &test_vctrl, vt: VCAP_TYPE_IS2, keyset: VCAP_KFS_MAC_ETYPE); |
755 | KUNIT_EXPECT_PTR_NE(test, NULL, tg); |
756 | KUNIT_EXPECT_EQ(test, 0, tg[0].offset); |
757 | KUNIT_EXPECT_EQ(test, 2, tg[0].width); |
758 | KUNIT_EXPECT_EQ(test, 2, tg[0].value); |
759 | KUNIT_EXPECT_EQ(test, 156, tg[1].offset); |
760 | KUNIT_EXPECT_EQ(test, 1, tg[1].width); |
761 | KUNIT_EXPECT_EQ(test, 0, tg[1].value); |
762 | KUNIT_EXPECT_EQ(test, 0, tg[2].offset); |
763 | KUNIT_EXPECT_EQ(test, 0, tg[2].width); |
764 | KUNIT_EXPECT_EQ(test, 0, tg[2].value); |
765 | |
766 | tg = vcap_keyfield_typegroup(vctrl: &test_vctrl, vt: VCAP_TYPE_ES2, keyset: VCAP_KFS_LL_FULL); |
767 | KUNIT_EXPECT_PTR_EQ(test, NULL, tg); |
768 | } |
769 | |
770 | static void vcap_api_actionfield_typegroup_test(struct kunit *test) |
771 | { |
772 | const struct vcap_typegroup *tg; |
773 | |
774 | tg = vcap_actionfield_typegroup(vctrl: &test_vctrl, vt: VCAP_TYPE_IS0, actionset: VCAP_AFS_FULL); |
775 | KUNIT_EXPECT_PTR_NE(test, NULL, tg); |
776 | KUNIT_EXPECT_EQ(test, 0, tg[0].offset); |
777 | KUNIT_EXPECT_EQ(test, 3, tg[0].width); |
778 | KUNIT_EXPECT_EQ(test, 4, tg[0].value); |
779 | KUNIT_EXPECT_EQ(test, 110, tg[1].offset); |
780 | KUNIT_EXPECT_EQ(test, 2, tg[1].width); |
781 | KUNIT_EXPECT_EQ(test, 0, tg[1].value); |
782 | KUNIT_EXPECT_EQ(test, 220, tg[2].offset); |
783 | KUNIT_EXPECT_EQ(test, 2, tg[2].width); |
784 | KUNIT_EXPECT_EQ(test, 0, tg[2].value); |
785 | KUNIT_EXPECT_EQ(test, 0, tg[3].offset); |
786 | KUNIT_EXPECT_EQ(test, 0, tg[3].width); |
787 | KUNIT_EXPECT_EQ(test, 0, tg[3].value); |
788 | |
789 | tg = vcap_actionfield_typegroup(vctrl: &test_vctrl, vt: VCAP_TYPE_IS2, actionset: VCAP_AFS_CLASSIFICATION); |
790 | KUNIT_EXPECT_PTR_EQ(test, NULL, tg); |
791 | } |
792 | |
793 | static void vcap_api_vcap_keyfields_test(struct kunit *test) |
794 | { |
795 | const struct vcap_field *ft; |
796 | |
797 | ft = vcap_keyfields(vctrl: &test_vctrl, vt: VCAP_TYPE_IS2, keyset: VCAP_KFS_MAC_ETYPE); |
798 | KUNIT_EXPECT_PTR_NE(test, NULL, ft); |
799 | |
800 | /* Keyset that is not available and within the maximum keyset enum value */ |
801 | ft = vcap_keyfields(vctrl: &test_vctrl, vt: VCAP_TYPE_ES2, keyset: VCAP_KFS_PURE_5TUPLE_IP4); |
802 | KUNIT_EXPECT_PTR_EQ(test, NULL, ft); |
803 | |
804 | /* Keyset that is not available and beyond the maximum keyset enum value */ |
805 | ft = vcap_keyfields(vctrl: &test_vctrl, vt: VCAP_TYPE_ES2, keyset: VCAP_KFS_LL_FULL); |
806 | KUNIT_EXPECT_PTR_EQ(test, NULL, ft); |
807 | } |
808 | |
809 | static void vcap_api_vcap_actionfields_test(struct kunit *test) |
810 | { |
811 | const struct vcap_field *ft; |
812 | |
813 | ft = vcap_actionfields(vctrl: &test_vctrl, vt: VCAP_TYPE_IS0, actionset: VCAP_AFS_FULL); |
814 | KUNIT_EXPECT_PTR_NE(test, NULL, ft); |
815 | |
816 | ft = vcap_actionfields(vctrl: &test_vctrl, vt: VCAP_TYPE_IS2, actionset: VCAP_AFS_FULL); |
817 | KUNIT_EXPECT_PTR_EQ(test, NULL, ft); |
818 | |
819 | ft = vcap_actionfields(vctrl: &test_vctrl, vt: VCAP_TYPE_IS2, actionset: VCAP_AFS_CLASSIFICATION); |
820 | KUNIT_EXPECT_PTR_EQ(test, NULL, ft); |
821 | } |
822 | |
823 | static void vcap_api_encode_rule_keyset_test(struct kunit *test) |
824 | { |
825 | u32 keywords[16] = {0}; |
826 | u32 maskwords[16] = {0}; |
827 | struct vcap_admin admin = { |
828 | .vtype = VCAP_TYPE_IS2, |
829 | .cache = { |
830 | .keystream = keywords, |
831 | .maskstream = maskwords, |
832 | }, |
833 | }; |
834 | struct vcap_rule_internal rule = { |
835 | .admin = &admin, |
836 | .data = { |
837 | .keyset = VCAP_KFS_MAC_ETYPE, |
838 | }, |
839 | .vctrl = &test_vctrl, |
840 | }; |
841 | struct vcap_client_keyfield ckf[] = { |
842 | { |
843 | .ctrl.key = VCAP_KF_TYPE, |
844 | .ctrl.type = VCAP_FIELD_U32, |
845 | .data.u32.value = 0x00, |
846 | .data.u32.mask = 0x0f, |
847 | }, |
848 | { |
849 | .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, |
850 | .ctrl.type = VCAP_FIELD_BIT, |
851 | .data.u1.value = 0x01, |
852 | .data.u1.mask = 0x01, |
853 | }, |
854 | { |
855 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_L3, |
856 | .ctrl.type = VCAP_FIELD_BIT, |
857 | .data.u1.value = 0x00, |
858 | .data.u1.mask = 0x01, |
859 | }, |
860 | { |
861 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_RNG, |
862 | .ctrl.type = VCAP_FIELD_U32, |
863 | .data.u32.value = 0x00, |
864 | .data.u32.mask = 0x0f, |
865 | }, |
866 | { |
867 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK, |
868 | .ctrl.type = VCAP_FIELD_U72, |
869 | .data.u72.value = {0x0, 0x00, 0x00, 0x00}, |
870 | .data.u72.mask = {0xfd, 0xff, 0xff, 0xff}, |
871 | }, |
872 | { |
873 | .ctrl.key = VCAP_KF_L2_DMAC, |
874 | .ctrl.type = VCAP_FIELD_U48, |
875 | /* Opposite endianness */ |
876 | .data.u48.value = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, |
877 | .data.u48.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, |
878 | }, |
879 | { |
880 | .ctrl.key = VCAP_KF_ETYPE_LEN_IS, |
881 | .ctrl.type = VCAP_FIELD_BIT, |
882 | .data.u1.value = 0x01, |
883 | .data.u1.mask = 0x01, |
884 | }, |
885 | { |
886 | .ctrl.key = VCAP_KF_ETYPE, |
887 | .ctrl.type = VCAP_FIELD_U32, |
888 | .data.u32.value = 0xaabb, |
889 | .data.u32.mask = 0xffff, |
890 | }, |
891 | }; |
892 | int idx; |
893 | int ret; |
894 | |
895 | /* Empty entry list */ |
896 | INIT_LIST_HEAD(list: &rule.data.keyfields); |
897 | ret = vcap_encode_rule_keyset(ri: &rule); |
898 | KUNIT_EXPECT_EQ(test, -EINVAL, ret); |
899 | |
900 | for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) |
901 | list_add_tail(new: &ckf[idx].ctrl.list, head: &rule.data.keyfields); |
902 | ret = vcap_encode_rule_keyset(ri: &rule); |
903 | KUNIT_EXPECT_EQ(test, 0, ret); |
904 | |
905 | /* The key and mask values below are from an actual Sparx5 rule config */ |
906 | /* Key */ |
907 | KUNIT_EXPECT_EQ(test, (u32)0x00000042, keywords[0]); |
908 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[1]); |
909 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[2]); |
910 | KUNIT_EXPECT_EQ(test, (u32)0x00020100, keywords[3]); |
911 | KUNIT_EXPECT_EQ(test, (u32)0x60504030, keywords[4]); |
912 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[5]); |
913 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[6]); |
914 | KUNIT_EXPECT_EQ(test, (u32)0x0002aaee, keywords[7]); |
915 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[8]); |
916 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[9]); |
917 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[10]); |
918 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, keywords[11]); |
919 | |
920 | /* Mask: they will be inverted when applied to the register */ |
921 | KUNIT_EXPECT_EQ(test, (u32)~0x00b07f80, maskwords[0]); |
922 | KUNIT_EXPECT_EQ(test, (u32)~0xfff00000, maskwords[1]); |
923 | KUNIT_EXPECT_EQ(test, (u32)~0xfffffffc, maskwords[2]); |
924 | KUNIT_EXPECT_EQ(test, (u32)~0xfff000ff, maskwords[3]); |
925 | KUNIT_EXPECT_EQ(test, (u32)~0x00000000, maskwords[4]); |
926 | KUNIT_EXPECT_EQ(test, (u32)~0xfffffff0, maskwords[5]); |
927 | KUNIT_EXPECT_EQ(test, (u32)~0xfffffffe, maskwords[6]); |
928 | KUNIT_EXPECT_EQ(test, (u32)~0xfffc0001, maskwords[7]); |
929 | KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[8]); |
930 | KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[9]); |
931 | KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[10]); |
932 | KUNIT_EXPECT_EQ(test, (u32)~0xffffffff, maskwords[11]); |
933 | } |
934 | |
935 | static void vcap_api_encode_rule_actionset_test(struct kunit *test) |
936 | { |
937 | u32 actwords[16] = {0}; |
938 | struct vcap_admin admin = { |
939 | .vtype = VCAP_TYPE_IS2, |
940 | .cache = { |
941 | .actionstream = actwords, |
942 | }, |
943 | }; |
944 | struct vcap_rule_internal rule = { |
945 | .admin = &admin, |
946 | .data = { |
947 | .actionset = VCAP_AFS_BASE_TYPE, |
948 | }, |
949 | .vctrl = &test_vctrl, |
950 | }; |
951 | struct vcap_client_actionfield caf[] = { |
952 | { |
953 | .ctrl.action = VCAP_AF_MATCH_ID, |
954 | .ctrl.type = VCAP_FIELD_U32, |
955 | .data.u32.value = 0x01, |
956 | }, |
957 | { |
958 | .ctrl.action = VCAP_AF_MATCH_ID_MASK, |
959 | .ctrl.type = VCAP_FIELD_U32, |
960 | .data.u32.value = 0x01, |
961 | }, |
962 | { |
963 | .ctrl.action = VCAP_AF_CNT_ID, |
964 | .ctrl.type = VCAP_FIELD_U32, |
965 | .data.u32.value = 0x64, |
966 | }, |
967 | }; |
968 | int idx; |
969 | int ret; |
970 | |
971 | /* Empty entry list */ |
972 | INIT_LIST_HEAD(list: &rule.data.actionfields); |
973 | ret = vcap_encode_rule_actionset(ri: &rule); |
974 | /* We allow rules with no actions */ |
975 | KUNIT_EXPECT_EQ(test, 0, ret); |
976 | |
977 | for (idx = 0; idx < ARRAY_SIZE(caf); idx++) |
978 | list_add_tail(new: &caf[idx].ctrl.list, head: &rule.data.actionfields); |
979 | ret = vcap_encode_rule_actionset(ri: &rule); |
980 | KUNIT_EXPECT_EQ(test, 0, ret); |
981 | |
982 | /* The action values below are from an actual Sparx5 rule config */ |
983 | KUNIT_EXPECT_EQ(test, (u32)0x00000002, actwords[0]); |
984 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[1]); |
985 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[2]); |
986 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[3]); |
987 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[4]); |
988 | KUNIT_EXPECT_EQ(test, (u32)0x00100000, actwords[5]); |
989 | KUNIT_EXPECT_EQ(test, (u32)0x06400010, actwords[6]); |
990 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[7]); |
991 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[8]); |
992 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[9]); |
993 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[10]); |
994 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[11]); |
995 | } |
996 | |
997 | static void vcap_free_ckf(struct vcap_rule *rule) |
998 | { |
999 | struct vcap_client_keyfield *ckf, *next_ckf; |
1000 | |
1001 | list_for_each_entry_safe(ckf, next_ckf, &rule->keyfields, ctrl.list) { |
1002 | list_del(entry: &ckf->ctrl.list); |
1003 | kfree(objp: ckf); |
1004 | } |
1005 | } |
1006 | |
1007 | static void vcap_api_rule_add_keyvalue_test(struct kunit *test) |
1008 | { |
1009 | struct vcap_admin admin = { |
1010 | .vtype = VCAP_TYPE_IS2, |
1011 | }; |
1012 | struct vcap_rule_internal ri = { |
1013 | .admin = &admin, |
1014 | .data = { |
1015 | .keyset = VCAP_KFS_NO_VALUE, |
1016 | }, |
1017 | .vctrl = &test_vctrl, |
1018 | }; |
1019 | struct vcap_rule *rule = (struct vcap_rule *)&ri; |
1020 | struct vcap_client_keyfield *kf; |
1021 | int ret; |
1022 | struct vcap_u128_key dip = { |
1023 | .value = {0x17, 0x26, 0x35, 0x44, 0x63, 0x62, 0x71}, |
1024 | .mask = {0xf1, 0xf2, 0xf3, 0xf4, 0x4f, 0x3f, 0x2f, 0x1f}, |
1025 | }; |
1026 | int idx; |
1027 | |
1028 | INIT_LIST_HEAD(list: &rule->keyfields); |
1029 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0); |
1030 | KUNIT_EXPECT_EQ(test, 0, ret); |
1031 | ret = list_empty(head: &rule->keyfields); |
1032 | KUNIT_EXPECT_EQ(test, false, ret); |
1033 | kf = list_first_entry(&rule->keyfields, struct vcap_client_keyfield, |
1034 | ctrl.list); |
1035 | KUNIT_EXPECT_EQ(test, VCAP_KF_LOOKUP_FIRST_IS, kf->ctrl.key); |
1036 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
1037 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); |
1038 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); |
1039 | vcap_free_ckf(rule); |
1040 | |
1041 | INIT_LIST_HEAD(list: &rule->keyfields); |
1042 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); |
1043 | KUNIT_EXPECT_EQ(test, 0, ret); |
1044 | ret = list_empty(head: &rule->keyfields); |
1045 | KUNIT_EXPECT_EQ(test, false, ret); |
1046 | kf = list_first_entry(&rule->keyfields, struct vcap_client_keyfield, |
1047 | ctrl.list); |
1048 | KUNIT_EXPECT_EQ(test, VCAP_KF_LOOKUP_FIRST_IS, kf->ctrl.key); |
1049 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
1050 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.value); |
1051 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); |
1052 | vcap_free_ckf(rule); |
1053 | |
1054 | INIT_LIST_HEAD(list: &rule->keyfields); |
1055 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, |
1056 | VCAP_BIT_ANY); |
1057 | KUNIT_EXPECT_EQ(test, 0, ret); |
1058 | ret = list_empty(head: &rule->keyfields); |
1059 | KUNIT_EXPECT_EQ(test, false, ret); |
1060 | kf = list_first_entry(&rule->keyfields, struct vcap_client_keyfield, |
1061 | ctrl.list); |
1062 | KUNIT_EXPECT_EQ(test, VCAP_KF_LOOKUP_FIRST_IS, kf->ctrl.key); |
1063 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
1064 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); |
1065 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.mask); |
1066 | vcap_free_ckf(rule); |
1067 | |
1068 | INIT_LIST_HEAD(list: &rule->keyfields); |
1069 | ret = vcap_rule_add_key_u32(rule, VCAP_KF_TYPE, 0x98765432, 0xff00ffab); |
1070 | KUNIT_EXPECT_EQ(test, 0, ret); |
1071 | ret = list_empty(head: &rule->keyfields); |
1072 | KUNIT_EXPECT_EQ(test, false, ret); |
1073 | kf = list_first_entry(&rule->keyfields, struct vcap_client_keyfield, |
1074 | ctrl.list); |
1075 | KUNIT_EXPECT_EQ(test, VCAP_KF_TYPE, kf->ctrl.key); |
1076 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, kf->ctrl.type); |
1077 | KUNIT_EXPECT_EQ(test, 0x98765432, kf->data.u32.value); |
1078 | KUNIT_EXPECT_EQ(test, 0xff00ffab, kf->data.u32.mask); |
1079 | vcap_free_ckf(rule); |
1080 | |
1081 | INIT_LIST_HEAD(list: &rule->keyfields); |
1082 | ret = vcap_rule_add_key_u128(rule, VCAP_KF_L3_IP6_SIP, &dip); |
1083 | KUNIT_EXPECT_EQ(test, 0, ret); |
1084 | ret = list_empty(head: &rule->keyfields); |
1085 | KUNIT_EXPECT_EQ(test, false, ret); |
1086 | kf = list_first_entry(&rule->keyfields, struct vcap_client_keyfield, |
1087 | ctrl.list); |
1088 | KUNIT_EXPECT_EQ(test, VCAP_KF_L3_IP6_SIP, kf->ctrl.key); |
1089 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U128, kf->ctrl.type); |
1090 | for (idx = 0; idx < ARRAY_SIZE(dip.value); ++idx) |
1091 | KUNIT_EXPECT_EQ(test, dip.value[idx], kf->data.u128.value[idx]); |
1092 | for (idx = 0; idx < ARRAY_SIZE(dip.mask); ++idx) |
1093 | KUNIT_EXPECT_EQ(test, dip.mask[idx], kf->data.u128.mask[idx]); |
1094 | vcap_free_ckf(rule); |
1095 | } |
1096 | |
1097 | static void vcap_free_caf(struct vcap_rule *rule) |
1098 | { |
1099 | struct vcap_client_actionfield *caf, *next_caf; |
1100 | |
1101 | list_for_each_entry_safe(caf, next_caf, |
1102 | &rule->actionfields, ctrl.list) { |
1103 | list_del(entry: &caf->ctrl.list); |
1104 | kfree(objp: caf); |
1105 | } |
1106 | } |
1107 | |
1108 | static void vcap_api_rule_add_actionvalue_test(struct kunit *test) |
1109 | { |
1110 | struct vcap_admin admin = { |
1111 | .vtype = VCAP_TYPE_IS2, |
1112 | }; |
1113 | struct vcap_rule_internal ri = { |
1114 | .admin = &admin, |
1115 | .data = { |
1116 | .actionset = VCAP_AFS_NO_VALUE, |
1117 | }, |
1118 | }; |
1119 | struct vcap_rule *rule = (struct vcap_rule *)&ri; |
1120 | struct vcap_client_actionfield *af; |
1121 | int ret; |
1122 | |
1123 | INIT_LIST_HEAD(list: &rule->actionfields); |
1124 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_0); |
1125 | KUNIT_EXPECT_EQ(test, 0, ret); |
1126 | ret = list_empty(head: &rule->actionfields); |
1127 | KUNIT_EXPECT_EQ(test, false, ret); |
1128 | af = list_first_entry(&rule->actionfields, |
1129 | struct vcap_client_actionfield, ctrl.list); |
1130 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
1131 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
1132 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); |
1133 | vcap_free_caf(rule); |
1134 | |
1135 | INIT_LIST_HEAD(list: &rule->actionfields); |
1136 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_1); |
1137 | KUNIT_EXPECT_EQ(test, 0, ret); |
1138 | ret = list_empty(head: &rule->actionfields); |
1139 | KUNIT_EXPECT_EQ(test, false, ret); |
1140 | af = list_first_entry(&rule->actionfields, |
1141 | struct vcap_client_actionfield, ctrl.list); |
1142 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
1143 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
1144 | KUNIT_EXPECT_EQ(test, 0x1, af->data.u1.value); |
1145 | vcap_free_caf(rule); |
1146 | |
1147 | INIT_LIST_HEAD(list: &rule->actionfields); |
1148 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_ANY); |
1149 | KUNIT_EXPECT_EQ(test, 0, ret); |
1150 | ret = list_empty(head: &rule->actionfields); |
1151 | KUNIT_EXPECT_EQ(test, false, ret); |
1152 | af = list_first_entry(&rule->actionfields, |
1153 | struct vcap_client_actionfield, ctrl.list); |
1154 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
1155 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
1156 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); |
1157 | vcap_free_caf(rule); |
1158 | |
1159 | INIT_LIST_HEAD(list: &rule->actionfields); |
1160 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_TYPE, 0x98765432); |
1161 | KUNIT_EXPECT_EQ(test, 0, ret); |
1162 | ret = list_empty(head: &rule->actionfields); |
1163 | KUNIT_EXPECT_EQ(test, false, ret); |
1164 | af = list_first_entry(&rule->actionfields, |
1165 | struct vcap_client_actionfield, ctrl.list); |
1166 | KUNIT_EXPECT_EQ(test, VCAP_AF_TYPE, af->ctrl.action); |
1167 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); |
1168 | KUNIT_EXPECT_EQ(test, 0x98765432, af->data.u32.value); |
1169 | vcap_free_caf(rule); |
1170 | |
1171 | INIT_LIST_HEAD(list: &rule->actionfields); |
1172 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_MASK_MODE, 0xaabbccdd); |
1173 | KUNIT_EXPECT_EQ(test, 0, ret); |
1174 | ret = list_empty(head: &rule->actionfields); |
1175 | KUNIT_EXPECT_EQ(test, false, ret); |
1176 | af = list_first_entry(&rule->actionfields, |
1177 | struct vcap_client_actionfield, ctrl.list); |
1178 | KUNIT_EXPECT_EQ(test, VCAP_AF_MASK_MODE, af->ctrl.action); |
1179 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); |
1180 | KUNIT_EXPECT_EQ(test, 0xaabbccdd, af->data.u32.value); |
1181 | vcap_free_caf(rule); |
1182 | } |
1183 | |
1184 | static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) |
1185 | { |
1186 | struct vcap_keyset_list matches = {}; |
1187 | struct vcap_admin admin = { |
1188 | .vtype = VCAP_TYPE_IS2, |
1189 | }; |
1190 | struct vcap_rule_internal ri = { |
1191 | .admin = &admin, |
1192 | .vctrl = &test_vctrl, |
1193 | }; |
1194 | struct vcap_client_keyfield ckf[] = { |
1195 | { |
1196 | .ctrl.key = VCAP_KF_TYPE, |
1197 | }, { |
1198 | .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, |
1199 | }, { |
1200 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_L3, |
1201 | }, { |
1202 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_RNG, |
1203 | }, { |
1204 | .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK, |
1205 | }, { |
1206 | .ctrl.key = VCAP_KF_L2_DMAC, |
1207 | }, { |
1208 | .ctrl.key = VCAP_KF_ETYPE_LEN_IS, |
1209 | }, { |
1210 | .ctrl.key = VCAP_KF_ETYPE, |
1211 | }, |
1212 | }; |
1213 | int idx; |
1214 | bool ret; |
1215 | enum vcap_keyfield_set keysets[10] = {}; |
1216 | |
1217 | matches.keysets = keysets; |
1218 | matches.max = ARRAY_SIZE(keysets); |
1219 | |
1220 | INIT_LIST_HEAD(list: &ri.data.keyfields); |
1221 | for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) |
1222 | list_add_tail(new: &ckf[idx].ctrl.list, head: &ri.data.keyfields); |
1223 | |
1224 | ret = vcap_rule_find_keysets(&ri.data, &matches); |
1225 | |
1226 | KUNIT_EXPECT_EQ(test, true, ret); |
1227 | KUNIT_EXPECT_EQ(test, 1, matches.cnt); |
1228 | KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, matches.keysets[0]); |
1229 | } |
1230 | |
1231 | static void vcap_api_rule_find_keyset_failed_test(struct kunit *test) |
1232 | { |
1233 | struct vcap_keyset_list matches = {}; |
1234 | struct vcap_admin admin = { |
1235 | .vtype = VCAP_TYPE_IS2, |
1236 | }; |
1237 | struct vcap_rule_internal ri = { |
1238 | .admin = &admin, |
1239 | .vctrl = &test_vctrl, |
1240 | }; |
1241 | struct vcap_client_keyfield ckf[] = { |
1242 | { |
1243 | .ctrl.key = VCAP_KF_TYPE, |
1244 | }, { |
1245 | .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, |
1246 | }, { |
1247 | .ctrl.key = VCAP_KF_ARP_OPCODE, |
1248 | }, { |
1249 | .ctrl.key = VCAP_KF_L3_IP4_SIP, |
1250 | }, { |
1251 | .ctrl.key = VCAP_KF_L3_IP4_DIP, |
1252 | }, { |
1253 | .ctrl.key = VCAP_KF_8021Q_PCP_CLS, |
1254 | }, { |
1255 | .ctrl.key = VCAP_KF_ETYPE_LEN_IS, /* Not with ARP */ |
1256 | }, { |
1257 | .ctrl.key = VCAP_KF_ETYPE, /* Not with ARP */ |
1258 | }, |
1259 | }; |
1260 | int idx; |
1261 | bool ret; |
1262 | enum vcap_keyfield_set keysets[10] = {}; |
1263 | |
1264 | matches.keysets = keysets; |
1265 | matches.max = ARRAY_SIZE(keysets); |
1266 | |
1267 | INIT_LIST_HEAD(list: &ri.data.keyfields); |
1268 | for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) |
1269 | list_add_tail(new: &ckf[idx].ctrl.list, head: &ri.data.keyfields); |
1270 | |
1271 | ret = vcap_rule_find_keysets(&ri.data, &matches); |
1272 | |
1273 | KUNIT_EXPECT_EQ(test, false, ret); |
1274 | KUNIT_EXPECT_EQ(test, 0, matches.cnt); |
1275 | KUNIT_EXPECT_EQ(test, VCAP_KFS_NO_VALUE, matches.keysets[0]); |
1276 | } |
1277 | |
1278 | static void vcap_api_rule_find_keyset_many_test(struct kunit *test) |
1279 | { |
1280 | struct vcap_keyset_list matches = {}; |
1281 | struct vcap_admin admin = { |
1282 | .vtype = VCAP_TYPE_IS2, |
1283 | }; |
1284 | struct vcap_rule_internal ri = { |
1285 | .admin = &admin, |
1286 | .vctrl = &test_vctrl, |
1287 | }; |
1288 | struct vcap_client_keyfield ckf[] = { |
1289 | { |
1290 | .ctrl.key = VCAP_KF_TYPE, |
1291 | }, { |
1292 | .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, |
1293 | }, { |
1294 | .ctrl.key = VCAP_KF_8021Q_DEI_CLS, |
1295 | }, { |
1296 | .ctrl.key = VCAP_KF_8021Q_PCP_CLS, |
1297 | }, { |
1298 | .ctrl.key = VCAP_KF_8021Q_VID_CLS, |
1299 | }, { |
1300 | .ctrl.key = VCAP_KF_ISDX_CLS, |
1301 | }, { |
1302 | .ctrl.key = VCAP_KF_L2_MC_IS, |
1303 | }, { |
1304 | .ctrl.key = VCAP_KF_L2_BC_IS, |
1305 | }, |
1306 | }; |
1307 | int idx; |
1308 | bool ret; |
1309 | enum vcap_keyfield_set keysets[10] = {}; |
1310 | |
1311 | matches.keysets = keysets; |
1312 | matches.max = ARRAY_SIZE(keysets); |
1313 | |
1314 | INIT_LIST_HEAD(list: &ri.data.keyfields); |
1315 | for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) |
1316 | list_add_tail(new: &ckf[idx].ctrl.list, head: &ri.data.keyfields); |
1317 | |
1318 | ret = vcap_rule_find_keysets(&ri.data, &matches); |
1319 | |
1320 | KUNIT_EXPECT_EQ(test, true, ret); |
1321 | KUNIT_EXPECT_EQ(test, 6, matches.cnt); |
1322 | KUNIT_EXPECT_EQ(test, VCAP_KFS_ARP, matches.keysets[0]); |
1323 | KUNIT_EXPECT_EQ(test, VCAP_KFS_IP4_OTHER, matches.keysets[1]); |
1324 | KUNIT_EXPECT_EQ(test, VCAP_KFS_IP4_TCP_UDP, matches.keysets[2]); |
1325 | KUNIT_EXPECT_EQ(test, VCAP_KFS_IP6_STD, matches.keysets[3]); |
1326 | KUNIT_EXPECT_EQ(test, VCAP_KFS_IP_7TUPLE, matches.keysets[4]); |
1327 | KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, matches.keysets[5]); |
1328 | } |
1329 | |
1330 | static void vcap_api_encode_rule_test(struct kunit *test) |
1331 | { |
1332 | /* Data used by VCAP Library callback */ |
1333 | static u32 keydata[32] = {}; |
1334 | static u32 mskdata[32] = {}; |
1335 | static u32 actdata[32] = {}; |
1336 | |
1337 | struct vcap_admin is2_admin = { |
1338 | .vtype = VCAP_TYPE_IS2, |
1339 | .first_cid = 8000000, |
1340 | .last_cid = 8099999, |
1341 | .lookups = 4, |
1342 | .last_valid_addr = 3071, |
1343 | .first_valid_addr = 0, |
1344 | .last_used_addr = 800, |
1345 | .cache = { |
1346 | .keystream = keydata, |
1347 | .maskstream = mskdata, |
1348 | .actionstream = actdata, |
1349 | }, |
1350 | }; |
1351 | struct vcap_rule *rule; |
1352 | struct vcap_rule_internal *ri; |
1353 | int vcap_chain_id = 8000000; |
1354 | enum vcap_user user = VCAP_USER_VCAP_UTIL; |
1355 | u16 priority = 10; |
1356 | int id = 100; |
1357 | int ret; |
1358 | struct vcap_u48_key smac = { |
1359 | .value = { 0x88, 0x75, 0x32, 0x34, 0x9e, 0xb1 }, |
1360 | .mask = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } |
1361 | }; |
1362 | struct vcap_u48_key dmac = { |
1363 | .value = { 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }, |
1364 | .mask = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } |
1365 | }; |
1366 | u32 port_mask_rng_value = 0x05; |
1367 | u32 port_mask_rng_mask = 0x0f; |
1368 | u32 igr_port_mask_value = 0xffabcd01; |
1369 | u32 igr_port_mask_mask = ~0; |
1370 | /* counter is written as the first operation */ |
1371 | u32 expwriteaddr[] = {792, 792, 793, 794, 795, 796, 797}; |
1372 | int idx; |
1373 | |
1374 | vcap_test_api_init(admin: &is2_admin); |
1375 | |
1376 | /* Allocate the rule */ |
1377 | rule = vcap_alloc_rule(&test_vctrl, &test_netdev, vcap_chain_id, user, |
1378 | priority, id); |
1379 | KUNIT_EXPECT_PTR_NE(test, NULL, rule); |
1380 | ri = (struct vcap_rule_internal *)rule; |
1381 | |
1382 | /* Add rule keys */ |
1383 | ret = vcap_rule_add_key_u48(rule, VCAP_KF_L2_DMAC, &dmac); |
1384 | KUNIT_EXPECT_EQ(test, 0, ret); |
1385 | ret = vcap_rule_add_key_u48(rule, VCAP_KF_L2_SMAC, &smac); |
1386 | KUNIT_EXPECT_EQ(test, 0, ret); |
1387 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_ETYPE_LEN_IS, VCAP_BIT_1); |
1388 | KUNIT_EXPECT_EQ(test, 0, ret); |
1389 | /* Cannot add the same field twice */ |
1390 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_ETYPE_LEN_IS, VCAP_BIT_1); |
1391 | KUNIT_EXPECT_EQ(test, -EINVAL, ret); |
1392 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_IF_IGR_PORT_MASK_L3, |
1393 | VCAP_BIT_ANY); |
1394 | KUNIT_EXPECT_EQ(test, 0, ret); |
1395 | ret = vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK_RNG, |
1396 | port_mask_rng_value, port_mask_rng_mask); |
1397 | KUNIT_EXPECT_EQ(test, 0, ret); |
1398 | ret = vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, |
1399 | igr_port_mask_value, igr_port_mask_mask); |
1400 | KUNIT_EXPECT_EQ(test, 0, ret); |
1401 | |
1402 | /* Add rule actions */ |
1403 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_1); |
1404 | KUNIT_EXPECT_EQ(test, 0, ret); |
1405 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_CNT_ID, id); |
1406 | KUNIT_EXPECT_EQ(test, 0, ret); |
1407 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_MATCH_ID, 1); |
1408 | KUNIT_EXPECT_EQ(test, 0, ret); |
1409 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_MATCH_ID_MASK, 1); |
1410 | KUNIT_EXPECT_EQ(test, 0, ret); |
1411 | |
1412 | /* For now the actionset is hardcoded */ |
1413 | ret = vcap_set_rule_set_actionset(rule, VCAP_AFS_BASE_TYPE); |
1414 | KUNIT_EXPECT_EQ(test, 0, ret); |
1415 | |
1416 | /* Validation with validate keyset callback */ |
1417 | ret = vcap_val_rule(rule, ETH_P_ALL); |
1418 | KUNIT_EXPECT_EQ(test, 0, ret); |
1419 | KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, rule->keyset); |
1420 | KUNIT_EXPECT_EQ(test, VCAP_AFS_BASE_TYPE, rule->actionset); |
1421 | KUNIT_EXPECT_EQ(test, 6, ri->size); |
1422 | KUNIT_EXPECT_EQ(test, 2, ri->keyset_sw_regs); |
1423 | KUNIT_EXPECT_EQ(test, 4, ri->actionset_sw_regs); |
1424 | |
1425 | /* Enable lookup, so the rule will be written */ |
1426 | ret = vcap_enable_lookups(&test_vctrl, &test_netdev, 0, |
1427 | rule->vcap_chain_id, rule->cookie, true); |
1428 | KUNIT_EXPECT_EQ(test, 0, ret); |
1429 | |
1430 | /* Add rule with write callback */ |
1431 | ret = vcap_add_rule(rule); |
1432 | KUNIT_EXPECT_EQ(test, 0, ret); |
1433 | KUNIT_EXPECT_EQ(test, 792, is2_admin.last_used_addr); |
1434 | for (idx = 0; idx < ARRAY_SIZE(expwriteaddr); ++idx) |
1435 | KUNIT_EXPECT_EQ(test, expwriteaddr[idx], test_updateaddr[idx]); |
1436 | |
1437 | /* Check that the rule has been added */ |
1438 | ret = list_empty(head: &is2_admin.rules); |
1439 | KUNIT_EXPECT_EQ(test, false, ret); |
1440 | KUNIT_EXPECT_EQ(test, 0, ret); |
1441 | |
1442 | vcap_enable_lookups(&test_vctrl, &test_netdev, 0, 0, |
1443 | rule->cookie, false); |
1444 | |
1445 | vcap_free_rule(rule); |
1446 | |
1447 | /* Check that the rule has been freed: tricky to access since this |
1448 | * memory should not be accessible anymore |
1449 | */ |
1450 | KUNIT_EXPECT_PTR_NE(test, NULL, rule); |
1451 | ret = list_empty(head: &rule->keyfields); |
1452 | KUNIT_EXPECT_EQ(test, true, ret); |
1453 | ret = list_empty(head: &rule->actionfields); |
1454 | KUNIT_EXPECT_EQ(test, true, ret); |
1455 | |
1456 | vcap_del_rule(&test_vctrl, &test_netdev, id); |
1457 | } |
1458 | |
1459 | static void vcap_api_set_rule_counter_test(struct kunit *test) |
1460 | { |
1461 | struct vcap_admin is2_admin = { |
1462 | .cache = { |
1463 | .counter = 100, |
1464 | .sticky = true, |
1465 | }, |
1466 | }; |
1467 | struct vcap_rule_internal ri = { |
1468 | .data = { |
1469 | .id = 1001, |
1470 | }, |
1471 | .addr = 600, |
1472 | .admin = &is2_admin, |
1473 | .counter_id = 1002, |
1474 | .vctrl = &test_vctrl, |
1475 | }; |
1476 | struct vcap_rule_internal ri2 = { |
1477 | .data = { |
1478 | .id = 2001, |
1479 | }, |
1480 | .addr = 700, |
1481 | .admin = &is2_admin, |
1482 | .counter_id = 2002, |
1483 | .vctrl = &test_vctrl, |
1484 | }; |
1485 | struct vcap_counter ctr = { .value = 0, .sticky = false}; |
1486 | struct vcap_counter ctr2 = { .value = 101, .sticky = true}; |
1487 | int ret; |
1488 | |
1489 | vcap_test_api_init(admin: &is2_admin); |
1490 | list_add_tail(new: &ri.list, head: &is2_admin.rules); |
1491 | list_add_tail(new: &ri2.list, head: &is2_admin.rules); |
1492 | |
1493 | pr_info("%s:%d\n" , __func__, __LINE__); |
1494 | ret = vcap_rule_set_counter(&ri.data, &ctr); |
1495 | pr_info("%s:%d\n" , __func__, __LINE__); |
1496 | KUNIT_EXPECT_EQ(test, 0, ret); |
1497 | |
1498 | KUNIT_EXPECT_EQ(test, 1002, test_hw_counter_id); |
1499 | KUNIT_EXPECT_EQ(test, 0, test_hw_cache.counter); |
1500 | KUNIT_EXPECT_EQ(test, false, test_hw_cache.sticky); |
1501 | KUNIT_EXPECT_EQ(test, 600, test_updateaddr[0]); |
1502 | |
1503 | ret = vcap_rule_set_counter(&ri2.data, &ctr2); |
1504 | KUNIT_EXPECT_EQ(test, 0, ret); |
1505 | |
1506 | KUNIT_EXPECT_EQ(test, 2002, test_hw_counter_id); |
1507 | KUNIT_EXPECT_EQ(test, 101, test_hw_cache.counter); |
1508 | KUNIT_EXPECT_EQ(test, true, test_hw_cache.sticky); |
1509 | KUNIT_EXPECT_EQ(test, 700, test_updateaddr[1]); |
1510 | } |
1511 | |
1512 | static void vcap_api_get_rule_counter_test(struct kunit *test) |
1513 | { |
1514 | struct vcap_admin is2_admin = { |
1515 | .cache = { |
1516 | .counter = 100, |
1517 | .sticky = true, |
1518 | }, |
1519 | }; |
1520 | struct vcap_rule_internal ri = { |
1521 | .data = { |
1522 | .id = 1010, |
1523 | }, |
1524 | .addr = 400, |
1525 | .admin = &is2_admin, |
1526 | .counter_id = 1011, |
1527 | .vctrl = &test_vctrl, |
1528 | }; |
1529 | struct vcap_rule_internal ri2 = { |
1530 | .data = { |
1531 | .id = 2011, |
1532 | }, |
1533 | .addr = 300, |
1534 | .admin = &is2_admin, |
1535 | .counter_id = 2012, |
1536 | .vctrl = &test_vctrl, |
1537 | }; |
1538 | struct vcap_counter ctr = {}; |
1539 | struct vcap_counter ctr2 = {}; |
1540 | int ret; |
1541 | |
1542 | vcap_test_api_init(admin: &is2_admin); |
1543 | test_hw_cache.counter = 55; |
1544 | test_hw_cache.sticky = true; |
1545 | |
1546 | list_add_tail(new: &ri.list, head: &is2_admin.rules); |
1547 | list_add_tail(new: &ri2.list, head: &is2_admin.rules); |
1548 | |
1549 | ret = vcap_rule_get_counter(&ri.data, &ctr); |
1550 | KUNIT_EXPECT_EQ(test, 0, ret); |
1551 | |
1552 | KUNIT_EXPECT_EQ(test, 1011, test_hw_counter_id); |
1553 | KUNIT_EXPECT_EQ(test, 55, ctr.value); |
1554 | KUNIT_EXPECT_EQ(test, true, ctr.sticky); |
1555 | KUNIT_EXPECT_EQ(test, 400, test_updateaddr[0]); |
1556 | |
1557 | test_hw_cache.counter = 22; |
1558 | test_hw_cache.sticky = false; |
1559 | |
1560 | ret = vcap_rule_get_counter(&ri2.data, &ctr2); |
1561 | KUNIT_EXPECT_EQ(test, 0, ret); |
1562 | |
1563 | KUNIT_EXPECT_EQ(test, 2012, test_hw_counter_id); |
1564 | KUNIT_EXPECT_EQ(test, 22, ctr2.value); |
1565 | KUNIT_EXPECT_EQ(test, false, ctr2.sticky); |
1566 | KUNIT_EXPECT_EQ(test, 300, test_updateaddr[1]); |
1567 | } |
1568 | |
1569 | static void vcap_api_rule_insert_in_order_test(struct kunit *test) |
1570 | { |
1571 | /* Data used by VCAP Library callback */ |
1572 | static u32 keydata[32] = {}; |
1573 | static u32 mskdata[32] = {}; |
1574 | static u32 actdata[32] = {}; |
1575 | |
1576 | struct vcap_admin admin = { |
1577 | .vtype = VCAP_TYPE_IS0, |
1578 | .first_cid = 10000, |
1579 | .last_cid = 19999, |
1580 | .lookups = 4, |
1581 | .last_valid_addr = 3071, |
1582 | .first_valid_addr = 0, |
1583 | .last_used_addr = 800, |
1584 | .cache = { |
1585 | .keystream = keydata, |
1586 | .maskstream = mskdata, |
1587 | .actionstream = actdata, |
1588 | }, |
1589 | }; |
1590 | |
1591 | vcap_test_api_init(admin: &admin); |
1592 | |
1593 | /* Create rules with different sizes and check that they are placed |
1594 | * at the correct address in the VCAP according to size |
1595 | */ |
1596 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 10, id: 500, size: 12, expected_addr: 780); |
1597 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 20, id: 400, size: 6, expected_addr: 774); |
1598 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 30, id: 300, size: 3, expected_addr: 771); |
1599 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 40, id: 200, size: 2, expected_addr: 768); |
1600 | |
1601 | vcap_del_rule(&test_vctrl, &test_netdev, 200); |
1602 | vcap_del_rule(&test_vctrl, &test_netdev, 300); |
1603 | vcap_del_rule(&test_vctrl, &test_netdev, 400); |
1604 | vcap_del_rule(&test_vctrl, &test_netdev, 500); |
1605 | } |
1606 | |
1607 | static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) |
1608 | { |
1609 | /* Data used by VCAP Library callback */ |
1610 | static u32 keydata[32] = {}; |
1611 | static u32 mskdata[32] = {}; |
1612 | static u32 actdata[32] = {}; |
1613 | |
1614 | struct vcap_admin admin = { |
1615 | .vtype = VCAP_TYPE_IS0, |
1616 | .first_cid = 10000, |
1617 | .last_cid = 19999, |
1618 | .lookups = 4, |
1619 | .last_valid_addr = 3071, |
1620 | .first_valid_addr = 0, |
1621 | .last_used_addr = 800, |
1622 | .cache = { |
1623 | .keystream = keydata, |
1624 | .maskstream = mskdata, |
1625 | .actionstream = actdata, |
1626 | }, |
1627 | }; |
1628 | struct vcap_rule_internal *elem; |
1629 | u32 exp_addr[] = {780, 774, 771, 768, 767}; |
1630 | int idx; |
1631 | |
1632 | vcap_test_api_init(admin: &admin); |
1633 | |
1634 | /* Create rules with different sizes and check that they are placed |
1635 | * at the correct address in the VCAP according to size |
1636 | */ |
1637 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 20, id: 200, size: 2, expected_addr: 798); |
1638 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1639 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1640 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1641 | |
1642 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 30, id: 300, size: 3, expected_addr: 795); |
1643 | KUNIT_EXPECT_EQ(test, 6, test_move_offset); |
1644 | KUNIT_EXPECT_EQ(test, 3, test_move_count); |
1645 | KUNIT_EXPECT_EQ(test, 798, test_move_addr); |
1646 | |
1647 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 40, id: 400, size: 6, expected_addr: 792); |
1648 | KUNIT_EXPECT_EQ(test, 6, test_move_offset); |
1649 | KUNIT_EXPECT_EQ(test, 6, test_move_count); |
1650 | KUNIT_EXPECT_EQ(test, 792, test_move_addr); |
1651 | |
1652 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 50, id: 500, size: 12, expected_addr: 780); |
1653 | KUNIT_EXPECT_EQ(test, 18, test_move_offset); |
1654 | KUNIT_EXPECT_EQ(test, 12, test_move_count); |
1655 | KUNIT_EXPECT_EQ(test, 786, test_move_addr); |
1656 | |
1657 | idx = 0; |
1658 | list_for_each_entry(elem, &admin.rules, list) { |
1659 | KUNIT_EXPECT_EQ(test, exp_addr[idx], elem->addr); |
1660 | ++idx; |
1661 | } |
1662 | KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); |
1663 | |
1664 | vcap_del_rule(&test_vctrl, &test_netdev, 500); |
1665 | vcap_del_rule(&test_vctrl, &test_netdev, 400); |
1666 | vcap_del_rule(&test_vctrl, &test_netdev, 300); |
1667 | vcap_del_rule(&test_vctrl, &test_netdev, 200); |
1668 | } |
1669 | |
1670 | static void vcap_api_rule_remove_at_end_test(struct kunit *test) |
1671 | { |
1672 | /* Data used by VCAP Library callback */ |
1673 | static u32 keydata[32] = {}; |
1674 | static u32 mskdata[32] = {}; |
1675 | static u32 actdata[32] = {}; |
1676 | |
1677 | struct vcap_admin admin = { |
1678 | .vtype = VCAP_TYPE_IS0, |
1679 | .first_cid = 10000, |
1680 | .last_cid = 19999, |
1681 | .lookups = 4, |
1682 | .last_valid_addr = 3071, |
1683 | .first_valid_addr = 0, |
1684 | .last_used_addr = 800, |
1685 | .cache = { |
1686 | .keystream = keydata, |
1687 | .maskstream = mskdata, |
1688 | .actionstream = actdata, |
1689 | }, |
1690 | }; |
1691 | int ret; |
1692 | |
1693 | vcap_test_api_init(admin: &admin); |
1694 | test_init_rule_deletion(); |
1695 | |
1696 | /* Create rules with different sizes and check that they are placed |
1697 | * at the correct address in the VCAP according to size |
1698 | */ |
1699 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 10, id: 500, size: 12, expected_addr: 780); |
1700 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 20, id: 400, size: 6, expected_addr: 774); |
1701 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 30, id: 300, size: 3, expected_addr: 771); |
1702 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 40, id: 200, size: 2, expected_addr: 768); |
1703 | |
1704 | /* Remove rules again from the end */ |
1705 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); |
1706 | KUNIT_EXPECT_EQ(test, 0, ret); |
1707 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1708 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1709 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1710 | KUNIT_EXPECT_EQ(test, 768, test_init_start); |
1711 | KUNIT_EXPECT_EQ(test, 2, test_init_count); |
1712 | KUNIT_EXPECT_EQ(test, 771, admin.last_used_addr); |
1713 | |
1714 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); |
1715 | KUNIT_EXPECT_EQ(test, ret, 0); |
1716 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1717 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1718 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1719 | KUNIT_EXPECT_EQ(test, 771, test_init_start); |
1720 | KUNIT_EXPECT_EQ(test, 3, test_init_count); |
1721 | KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); |
1722 | |
1723 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); |
1724 | KUNIT_EXPECT_EQ(test, ret, 0); |
1725 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1726 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1727 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1728 | KUNIT_EXPECT_EQ(test, 774, test_init_start); |
1729 | KUNIT_EXPECT_EQ(test, 6, test_init_count); |
1730 | KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); |
1731 | |
1732 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); |
1733 | KUNIT_EXPECT_EQ(test, ret, 0); |
1734 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1735 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1736 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1737 | KUNIT_EXPECT_EQ(test, 780, test_init_start); |
1738 | KUNIT_EXPECT_EQ(test, 12, test_init_count); |
1739 | KUNIT_EXPECT_EQ(test, 3072, admin.last_used_addr); |
1740 | } |
1741 | |
1742 | static void vcap_api_rule_remove_in_middle_test(struct kunit *test) |
1743 | { |
1744 | /* Data used by VCAP Library callback */ |
1745 | static u32 keydata[32] = {}; |
1746 | static u32 mskdata[32] = {}; |
1747 | static u32 actdata[32] = {}; |
1748 | |
1749 | struct vcap_admin admin = { |
1750 | .vtype = VCAP_TYPE_IS0, |
1751 | .first_cid = 10000, |
1752 | .last_cid = 19999, |
1753 | .lookups = 4, |
1754 | .first_valid_addr = 0, |
1755 | .last_used_addr = 800, |
1756 | .last_valid_addr = 800 - 1, |
1757 | .cache = { |
1758 | .keystream = keydata, |
1759 | .maskstream = mskdata, |
1760 | .actionstream = actdata, |
1761 | }, |
1762 | }; |
1763 | int ret; |
1764 | |
1765 | vcap_test_api_init(admin: &admin); |
1766 | |
1767 | /* Create rules with different sizes and check that they are placed |
1768 | * at the correct address in the VCAP according to size |
1769 | */ |
1770 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 10, id: 500, size: 12, expected_addr: 780); |
1771 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 20, id: 400, size: 6, expected_addr: 774); |
1772 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 30, id: 300, size: 3, expected_addr: 771); |
1773 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 40, id: 200, size: 2, expected_addr: 768); |
1774 | |
1775 | /* Remove rules in the middle */ |
1776 | test_init_rule_deletion(); |
1777 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); |
1778 | KUNIT_EXPECT_EQ(test, 0, ret); |
1779 | KUNIT_EXPECT_EQ(test, 768, test_move_addr); |
1780 | KUNIT_EXPECT_EQ(test, -6, test_move_offset); |
1781 | KUNIT_EXPECT_EQ(test, 6, test_move_count); |
1782 | KUNIT_EXPECT_EQ(test, 768, test_init_start); |
1783 | KUNIT_EXPECT_EQ(test, 6, test_init_count); |
1784 | KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); |
1785 | |
1786 | test_init_rule_deletion(); |
1787 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); |
1788 | KUNIT_EXPECT_EQ(test, 0, ret); |
1789 | KUNIT_EXPECT_EQ(test, 774, test_move_addr); |
1790 | KUNIT_EXPECT_EQ(test, -4, test_move_offset); |
1791 | KUNIT_EXPECT_EQ(test, 2, test_move_count); |
1792 | KUNIT_EXPECT_EQ(test, 774, test_init_start); |
1793 | KUNIT_EXPECT_EQ(test, 4, test_init_count); |
1794 | KUNIT_EXPECT_EQ(test, 778, admin.last_used_addr); |
1795 | |
1796 | test_init_rule_deletion(); |
1797 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); |
1798 | KUNIT_EXPECT_EQ(test, 0, ret); |
1799 | KUNIT_EXPECT_EQ(test, 778, test_move_addr); |
1800 | KUNIT_EXPECT_EQ(test, -20, test_move_offset); |
1801 | KUNIT_EXPECT_EQ(test, 2, test_move_count); |
1802 | KUNIT_EXPECT_EQ(test, 778, test_init_start); |
1803 | KUNIT_EXPECT_EQ(test, 20, test_init_count); |
1804 | KUNIT_EXPECT_EQ(test, 798, admin.last_used_addr); |
1805 | |
1806 | test_init_rule_deletion(); |
1807 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); |
1808 | KUNIT_EXPECT_EQ(test, 0, ret); |
1809 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1810 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1811 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1812 | KUNIT_EXPECT_EQ(test, 798, test_init_start); |
1813 | KUNIT_EXPECT_EQ(test, 2, test_init_count); |
1814 | KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr); |
1815 | } |
1816 | |
1817 | static void vcap_api_rule_remove_in_front_test(struct kunit *test) |
1818 | { |
1819 | /* Data used by VCAP Library callback */ |
1820 | static u32 keydata[32] = {}; |
1821 | static u32 mskdata[32] = {}; |
1822 | static u32 actdata[32] = {}; |
1823 | |
1824 | struct vcap_admin admin = { |
1825 | .vtype = VCAP_TYPE_IS0, |
1826 | .first_cid = 10000, |
1827 | .last_cid = 19999, |
1828 | .lookups = 4, |
1829 | .first_valid_addr = 0, |
1830 | .last_used_addr = 800, |
1831 | .last_valid_addr = 800 - 1, |
1832 | .cache = { |
1833 | .keystream = keydata, |
1834 | .maskstream = mskdata, |
1835 | .actionstream = actdata, |
1836 | }, |
1837 | }; |
1838 | int ret; |
1839 | |
1840 | vcap_test_api_init(admin: &admin); |
1841 | |
1842 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 10, id: 500, size: 12, expected_addr: 780); |
1843 | KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); |
1844 | |
1845 | test_init_rule_deletion(); |
1846 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); |
1847 | KUNIT_EXPECT_EQ(test, 0, ret); |
1848 | KUNIT_EXPECT_EQ(test, 0, test_move_addr); |
1849 | KUNIT_EXPECT_EQ(test, 0, test_move_offset); |
1850 | KUNIT_EXPECT_EQ(test, 0, test_move_count); |
1851 | KUNIT_EXPECT_EQ(test, 780, test_init_start); |
1852 | KUNIT_EXPECT_EQ(test, 12, test_init_count); |
1853 | KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr); |
1854 | |
1855 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 20, id: 400, size: 6, expected_addr: 792); |
1856 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 30, id: 300, size: 3, expected_addr: 789); |
1857 | test_vcap_xn_rule_creator(test, cid: 10000, user: VCAP_USER_QOS, priority: 40, id: 200, size: 2, expected_addr: 786); |
1858 | |
1859 | test_init_rule_deletion(); |
1860 | ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); |
1861 | KUNIT_EXPECT_EQ(test, 0, ret); |
1862 | KUNIT_EXPECT_EQ(test, 786, test_move_addr); |
1863 | KUNIT_EXPECT_EQ(test, -8, test_move_offset); |
1864 | KUNIT_EXPECT_EQ(test, 6, test_move_count); |
1865 | KUNIT_EXPECT_EQ(test, 786, test_init_start); |
1866 | KUNIT_EXPECT_EQ(test, 8, test_init_count); |
1867 | KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); |
1868 | |
1869 | vcap_del_rule(&test_vctrl, &test_netdev, 200); |
1870 | vcap_del_rule(&test_vctrl, &test_netdev, 300); |
1871 | } |
1872 | |
1873 | static struct kunit_case vcap_api_rule_remove_test_cases[] = { |
1874 | KUNIT_CASE(vcap_api_rule_remove_at_end_test), |
1875 | KUNIT_CASE(vcap_api_rule_remove_in_middle_test), |
1876 | KUNIT_CASE(vcap_api_rule_remove_in_front_test), |
1877 | {} |
1878 | }; |
1879 | |
1880 | static void vcap_api_next_lookup_basic_test(struct kunit *test) |
1881 | { |
1882 | struct vcap_admin admin1 = { |
1883 | .vtype = VCAP_TYPE_IS2, |
1884 | .vinst = 0, |
1885 | .first_cid = 8000000, |
1886 | .last_cid = 8199999, |
1887 | .lookups = 4, |
1888 | .lookups_per_instance = 2, |
1889 | }; |
1890 | struct vcap_admin admin2 = { |
1891 | .vtype = VCAP_TYPE_IS2, |
1892 | .vinst = 1, |
1893 | .first_cid = 8200000, |
1894 | .last_cid = 8399999, |
1895 | .lookups = 4, |
1896 | .lookups_per_instance = 2, |
1897 | }; |
1898 | bool ret; |
1899 | |
1900 | vcap_test_api_init(admin: &admin1); |
1901 | list_add_tail(new: &admin2.list, head: &test_vctrl.list); |
1902 | |
1903 | ret = vcap_is_next_lookup(&test_vctrl, 8000000, 1001000); |
1904 | KUNIT_EXPECT_EQ(test, false, ret); |
1905 | ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000); |
1906 | KUNIT_EXPECT_EQ(test, false, ret); |
1907 | ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000); |
1908 | KUNIT_EXPECT_EQ(test, true, ret); |
1909 | |
1910 | ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8101000); |
1911 | KUNIT_EXPECT_EQ(test, false, ret); |
1912 | ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8201000); |
1913 | KUNIT_EXPECT_EQ(test, true, ret); |
1914 | |
1915 | ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8201000); |
1916 | KUNIT_EXPECT_EQ(test, false, ret); |
1917 | ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8301000); |
1918 | KUNIT_EXPECT_EQ(test, true, ret); |
1919 | |
1920 | ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000); |
1921 | KUNIT_EXPECT_EQ(test, false, ret); |
1922 | ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000); |
1923 | KUNIT_EXPECT_EQ(test, false, ret); |
1924 | } |
1925 | |
1926 | static void vcap_api_next_lookup_advanced_test(struct kunit *test) |
1927 | { |
1928 | struct vcap_admin admin[] = { |
1929 | { |
1930 | .vtype = VCAP_TYPE_IS0, |
1931 | .vinst = 0, |
1932 | .first_cid = 1000000, |
1933 | .last_cid = 1199999, |
1934 | .lookups = 6, |
1935 | .lookups_per_instance = 2, |
1936 | }, { |
1937 | .vtype = VCAP_TYPE_IS0, |
1938 | .vinst = 1, |
1939 | .first_cid = 1200000, |
1940 | .last_cid = 1399999, |
1941 | .lookups = 6, |
1942 | .lookups_per_instance = 2, |
1943 | }, { |
1944 | .vtype = VCAP_TYPE_IS0, |
1945 | .vinst = 2, |
1946 | .first_cid = 1400000, |
1947 | .last_cid = 1599999, |
1948 | .lookups = 6, |
1949 | .lookups_per_instance = 2, |
1950 | }, { |
1951 | .vtype = VCAP_TYPE_IS2, |
1952 | .vinst = 0, |
1953 | .first_cid = 8000000, |
1954 | .last_cid = 8199999, |
1955 | .lookups = 4, |
1956 | .lookups_per_instance = 2, |
1957 | }, { |
1958 | .vtype = VCAP_TYPE_IS2, |
1959 | .vinst = 1, |
1960 | .first_cid = 8200000, |
1961 | .last_cid = 8399999, |
1962 | .lookups = 4, |
1963 | .lookups_per_instance = 2, |
1964 | } |
1965 | }; |
1966 | bool ret; |
1967 | |
1968 | vcap_test_api_init(admin: &admin[0]); |
1969 | list_add_tail(new: &admin[1].list, head: &test_vctrl.list); |
1970 | list_add_tail(new: &admin[2].list, head: &test_vctrl.list); |
1971 | list_add_tail(new: &admin[3].list, head: &test_vctrl.list); |
1972 | list_add_tail(new: &admin[4].list, head: &test_vctrl.list); |
1973 | |
1974 | ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1001000); |
1975 | KUNIT_EXPECT_EQ(test, false, ret); |
1976 | ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1101000); |
1977 | KUNIT_EXPECT_EQ(test, true, ret); |
1978 | |
1979 | ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1201000); |
1980 | KUNIT_EXPECT_EQ(test, true, ret); |
1981 | ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1301000); |
1982 | KUNIT_EXPECT_EQ(test, true, ret); |
1983 | ret = vcap_is_next_lookup(&test_vctrl, 1100000, 8101000); |
1984 | KUNIT_EXPECT_EQ(test, true, ret); |
1985 | ret = vcap_is_next_lookup(&test_vctrl, 1300000, 1401000); |
1986 | KUNIT_EXPECT_EQ(test, true, ret); |
1987 | ret = vcap_is_next_lookup(&test_vctrl, 1400000, 1501000); |
1988 | KUNIT_EXPECT_EQ(test, true, ret); |
1989 | ret = vcap_is_next_lookup(&test_vctrl, 1500000, 8001000); |
1990 | KUNIT_EXPECT_EQ(test, true, ret); |
1991 | |
1992 | ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000); |
1993 | KUNIT_EXPECT_EQ(test, false, ret); |
1994 | ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000); |
1995 | KUNIT_EXPECT_EQ(test, true, ret); |
1996 | |
1997 | ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000); |
1998 | KUNIT_EXPECT_EQ(test, false, ret); |
1999 | ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000); |
2000 | KUNIT_EXPECT_EQ(test, false, ret); |
2001 | } |
2002 | |
2003 | static void vcap_api_filter_unsupported_keys_test(struct kunit *test) |
2004 | { |
2005 | struct vcap_admin admin = { |
2006 | .vtype = VCAP_TYPE_IS2, |
2007 | }; |
2008 | struct vcap_rule_internal ri = { |
2009 | .admin = &admin, |
2010 | .vctrl = &test_vctrl, |
2011 | .data.keyset = VCAP_KFS_MAC_ETYPE, |
2012 | }; |
2013 | enum vcap_key_field keylist[] = { |
2014 | VCAP_KF_TYPE, |
2015 | VCAP_KF_LOOKUP_FIRST_IS, |
2016 | VCAP_KF_ARP_ADDR_SPACE_OK_IS, /* arp keys are not in keyset */ |
2017 | VCAP_KF_ARP_PROTO_SPACE_OK_IS, |
2018 | VCAP_KF_ARP_LEN_OK_IS, |
2019 | VCAP_KF_ARP_TGT_MATCH_IS, |
2020 | VCAP_KF_ARP_SENDER_MATCH_IS, |
2021 | VCAP_KF_ARP_OPCODE_UNKNOWN_IS, |
2022 | VCAP_KF_ARP_OPCODE, |
2023 | VCAP_KF_8021Q_DEI_CLS, |
2024 | VCAP_KF_8021Q_PCP_CLS, |
2025 | VCAP_KF_8021Q_VID_CLS, |
2026 | VCAP_KF_L2_MC_IS, |
2027 | VCAP_KF_L2_BC_IS, |
2028 | }; |
2029 | enum vcap_key_field expected[] = { |
2030 | VCAP_KF_TYPE, |
2031 | VCAP_KF_LOOKUP_FIRST_IS, |
2032 | VCAP_KF_8021Q_DEI_CLS, |
2033 | VCAP_KF_8021Q_PCP_CLS, |
2034 | VCAP_KF_8021Q_VID_CLS, |
2035 | VCAP_KF_L2_MC_IS, |
2036 | VCAP_KF_L2_BC_IS, |
2037 | }; |
2038 | struct vcap_client_keyfield *ckf, *next; |
2039 | bool ret; |
2040 | int idx; |
2041 | |
2042 | /* Add all keys to the rule */ |
2043 | INIT_LIST_HEAD(list: &ri.data.keyfields); |
2044 | for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { |
2045 | ckf = kzalloc(size: sizeof(*ckf), GFP_KERNEL); |
2046 | if (ckf) { |
2047 | ckf->ctrl.key = keylist[idx]; |
2048 | list_add_tail(new: &ckf->ctrl.list, head: &ri.data.keyfields); |
2049 | } |
2050 | } |
2051 | |
2052 | KUNIT_EXPECT_EQ(test, 14, ARRAY_SIZE(keylist)); |
2053 | |
2054 | /* Drop unsupported keys from the rule */ |
2055 | ret = vcap_filter_rule_keys(&ri.data, NULL, 0, true); |
2056 | |
2057 | KUNIT_EXPECT_EQ(test, 0, ret); |
2058 | |
2059 | /* Check remaining keys in the rule */ |
2060 | idx = 0; |
2061 | list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { |
2062 | KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); |
2063 | list_del(entry: &ckf->ctrl.list); |
2064 | kfree(objp: ckf); |
2065 | ++idx; |
2066 | } |
2067 | KUNIT_EXPECT_EQ(test, 7, idx); |
2068 | } |
2069 | |
2070 | static void vcap_api_filter_keylist_test(struct kunit *test) |
2071 | { |
2072 | struct vcap_admin admin = { |
2073 | .vtype = VCAP_TYPE_IS0, |
2074 | }; |
2075 | struct vcap_rule_internal ri = { |
2076 | .admin = &admin, |
2077 | .vctrl = &test_vctrl, |
2078 | .data.keyset = VCAP_KFS_NORMAL_7TUPLE, |
2079 | }; |
2080 | enum vcap_key_field keylist[] = { |
2081 | VCAP_KF_TYPE, |
2082 | VCAP_KF_LOOKUP_FIRST_IS, |
2083 | VCAP_KF_LOOKUP_GEN_IDX_SEL, |
2084 | VCAP_KF_LOOKUP_GEN_IDX, |
2085 | VCAP_KF_IF_IGR_PORT_MASK_SEL, |
2086 | VCAP_KF_IF_IGR_PORT_MASK, |
2087 | VCAP_KF_L2_MC_IS, |
2088 | VCAP_KF_L2_BC_IS, |
2089 | VCAP_KF_8021Q_VLAN_TAGS, |
2090 | VCAP_KF_8021Q_TPID0, |
2091 | VCAP_KF_8021Q_PCP0, |
2092 | VCAP_KF_8021Q_DEI0, |
2093 | VCAP_KF_8021Q_VID0, |
2094 | VCAP_KF_8021Q_TPID1, |
2095 | VCAP_KF_8021Q_PCP1, |
2096 | VCAP_KF_8021Q_DEI1, |
2097 | VCAP_KF_8021Q_VID1, |
2098 | VCAP_KF_8021Q_TPID2, |
2099 | VCAP_KF_8021Q_PCP2, |
2100 | VCAP_KF_8021Q_DEI2, |
2101 | VCAP_KF_8021Q_VID2, |
2102 | VCAP_KF_L2_DMAC, |
2103 | VCAP_KF_L2_SMAC, |
2104 | VCAP_KF_IP_MC_IS, |
2105 | VCAP_KF_ETYPE_LEN_IS, |
2106 | VCAP_KF_ETYPE, |
2107 | VCAP_KF_IP_SNAP_IS, |
2108 | VCAP_KF_IP4_IS, |
2109 | VCAP_KF_L3_FRAGMENT_TYPE, |
2110 | VCAP_KF_L3_FRAG_INVLD_L4_LEN, |
2111 | VCAP_KF_L3_OPTIONS_IS, |
2112 | VCAP_KF_L3_DSCP, |
2113 | VCAP_KF_L3_IP6_DIP, |
2114 | VCAP_KF_L3_IP6_SIP, |
2115 | VCAP_KF_TCP_UDP_IS, |
2116 | VCAP_KF_TCP_IS, |
2117 | VCAP_KF_L4_SPORT, |
2118 | VCAP_KF_L4_RNG, |
2119 | }; |
2120 | enum vcap_key_field droplist[] = { |
2121 | VCAP_KF_8021Q_TPID1, |
2122 | VCAP_KF_8021Q_PCP1, |
2123 | VCAP_KF_8021Q_DEI1, |
2124 | VCAP_KF_8021Q_VID1, |
2125 | VCAP_KF_8021Q_TPID2, |
2126 | VCAP_KF_8021Q_PCP2, |
2127 | VCAP_KF_8021Q_DEI2, |
2128 | VCAP_KF_8021Q_VID2, |
2129 | VCAP_KF_L3_IP6_DIP, |
2130 | VCAP_KF_L3_IP6_SIP, |
2131 | VCAP_KF_L4_SPORT, |
2132 | VCAP_KF_L4_RNG, |
2133 | }; |
2134 | enum vcap_key_field expected[] = { |
2135 | VCAP_KF_TYPE, |
2136 | VCAP_KF_LOOKUP_FIRST_IS, |
2137 | VCAP_KF_LOOKUP_GEN_IDX_SEL, |
2138 | VCAP_KF_LOOKUP_GEN_IDX, |
2139 | VCAP_KF_IF_IGR_PORT_MASK_SEL, |
2140 | VCAP_KF_IF_IGR_PORT_MASK, |
2141 | VCAP_KF_L2_MC_IS, |
2142 | VCAP_KF_L2_BC_IS, |
2143 | VCAP_KF_8021Q_VLAN_TAGS, |
2144 | VCAP_KF_8021Q_TPID0, |
2145 | VCAP_KF_8021Q_PCP0, |
2146 | VCAP_KF_8021Q_DEI0, |
2147 | VCAP_KF_8021Q_VID0, |
2148 | VCAP_KF_L2_DMAC, |
2149 | VCAP_KF_L2_SMAC, |
2150 | VCAP_KF_IP_MC_IS, |
2151 | VCAP_KF_ETYPE_LEN_IS, |
2152 | VCAP_KF_ETYPE, |
2153 | VCAP_KF_IP_SNAP_IS, |
2154 | VCAP_KF_IP4_IS, |
2155 | VCAP_KF_L3_FRAGMENT_TYPE, |
2156 | VCAP_KF_L3_FRAG_INVLD_L4_LEN, |
2157 | VCAP_KF_L3_OPTIONS_IS, |
2158 | VCAP_KF_L3_DSCP, |
2159 | VCAP_KF_TCP_UDP_IS, |
2160 | VCAP_KF_TCP_IS, |
2161 | }; |
2162 | struct vcap_client_keyfield *ckf, *next; |
2163 | bool ret; |
2164 | int idx; |
2165 | |
2166 | /* Add all keys to the rule */ |
2167 | INIT_LIST_HEAD(list: &ri.data.keyfields); |
2168 | for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { |
2169 | ckf = kzalloc(size: sizeof(*ckf), GFP_KERNEL); |
2170 | if (ckf) { |
2171 | ckf->ctrl.key = keylist[idx]; |
2172 | list_add_tail(new: &ckf->ctrl.list, head: &ri.data.keyfields); |
2173 | } |
2174 | } |
2175 | |
2176 | KUNIT_EXPECT_EQ(test, 38, ARRAY_SIZE(keylist)); |
2177 | |
2178 | /* Drop listed keys from the rule */ |
2179 | ret = vcap_filter_rule_keys(&ri.data, droplist, ARRAY_SIZE(droplist), |
2180 | false); |
2181 | |
2182 | KUNIT_EXPECT_EQ(test, 0, ret); |
2183 | |
2184 | /* Check remaining keys in the rule */ |
2185 | idx = 0; |
2186 | list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { |
2187 | KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); |
2188 | list_del(entry: &ckf->ctrl.list); |
2189 | kfree(objp: ckf); |
2190 | ++idx; |
2191 | } |
2192 | KUNIT_EXPECT_EQ(test, 26, idx); |
2193 | } |
2194 | |
2195 | static void vcap_api_rule_chain_path_test(struct kunit *test) |
2196 | { |
2197 | struct vcap_admin admin1 = { |
2198 | .vtype = VCAP_TYPE_IS0, |
2199 | .vinst = 0, |
2200 | .first_cid = 1000000, |
2201 | .last_cid = 1199999, |
2202 | .lookups = 6, |
2203 | .lookups_per_instance = 2, |
2204 | }; |
2205 | struct vcap_enabled_port eport3 = { |
2206 | .ndev = &test_netdev, |
2207 | .cookie = 0x100, |
2208 | .src_cid = 0, |
2209 | .dst_cid = 1000000, |
2210 | }; |
2211 | struct vcap_enabled_port eport2 = { |
2212 | .ndev = &test_netdev, |
2213 | .cookie = 0x200, |
2214 | .src_cid = 1000000, |
2215 | .dst_cid = 1100000, |
2216 | }; |
2217 | struct vcap_enabled_port eport1 = { |
2218 | .ndev = &test_netdev, |
2219 | .cookie = 0x300, |
2220 | .src_cid = 1100000, |
2221 | .dst_cid = 8000000, |
2222 | }; |
2223 | bool ret; |
2224 | int chain; |
2225 | |
2226 | vcap_test_api_init(admin: &admin1); |
2227 | list_add_tail(new: &eport1.list, head: &admin1.enabled); |
2228 | list_add_tail(new: &eport2.list, head: &admin1.enabled); |
2229 | list_add_tail(new: &eport3.list, head: &admin1.enabled); |
2230 | |
2231 | ret = vcap_path_exist(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 1000000); |
2232 | KUNIT_EXPECT_EQ(test, true, ret); |
2233 | |
2234 | ret = vcap_path_exist(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 1100000); |
2235 | KUNIT_EXPECT_EQ(test, true, ret); |
2236 | |
2237 | ret = vcap_path_exist(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 1200000); |
2238 | KUNIT_EXPECT_EQ(test, false, ret); |
2239 | |
2240 | chain = vcap_get_next_chain(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 0); |
2241 | KUNIT_EXPECT_EQ(test, 1000000, chain); |
2242 | |
2243 | chain = vcap_get_next_chain(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 1000000); |
2244 | KUNIT_EXPECT_EQ(test, 1100000, chain); |
2245 | |
2246 | chain = vcap_get_next_chain(vctrl: &test_vctrl, ndev: &test_netdev, dst_cid: 1100000); |
2247 | KUNIT_EXPECT_EQ(test, 8000000, chain); |
2248 | } |
2249 | |
2250 | static struct kunit_case vcap_api_rule_enable_test_cases[] = { |
2251 | KUNIT_CASE(vcap_api_rule_chain_path_test), |
2252 | {} |
2253 | }; |
2254 | |
2255 | static struct kunit_suite vcap_api_rule_enable_test_suite = { |
2256 | .name = "VCAP_API_Rule_Enable_Testsuite" , |
2257 | .test_cases = vcap_api_rule_enable_test_cases, |
2258 | }; |
2259 | |
2260 | static struct kunit_suite vcap_api_rule_remove_test_suite = { |
2261 | .name = "VCAP_API_Rule_Remove_Testsuite" , |
2262 | .test_cases = vcap_api_rule_remove_test_cases, |
2263 | }; |
2264 | |
2265 | static struct kunit_case vcap_api_rule_insert_test_cases[] = { |
2266 | KUNIT_CASE(vcap_api_rule_insert_in_order_test), |
2267 | KUNIT_CASE(vcap_api_rule_insert_reverse_order_test), |
2268 | {} |
2269 | }; |
2270 | |
2271 | static struct kunit_suite vcap_api_rule_insert_test_suite = { |
2272 | .name = "VCAP_API_Rule_Insert_Testsuite" , |
2273 | .test_cases = vcap_api_rule_insert_test_cases, |
2274 | }; |
2275 | |
2276 | static struct kunit_case vcap_api_rule_counter_test_cases[] = { |
2277 | KUNIT_CASE(vcap_api_set_rule_counter_test), |
2278 | KUNIT_CASE(vcap_api_get_rule_counter_test), |
2279 | {} |
2280 | }; |
2281 | |
2282 | static struct kunit_suite vcap_api_rule_counter_test_suite = { |
2283 | .name = "VCAP_API_Rule_Counter_Testsuite" , |
2284 | .test_cases = vcap_api_rule_counter_test_cases, |
2285 | }; |
2286 | |
2287 | static struct kunit_case vcap_api_support_test_cases[] = { |
2288 | KUNIT_CASE(vcap_api_next_lookup_basic_test), |
2289 | KUNIT_CASE(vcap_api_next_lookup_advanced_test), |
2290 | KUNIT_CASE(vcap_api_filter_unsupported_keys_test), |
2291 | KUNIT_CASE(vcap_api_filter_keylist_test), |
2292 | {} |
2293 | }; |
2294 | |
2295 | static struct kunit_suite vcap_api_support_test_suite = { |
2296 | .name = "VCAP_API_Support_Testsuite" , |
2297 | .test_cases = vcap_api_support_test_cases, |
2298 | }; |
2299 | |
2300 | static struct kunit_case vcap_api_full_rule_test_cases[] = { |
2301 | KUNIT_CASE(vcap_api_rule_find_keyset_basic_test), |
2302 | KUNIT_CASE(vcap_api_rule_find_keyset_failed_test), |
2303 | KUNIT_CASE(vcap_api_rule_find_keyset_many_test), |
2304 | KUNIT_CASE(vcap_api_encode_rule_test), |
2305 | {} |
2306 | }; |
2307 | |
2308 | static struct kunit_suite vcap_api_full_rule_test_suite = { |
2309 | .name = "VCAP_API_Full_Rule_Testsuite" , |
2310 | .test_cases = vcap_api_full_rule_test_cases, |
2311 | }; |
2312 | |
2313 | static struct kunit_case vcap_api_rule_value_test_cases[] = { |
2314 | KUNIT_CASE(vcap_api_rule_add_keyvalue_test), |
2315 | KUNIT_CASE(vcap_api_rule_add_actionvalue_test), |
2316 | {} |
2317 | }; |
2318 | |
2319 | static struct kunit_suite vcap_api_rule_value_test_suite = { |
2320 | .name = "VCAP_API_Rule_Value_Testsuite" , |
2321 | .test_cases = vcap_api_rule_value_test_cases, |
2322 | }; |
2323 | |
2324 | static struct kunit_case vcap_api_encoding_test_cases[] = { |
2325 | KUNIT_CASE(vcap_api_set_bit_1_test), |
2326 | KUNIT_CASE(vcap_api_set_bit_0_test), |
2327 | KUNIT_CASE(vcap_api_iterator_init_test), |
2328 | KUNIT_CASE(vcap_api_iterator_next_test), |
2329 | KUNIT_CASE(vcap_api_encode_typegroups_test), |
2330 | KUNIT_CASE(vcap_api_encode_bit_test), |
2331 | KUNIT_CASE(vcap_api_encode_field_test), |
2332 | KUNIT_CASE(vcap_api_encode_short_field_test), |
2333 | KUNIT_CASE(vcap_api_encode_keyfield_test), |
2334 | KUNIT_CASE(vcap_api_encode_max_keyfield_test), |
2335 | KUNIT_CASE(vcap_api_encode_actionfield_test), |
2336 | KUNIT_CASE(vcap_api_keyfield_typegroup_test), |
2337 | KUNIT_CASE(vcap_api_actionfield_typegroup_test), |
2338 | KUNIT_CASE(vcap_api_vcap_keyfields_test), |
2339 | KUNIT_CASE(vcap_api_vcap_actionfields_test), |
2340 | KUNIT_CASE(vcap_api_encode_rule_keyset_test), |
2341 | KUNIT_CASE(vcap_api_encode_rule_actionset_test), |
2342 | {} |
2343 | }; |
2344 | |
2345 | static struct kunit_suite vcap_api_encoding_test_suite = { |
2346 | .name = "VCAP_API_Encoding_Testsuite" , |
2347 | .test_cases = vcap_api_encoding_test_cases, |
2348 | }; |
2349 | |
2350 | kunit_test_suite(vcap_api_rule_enable_test_suite); |
2351 | kunit_test_suite(vcap_api_rule_remove_test_suite); |
2352 | kunit_test_suite(vcap_api_rule_insert_test_suite); |
2353 | kunit_test_suite(vcap_api_rule_counter_test_suite); |
2354 | kunit_test_suite(vcap_api_support_test_suite); |
2355 | kunit_test_suite(vcap_api_full_rule_test_suite); |
2356 | kunit_test_suite(vcap_api_rule_value_test_suite); |
2357 | kunit_test_suite(vcap_api_encoding_test_suite); |
2358 | |