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