2350 lines · c
1// SPDX-License-Identifier: BSD-3-Clause2/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.3 * Microchip VCAP API kunit test suite4 */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 platform12 * implementation13 */14#define TEST_BUF_CNT 10015#define TEST_BUF_SZ 35016#define STREAMWSIZE 6417 18static u32 test_updateaddr[STREAMWSIZE] = {};19static int test_updateaddridx;20static int test_cache_erase_count;21static u32 test_init_start;22static u32 test_init_count;23static u32 test_hw_counter_id;24static struct vcap_cache_data test_hw_cache;25static struct net_device test_netdev = {};26static int test_move_addr;27static int test_move_offset;28static int test_move_count;29 30/* Callback used by the VCAP API */31static 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 */73static 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 else80 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0);81}82 83/* Callback used by the VCAP API */84static 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 */95static 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 */103static 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 */145static 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 */187static 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 else194 pr_err("%s:%d: overflow: %d\n", __func__, __LINE__, test_updateaddridx);195 test_updateaddridx++;196}197 198static 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 */207static 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 214static const 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 226static struct vcap_control test_vctrl = {227 .vcaps = kunit_test_vcaps,228 .stats = &kunit_test_vcap_stats,229 .ops = &test_callbacks,230};231 232static 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 */246static 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 */317static 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 328static 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, &iter, 1);340 341 KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]);342 KUNIT_EXPECT_EQ(test, (u32)BIT(20), stream[1]);343}344 345static 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, &iter, 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 363static 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(&iter, 52, typegroups, 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(&iter, 49, typegroups2, 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 392static 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(&iter, 49, typegroups, 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(&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(&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 426static 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, 49, typegroups, 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 455static 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(&iter, 49, typegroups, 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, &iter, 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 481static 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(&iter, 49, typegroups, 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, &iter, 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, 49, typegroups, 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 */532static 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(&iter, sw_width, tgt, 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, &iter, 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, tgt, 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 577static 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);615 vcap_encode_keyfield(&rule, &ckf, &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 636static 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(&rule, &ckf, &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 703static 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(&rule, &caf, &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 750static void vcap_api_keyfield_typegroup_test(struct kunit *test)751{752 const struct vcap_typegroup *tg;753 754 tg = vcap_keyfield_typegroup(&test_vctrl, VCAP_TYPE_IS2, 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(&test_vctrl, VCAP_TYPE_ES2, VCAP_KFS_LL_FULL);767 KUNIT_EXPECT_PTR_EQ(test, NULL, tg);768}769 770static void vcap_api_actionfield_typegroup_test(struct kunit *test)771{772 const struct vcap_typegroup *tg;773 774 tg = vcap_actionfield_typegroup(&test_vctrl, VCAP_TYPE_IS0, 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(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_CLASSIFICATION);790 KUNIT_EXPECT_PTR_EQ(test, NULL, tg);791}792 793static void vcap_api_vcap_keyfields_test(struct kunit *test)794{795 const struct vcap_field *ft;796 797 ft = vcap_keyfields(&test_vctrl, VCAP_TYPE_IS2, 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(&test_vctrl, VCAP_TYPE_ES2, 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(&test_vctrl, VCAP_TYPE_ES2, VCAP_KFS_LL_FULL);806 KUNIT_EXPECT_PTR_EQ(test, NULL, ft);807}808 809static void vcap_api_vcap_actionfields_test(struct kunit *test)810{811 const struct vcap_field *ft;812 813 ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS0, VCAP_AFS_FULL);814 KUNIT_EXPECT_PTR_NE(test, NULL, ft);815 816 ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_FULL);817 KUNIT_EXPECT_PTR_EQ(test, NULL, ft);818 819 ft = vcap_actionfields(&test_vctrl, VCAP_TYPE_IS2, VCAP_AFS_CLASSIFICATION);820 KUNIT_EXPECT_PTR_EQ(test, NULL, ft);821}822 823static 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(&rule.data.keyfields);897 ret = vcap_encode_rule_keyset(&rule);898 KUNIT_EXPECT_EQ(test, -EINVAL, ret);899 900 for (idx = 0; idx < ARRAY_SIZE(ckf); idx++)901 list_add_tail(&ckf[idx].ctrl.list, &rule.data.keyfields);902 ret = vcap_encode_rule_keyset(&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 935static 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(&rule.data.actionfields);973 ret = vcap_encode_rule_actionset(&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(&caf[idx].ctrl.list, &rule.data.actionfields);979 ret = vcap_encode_rule_actionset(&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 997static 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(&ckf->ctrl.list);1003 kfree(ckf);1004 }1005}1006 1007static 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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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 1097static 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(&caf->ctrl.list);1104 kfree(caf);1105 }1106}1107 1108static 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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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 1184static 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(&ri.data.keyfields);1221 for (idx = 0; idx < ARRAY_SIZE(ckf); idx++)1222 list_add_tail(&ckf[idx].ctrl.list, &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 1231static 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(&ri.data.keyfields);1268 for (idx = 0; idx < ARRAY_SIZE(ckf); idx++)1269 list_add_tail(&ckf[idx].ctrl.list, &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 1278static 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(&ri.data.keyfields);1315 for (idx = 0; idx < ARRAY_SIZE(ckf); idx++)1316 list_add_tail(&ckf[idx].ctrl.list, &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 1330static 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(&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(&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 ret = vcap_del_rule(&test_vctrl, &test_netdev, id);1446 KUNIT_EXPECT_EQ(test, 0, ret);1447 1448 vcap_free_rule(rule);1449}1450 1451static void vcap_api_set_rule_counter_test(struct kunit *test)1452{1453 struct vcap_admin is2_admin = {1454 .cache = {1455 .counter = 100,1456 .sticky = true,1457 },1458 };1459 struct vcap_rule_internal ri = {1460 .data = {1461 .id = 1001,1462 },1463 .addr = 600,1464 .admin = &is2_admin,1465 .counter_id = 1002,1466 .vctrl = &test_vctrl,1467 };1468 struct vcap_rule_internal ri2 = {1469 .data = {1470 .id = 2001,1471 },1472 .addr = 700,1473 .admin = &is2_admin,1474 .counter_id = 2002,1475 .vctrl = &test_vctrl,1476 };1477 struct vcap_counter ctr = { .value = 0, .sticky = false};1478 struct vcap_counter ctr2 = { .value = 101, .sticky = true};1479 int ret;1480 1481 vcap_test_api_init(&is2_admin);1482 list_add_tail(&ri.list, &is2_admin.rules);1483 list_add_tail(&ri2.list, &is2_admin.rules);1484 1485 pr_info("%s:%d\n", __func__, __LINE__);1486 ret = vcap_rule_set_counter(&ri.data, &ctr);1487 pr_info("%s:%d\n", __func__, __LINE__);1488 KUNIT_EXPECT_EQ(test, 0, ret);1489 1490 KUNIT_EXPECT_EQ(test, 1002, test_hw_counter_id);1491 KUNIT_EXPECT_EQ(test, 0, test_hw_cache.counter);1492 KUNIT_EXPECT_EQ(test, false, test_hw_cache.sticky);1493 KUNIT_EXPECT_EQ(test, 600, test_updateaddr[0]);1494 1495 ret = vcap_rule_set_counter(&ri2.data, &ctr2);1496 KUNIT_EXPECT_EQ(test, 0, ret);1497 1498 KUNIT_EXPECT_EQ(test, 2002, test_hw_counter_id);1499 KUNIT_EXPECT_EQ(test, 101, test_hw_cache.counter);1500 KUNIT_EXPECT_EQ(test, true, test_hw_cache.sticky);1501 KUNIT_EXPECT_EQ(test, 700, test_updateaddr[1]);1502}1503 1504static void vcap_api_get_rule_counter_test(struct kunit *test)1505{1506 struct vcap_admin is2_admin = {1507 .cache = {1508 .counter = 100,1509 .sticky = true,1510 },1511 };1512 struct vcap_rule_internal ri = {1513 .data = {1514 .id = 1010,1515 },1516 .addr = 400,1517 .admin = &is2_admin,1518 .counter_id = 1011,1519 .vctrl = &test_vctrl,1520 };1521 struct vcap_rule_internal ri2 = {1522 .data = {1523 .id = 2011,1524 },1525 .addr = 300,1526 .admin = &is2_admin,1527 .counter_id = 2012,1528 .vctrl = &test_vctrl,1529 };1530 struct vcap_counter ctr = {};1531 struct vcap_counter ctr2 = {};1532 int ret;1533 1534 vcap_test_api_init(&is2_admin);1535 test_hw_cache.counter = 55;1536 test_hw_cache.sticky = true;1537 1538 list_add_tail(&ri.list, &is2_admin.rules);1539 list_add_tail(&ri2.list, &is2_admin.rules);1540 1541 ret = vcap_rule_get_counter(&ri.data, &ctr);1542 KUNIT_EXPECT_EQ(test, 0, ret);1543 1544 KUNIT_EXPECT_EQ(test, 1011, test_hw_counter_id);1545 KUNIT_EXPECT_EQ(test, 55, ctr.value);1546 KUNIT_EXPECT_EQ(test, true, ctr.sticky);1547 KUNIT_EXPECT_EQ(test, 400, test_updateaddr[0]);1548 1549 test_hw_cache.counter = 22;1550 test_hw_cache.sticky = false;1551 1552 ret = vcap_rule_get_counter(&ri2.data, &ctr2);1553 KUNIT_EXPECT_EQ(test, 0, ret);1554 1555 KUNIT_EXPECT_EQ(test, 2012, test_hw_counter_id);1556 KUNIT_EXPECT_EQ(test, 22, ctr2.value);1557 KUNIT_EXPECT_EQ(test, false, ctr2.sticky);1558 KUNIT_EXPECT_EQ(test, 300, test_updateaddr[1]);1559}1560 1561static void vcap_api_rule_insert_in_order_test(struct kunit *test)1562{1563 /* Data used by VCAP Library callback */1564 static u32 keydata[32] = {};1565 static u32 mskdata[32] = {};1566 static u32 actdata[32] = {};1567 1568 struct vcap_admin admin = {1569 .vtype = VCAP_TYPE_IS0,1570 .first_cid = 10000,1571 .last_cid = 19999,1572 .lookups = 4,1573 .last_valid_addr = 3071,1574 .first_valid_addr = 0,1575 .last_used_addr = 800,1576 .cache = {1577 .keystream = keydata,1578 .maskstream = mskdata,1579 .actionstream = actdata,1580 },1581 };1582 1583 vcap_test_api_init(&admin);1584 1585 /* Create rules with different sizes and check that they are placed1586 * at the correct address in the VCAP according to size1587 */1588 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780);1589 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774);1590 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771);1591 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768);1592 1593 vcap_del_rule(&test_vctrl, &test_netdev, 200);1594 vcap_del_rule(&test_vctrl, &test_netdev, 300);1595 vcap_del_rule(&test_vctrl, &test_netdev, 400);1596 vcap_del_rule(&test_vctrl, &test_netdev, 500);1597}1598 1599static void vcap_api_rule_insert_reverse_order_test(struct kunit *test)1600{1601 /* Data used by VCAP Library callback */1602 static u32 keydata[32] = {};1603 static u32 mskdata[32] = {};1604 static u32 actdata[32] = {};1605 1606 struct vcap_admin admin = {1607 .vtype = VCAP_TYPE_IS0,1608 .first_cid = 10000,1609 .last_cid = 19999,1610 .lookups = 4,1611 .last_valid_addr = 3071,1612 .first_valid_addr = 0,1613 .last_used_addr = 800,1614 .cache = {1615 .keystream = keydata,1616 .maskstream = mskdata,1617 .actionstream = actdata,1618 },1619 };1620 struct vcap_rule_internal *elem;1621 u32 exp_addr[] = {780, 774, 771, 768, 767};1622 int idx;1623 1624 vcap_test_api_init(&admin);1625 1626 /* Create rules with different sizes and check that they are placed1627 * at the correct address in the VCAP according to size1628 */1629 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 200, 2, 798);1630 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1631 KUNIT_EXPECT_EQ(test, 0, test_move_count);1632 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1633 1634 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 795);1635 KUNIT_EXPECT_EQ(test, 6, test_move_offset);1636 KUNIT_EXPECT_EQ(test, 3, test_move_count);1637 KUNIT_EXPECT_EQ(test, 798, test_move_addr);1638 1639 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 400, 6, 792);1640 KUNIT_EXPECT_EQ(test, 6, test_move_offset);1641 KUNIT_EXPECT_EQ(test, 6, test_move_count);1642 KUNIT_EXPECT_EQ(test, 792, test_move_addr);1643 1644 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 50, 500, 12, 780);1645 KUNIT_EXPECT_EQ(test, 18, test_move_offset);1646 KUNIT_EXPECT_EQ(test, 12, test_move_count);1647 KUNIT_EXPECT_EQ(test, 786, test_move_addr);1648 1649 idx = 0;1650 list_for_each_entry(elem, &admin.rules, list) {1651 KUNIT_EXPECT_EQ(test, exp_addr[idx], elem->addr);1652 ++idx;1653 }1654 KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr);1655 1656 vcap_del_rule(&test_vctrl, &test_netdev, 500);1657 vcap_del_rule(&test_vctrl, &test_netdev, 400);1658 vcap_del_rule(&test_vctrl, &test_netdev, 300);1659 vcap_del_rule(&test_vctrl, &test_netdev, 200);1660}1661 1662static void vcap_api_rule_remove_at_end_test(struct kunit *test)1663{1664 /* Data used by VCAP Library callback */1665 static u32 keydata[32] = {};1666 static u32 mskdata[32] = {};1667 static u32 actdata[32] = {};1668 1669 struct vcap_admin admin = {1670 .vtype = VCAP_TYPE_IS0,1671 .first_cid = 10000,1672 .last_cid = 19999,1673 .lookups = 4,1674 .last_valid_addr = 3071,1675 .first_valid_addr = 0,1676 .last_used_addr = 800,1677 .cache = {1678 .keystream = keydata,1679 .maskstream = mskdata,1680 .actionstream = actdata,1681 },1682 };1683 int ret;1684 1685 vcap_test_api_init(&admin);1686 test_init_rule_deletion();1687 1688 /* Create rules with different sizes and check that they are placed1689 * at the correct address in the VCAP according to size1690 */1691 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780);1692 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774);1693 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771);1694 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768);1695 1696 /* Remove rules again from the end */1697 ret = vcap_del_rule(&test_vctrl, &test_netdev, 200);1698 KUNIT_EXPECT_EQ(test, 0, ret);1699 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1700 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1701 KUNIT_EXPECT_EQ(test, 0, test_move_count);1702 KUNIT_EXPECT_EQ(test, 768, test_init_start);1703 KUNIT_EXPECT_EQ(test, 2, test_init_count);1704 KUNIT_EXPECT_EQ(test, 771, admin.last_used_addr);1705 1706 ret = vcap_del_rule(&test_vctrl, &test_netdev, 300);1707 KUNIT_EXPECT_EQ(test, ret, 0);1708 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1709 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1710 KUNIT_EXPECT_EQ(test, 0, test_move_count);1711 KUNIT_EXPECT_EQ(test, 771, test_init_start);1712 KUNIT_EXPECT_EQ(test, 3, test_init_count);1713 KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr);1714 1715 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400);1716 KUNIT_EXPECT_EQ(test, ret, 0);1717 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1718 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1719 KUNIT_EXPECT_EQ(test, 0, test_move_count);1720 KUNIT_EXPECT_EQ(test, 774, test_init_start);1721 KUNIT_EXPECT_EQ(test, 6, test_init_count);1722 KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr);1723 1724 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500);1725 KUNIT_EXPECT_EQ(test, ret, 0);1726 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1727 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1728 KUNIT_EXPECT_EQ(test, 0, test_move_count);1729 KUNIT_EXPECT_EQ(test, 780, test_init_start);1730 KUNIT_EXPECT_EQ(test, 12, test_init_count);1731 KUNIT_EXPECT_EQ(test, 3072, admin.last_used_addr);1732}1733 1734static void vcap_api_rule_remove_in_middle_test(struct kunit *test)1735{1736 /* Data used by VCAP Library callback */1737 static u32 keydata[32] = {};1738 static u32 mskdata[32] = {};1739 static u32 actdata[32] = {};1740 1741 struct vcap_admin admin = {1742 .vtype = VCAP_TYPE_IS0,1743 .first_cid = 10000,1744 .last_cid = 19999,1745 .lookups = 4,1746 .first_valid_addr = 0,1747 .last_used_addr = 800,1748 .last_valid_addr = 800 - 1,1749 .cache = {1750 .keystream = keydata,1751 .maskstream = mskdata,1752 .actionstream = actdata,1753 },1754 };1755 int ret;1756 1757 vcap_test_api_init(&admin);1758 1759 /* Create rules with different sizes and check that they are placed1760 * at the correct address in the VCAP according to size1761 */1762 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780);1763 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774);1764 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771);1765 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768);1766 1767 /* Remove rules in the middle */1768 test_init_rule_deletion();1769 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400);1770 KUNIT_EXPECT_EQ(test, 0, ret);1771 KUNIT_EXPECT_EQ(test, 768, test_move_addr);1772 KUNIT_EXPECT_EQ(test, -6, test_move_offset);1773 KUNIT_EXPECT_EQ(test, 6, test_move_count);1774 KUNIT_EXPECT_EQ(test, 768, test_init_start);1775 KUNIT_EXPECT_EQ(test, 6, test_init_count);1776 KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr);1777 1778 test_init_rule_deletion();1779 ret = vcap_del_rule(&test_vctrl, &test_netdev, 300);1780 KUNIT_EXPECT_EQ(test, 0, ret);1781 KUNIT_EXPECT_EQ(test, 774, test_move_addr);1782 KUNIT_EXPECT_EQ(test, -4, test_move_offset);1783 KUNIT_EXPECT_EQ(test, 2, test_move_count);1784 KUNIT_EXPECT_EQ(test, 774, test_init_start);1785 KUNIT_EXPECT_EQ(test, 4, test_init_count);1786 KUNIT_EXPECT_EQ(test, 778, admin.last_used_addr);1787 1788 test_init_rule_deletion();1789 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500);1790 KUNIT_EXPECT_EQ(test, 0, ret);1791 KUNIT_EXPECT_EQ(test, 778, test_move_addr);1792 KUNIT_EXPECT_EQ(test, -20, test_move_offset);1793 KUNIT_EXPECT_EQ(test, 2, test_move_count);1794 KUNIT_EXPECT_EQ(test, 778, test_init_start);1795 KUNIT_EXPECT_EQ(test, 20, test_init_count);1796 KUNIT_EXPECT_EQ(test, 798, admin.last_used_addr);1797 1798 test_init_rule_deletion();1799 ret = vcap_del_rule(&test_vctrl, &test_netdev, 200);1800 KUNIT_EXPECT_EQ(test, 0, ret);1801 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1802 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1803 KUNIT_EXPECT_EQ(test, 0, test_move_count);1804 KUNIT_EXPECT_EQ(test, 798, test_init_start);1805 KUNIT_EXPECT_EQ(test, 2, test_init_count);1806 KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr);1807}1808 1809static void vcap_api_rule_remove_in_front_test(struct kunit *test)1810{1811 /* Data used by VCAP Library callback */1812 static u32 keydata[32] = {};1813 static u32 mskdata[32] = {};1814 static u32 actdata[32] = {};1815 1816 struct vcap_admin admin = {1817 .vtype = VCAP_TYPE_IS0,1818 .first_cid = 10000,1819 .last_cid = 19999,1820 .lookups = 4,1821 .first_valid_addr = 0,1822 .last_used_addr = 800,1823 .last_valid_addr = 800 - 1,1824 .cache = {1825 .keystream = keydata,1826 .maskstream = mskdata,1827 .actionstream = actdata,1828 },1829 };1830 int ret;1831 1832 vcap_test_api_init(&admin);1833 1834 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780);1835 KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr);1836 1837 test_init_rule_deletion();1838 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500);1839 KUNIT_EXPECT_EQ(test, 0, ret);1840 KUNIT_EXPECT_EQ(test, 0, test_move_addr);1841 KUNIT_EXPECT_EQ(test, 0, test_move_offset);1842 KUNIT_EXPECT_EQ(test, 0, test_move_count);1843 KUNIT_EXPECT_EQ(test, 780, test_init_start);1844 KUNIT_EXPECT_EQ(test, 12, test_init_count);1845 KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr);1846 1847 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 792);1848 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 789);1849 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 786);1850 1851 test_init_rule_deletion();1852 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400);1853 KUNIT_EXPECT_EQ(test, 0, ret);1854 KUNIT_EXPECT_EQ(test, 786, test_move_addr);1855 KUNIT_EXPECT_EQ(test, -8, test_move_offset);1856 KUNIT_EXPECT_EQ(test, 6, test_move_count);1857 KUNIT_EXPECT_EQ(test, 786, test_init_start);1858 KUNIT_EXPECT_EQ(test, 8, test_init_count);1859 KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr);1860 1861 vcap_del_rule(&test_vctrl, &test_netdev, 200);1862 vcap_del_rule(&test_vctrl, &test_netdev, 300);1863}1864 1865static struct kunit_case vcap_api_rule_remove_test_cases[] = {1866 KUNIT_CASE(vcap_api_rule_remove_at_end_test),1867 KUNIT_CASE(vcap_api_rule_remove_in_middle_test),1868 KUNIT_CASE(vcap_api_rule_remove_in_front_test),1869 {}1870};1871 1872static void vcap_api_next_lookup_basic_test(struct kunit *test)1873{1874 struct vcap_admin admin1 = {1875 .vtype = VCAP_TYPE_IS2,1876 .vinst = 0,1877 .first_cid = 8000000,1878 .last_cid = 8199999,1879 .lookups = 4,1880 .lookups_per_instance = 2,1881 };1882 struct vcap_admin admin2 = {1883 .vtype = VCAP_TYPE_IS2,1884 .vinst = 1,1885 .first_cid = 8200000,1886 .last_cid = 8399999,1887 .lookups = 4,1888 .lookups_per_instance = 2,1889 };1890 bool ret;1891 1892 vcap_test_api_init(&admin1);1893 list_add_tail(&admin2.list, &test_vctrl.list);1894 1895 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 1001000);1896 KUNIT_EXPECT_EQ(test, false, ret);1897 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000);1898 KUNIT_EXPECT_EQ(test, false, ret);1899 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000);1900 KUNIT_EXPECT_EQ(test, true, ret);1901 1902 ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8101000);1903 KUNIT_EXPECT_EQ(test, false, ret);1904 ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8201000);1905 KUNIT_EXPECT_EQ(test, true, ret);1906 1907 ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8201000);1908 KUNIT_EXPECT_EQ(test, false, ret);1909 ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8301000);1910 KUNIT_EXPECT_EQ(test, true, ret);1911 1912 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000);1913 KUNIT_EXPECT_EQ(test, false, ret);1914 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000);1915 KUNIT_EXPECT_EQ(test, false, ret);1916}1917 1918static void vcap_api_next_lookup_advanced_test(struct kunit *test)1919{1920 struct vcap_admin admin[] = {1921 {1922 .vtype = VCAP_TYPE_IS0,1923 .vinst = 0,1924 .first_cid = 1000000,1925 .last_cid = 1199999,1926 .lookups = 6,1927 .lookups_per_instance = 2,1928 }, {1929 .vtype = VCAP_TYPE_IS0,1930 .vinst = 1,1931 .first_cid = 1200000,1932 .last_cid = 1399999,1933 .lookups = 6,1934 .lookups_per_instance = 2,1935 }, {1936 .vtype = VCAP_TYPE_IS0,1937 .vinst = 2,1938 .first_cid = 1400000,1939 .last_cid = 1599999,1940 .lookups = 6,1941 .lookups_per_instance = 2,1942 }, {1943 .vtype = VCAP_TYPE_IS2,1944 .vinst = 0,1945 .first_cid = 8000000,1946 .last_cid = 8199999,1947 .lookups = 4,1948 .lookups_per_instance = 2,1949 }, {1950 .vtype = VCAP_TYPE_IS2,1951 .vinst = 1,1952 .first_cid = 8200000,1953 .last_cid = 8399999,1954 .lookups = 4,1955 .lookups_per_instance = 2,1956 }1957 };1958 bool ret;1959 1960 vcap_test_api_init(&admin[0]);1961 list_add_tail(&admin[1].list, &test_vctrl.list);1962 list_add_tail(&admin[2].list, &test_vctrl.list);1963 list_add_tail(&admin[3].list, &test_vctrl.list);1964 list_add_tail(&admin[4].list, &test_vctrl.list);1965 1966 ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1001000);1967 KUNIT_EXPECT_EQ(test, false, ret);1968 ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1101000);1969 KUNIT_EXPECT_EQ(test, true, ret);1970 1971 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1201000);1972 KUNIT_EXPECT_EQ(test, true, ret);1973 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1301000);1974 KUNIT_EXPECT_EQ(test, true, ret);1975 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 8101000);1976 KUNIT_EXPECT_EQ(test, true, ret);1977 ret = vcap_is_next_lookup(&test_vctrl, 1300000, 1401000);1978 KUNIT_EXPECT_EQ(test, true, ret);1979 ret = vcap_is_next_lookup(&test_vctrl, 1400000, 1501000);1980 KUNIT_EXPECT_EQ(test, true, ret);1981 ret = vcap_is_next_lookup(&test_vctrl, 1500000, 8001000);1982 KUNIT_EXPECT_EQ(test, true, ret);1983 1984 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000);1985 KUNIT_EXPECT_EQ(test, false, ret);1986 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000);1987 KUNIT_EXPECT_EQ(test, true, ret);1988 1989 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000);1990 KUNIT_EXPECT_EQ(test, false, ret);1991 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000);1992 KUNIT_EXPECT_EQ(test, false, ret);1993}1994 1995static void vcap_api_filter_unsupported_keys_test(struct kunit *test)1996{1997 struct vcap_admin admin = {1998 .vtype = VCAP_TYPE_IS2,1999 };2000 struct vcap_rule_internal ri = {2001 .admin = &admin,2002 .vctrl = &test_vctrl,2003 .data.keyset = VCAP_KFS_MAC_ETYPE,2004 };2005 enum vcap_key_field keylist[] = {2006 VCAP_KF_TYPE,2007 VCAP_KF_LOOKUP_FIRST_IS,2008 VCAP_KF_ARP_ADDR_SPACE_OK_IS, /* arp keys are not in keyset */2009 VCAP_KF_ARP_PROTO_SPACE_OK_IS,2010 VCAP_KF_ARP_LEN_OK_IS,2011 VCAP_KF_ARP_TGT_MATCH_IS,2012 VCAP_KF_ARP_SENDER_MATCH_IS,2013 VCAP_KF_ARP_OPCODE_UNKNOWN_IS,2014 VCAP_KF_ARP_OPCODE,2015 VCAP_KF_8021Q_DEI_CLS,2016 VCAP_KF_8021Q_PCP_CLS,2017 VCAP_KF_8021Q_VID_CLS,2018 VCAP_KF_L2_MC_IS,2019 VCAP_KF_L2_BC_IS,2020 };2021 enum vcap_key_field expected[] = {2022 VCAP_KF_TYPE,2023 VCAP_KF_LOOKUP_FIRST_IS,2024 VCAP_KF_8021Q_DEI_CLS,2025 VCAP_KF_8021Q_PCP_CLS,2026 VCAP_KF_8021Q_VID_CLS,2027 VCAP_KF_L2_MC_IS,2028 VCAP_KF_L2_BC_IS,2029 };2030 struct vcap_client_keyfield *ckf, *next;2031 bool ret;2032 int idx;2033 2034 /* Add all keys to the rule */2035 INIT_LIST_HEAD(&ri.data.keyfields);2036 for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) {2037 ckf = kzalloc(sizeof(*ckf), GFP_KERNEL);2038 if (ckf) {2039 ckf->ctrl.key = keylist[idx];2040 list_add_tail(&ckf->ctrl.list, &ri.data.keyfields);2041 }2042 }2043 2044 KUNIT_EXPECT_EQ(test, 14, ARRAY_SIZE(keylist));2045 2046 /* Drop unsupported keys from the rule */2047 ret = vcap_filter_rule_keys(&ri.data, NULL, 0, true);2048 2049 KUNIT_EXPECT_EQ(test, 0, ret);2050 2051 /* Check remaining keys in the rule */2052 idx = 0;2053 list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) {2054 KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key);2055 list_del(&ckf->ctrl.list);2056 kfree(ckf);2057 ++idx;2058 }2059 KUNIT_EXPECT_EQ(test, 7, idx);2060}2061 2062static void vcap_api_filter_keylist_test(struct kunit *test)2063{2064 struct vcap_admin admin = {2065 .vtype = VCAP_TYPE_IS0,2066 };2067 struct vcap_rule_internal ri = {2068 .admin = &admin,2069 .vctrl = &test_vctrl,2070 .data.keyset = VCAP_KFS_NORMAL_7TUPLE,2071 };2072 enum vcap_key_field keylist[] = {2073 VCAP_KF_TYPE,2074 VCAP_KF_LOOKUP_FIRST_IS,2075 VCAP_KF_LOOKUP_GEN_IDX_SEL,2076 VCAP_KF_LOOKUP_GEN_IDX,2077 VCAP_KF_IF_IGR_PORT_MASK_SEL,2078 VCAP_KF_IF_IGR_PORT_MASK,2079 VCAP_KF_L2_MC_IS,2080 VCAP_KF_L2_BC_IS,2081 VCAP_KF_8021Q_VLAN_TAGS,2082 VCAP_KF_8021Q_TPID0,2083 VCAP_KF_8021Q_PCP0,2084 VCAP_KF_8021Q_DEI0,2085 VCAP_KF_8021Q_VID0,2086 VCAP_KF_8021Q_TPID1,2087 VCAP_KF_8021Q_PCP1,2088 VCAP_KF_8021Q_DEI1,2089 VCAP_KF_8021Q_VID1,2090 VCAP_KF_8021Q_TPID2,2091 VCAP_KF_8021Q_PCP2,2092 VCAP_KF_8021Q_DEI2,2093 VCAP_KF_8021Q_VID2,2094 VCAP_KF_L2_DMAC,2095 VCAP_KF_L2_SMAC,2096 VCAP_KF_IP_MC_IS,2097 VCAP_KF_ETYPE_LEN_IS,2098 VCAP_KF_ETYPE,2099 VCAP_KF_IP_SNAP_IS,2100 VCAP_KF_IP4_IS,2101 VCAP_KF_L3_FRAGMENT_TYPE,2102 VCAP_KF_L3_FRAG_INVLD_L4_LEN,2103 VCAP_KF_L3_OPTIONS_IS,2104 VCAP_KF_L3_DSCP,2105 VCAP_KF_L3_IP6_DIP,2106 VCAP_KF_L3_IP6_SIP,2107 VCAP_KF_TCP_UDP_IS,2108 VCAP_KF_TCP_IS,2109 VCAP_KF_L4_SPORT,2110 VCAP_KF_L4_RNG,2111 };2112 enum vcap_key_field droplist[] = {2113 VCAP_KF_8021Q_TPID1,2114 VCAP_KF_8021Q_PCP1,2115 VCAP_KF_8021Q_DEI1,2116 VCAP_KF_8021Q_VID1,2117 VCAP_KF_8021Q_TPID2,2118 VCAP_KF_8021Q_PCP2,2119 VCAP_KF_8021Q_DEI2,2120 VCAP_KF_8021Q_VID2,2121 VCAP_KF_L3_IP6_DIP,2122 VCAP_KF_L3_IP6_SIP,2123 VCAP_KF_L4_SPORT,2124 VCAP_KF_L4_RNG,2125 };2126 enum vcap_key_field expected[] = {2127 VCAP_KF_TYPE,2128 VCAP_KF_LOOKUP_FIRST_IS,2129 VCAP_KF_LOOKUP_GEN_IDX_SEL,2130 VCAP_KF_LOOKUP_GEN_IDX,2131 VCAP_KF_IF_IGR_PORT_MASK_SEL,2132 VCAP_KF_IF_IGR_PORT_MASK,2133 VCAP_KF_L2_MC_IS,2134 VCAP_KF_L2_BC_IS,2135 VCAP_KF_8021Q_VLAN_TAGS,2136 VCAP_KF_8021Q_TPID0,2137 VCAP_KF_8021Q_PCP0,2138 VCAP_KF_8021Q_DEI0,2139 VCAP_KF_8021Q_VID0,2140 VCAP_KF_L2_DMAC,2141 VCAP_KF_L2_SMAC,2142 VCAP_KF_IP_MC_IS,2143 VCAP_KF_ETYPE_LEN_IS,2144 VCAP_KF_ETYPE,2145 VCAP_KF_IP_SNAP_IS,2146 VCAP_KF_IP4_IS,2147 VCAP_KF_L3_FRAGMENT_TYPE,2148 VCAP_KF_L3_FRAG_INVLD_L4_LEN,2149 VCAP_KF_L3_OPTIONS_IS,2150 VCAP_KF_L3_DSCP,2151 VCAP_KF_TCP_UDP_IS,2152 VCAP_KF_TCP_IS,2153 };2154 struct vcap_client_keyfield *ckf, *next;2155 bool ret;2156 int idx;2157 2158 /* Add all keys to the rule */2159 INIT_LIST_HEAD(&ri.data.keyfields);2160 for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) {2161 ckf = kzalloc(sizeof(*ckf), GFP_KERNEL);2162 if (ckf) {2163 ckf->ctrl.key = keylist[idx];2164 list_add_tail(&ckf->ctrl.list, &ri.data.keyfields);2165 }2166 }2167 2168 KUNIT_EXPECT_EQ(test, 38, ARRAY_SIZE(keylist));2169 2170 /* Drop listed keys from the rule */2171 ret = vcap_filter_rule_keys(&ri.data, droplist, ARRAY_SIZE(droplist),2172 false);2173 2174 KUNIT_EXPECT_EQ(test, 0, ret);2175 2176 /* Check remaining keys in the rule */2177 idx = 0;2178 list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) {2179 KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key);2180 list_del(&ckf->ctrl.list);2181 kfree(ckf);2182 ++idx;2183 }2184 KUNIT_EXPECT_EQ(test, 26, idx);2185}2186 2187static void vcap_api_rule_chain_path_test(struct kunit *test)2188{2189 struct vcap_admin admin1 = {2190 .vtype = VCAP_TYPE_IS0,2191 .vinst = 0,2192 .first_cid = 1000000,2193 .last_cid = 1199999,2194 .lookups = 6,2195 .lookups_per_instance = 2,2196 };2197 struct vcap_enabled_port eport3 = {2198 .ndev = &test_netdev,2199 .cookie = 0x100,2200 .src_cid = 0,2201 .dst_cid = 1000000,2202 };2203 struct vcap_enabled_port eport2 = {2204 .ndev = &test_netdev,2205 .cookie = 0x200,2206 .src_cid = 1000000,2207 .dst_cid = 1100000,2208 };2209 struct vcap_enabled_port eport1 = {2210 .ndev = &test_netdev,2211 .cookie = 0x300,2212 .src_cid = 1100000,2213 .dst_cid = 8000000,2214 };2215 bool ret;2216 int chain;2217 2218 vcap_test_api_init(&admin1);2219 list_add_tail(&eport1.list, &admin1.enabled);2220 list_add_tail(&eport2.list, &admin1.enabled);2221 list_add_tail(&eport3.list, &admin1.enabled);2222 2223 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1000000);2224 KUNIT_EXPECT_EQ(test, true, ret);2225 2226 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1100000);2227 KUNIT_EXPECT_EQ(test, true, ret);2228 2229 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1200000);2230 KUNIT_EXPECT_EQ(test, false, ret);2231 2232 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 0);2233 KUNIT_EXPECT_EQ(test, 1000000, chain);2234 2235 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 1000000);2236 KUNIT_EXPECT_EQ(test, 1100000, chain);2237 2238 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 1100000);2239 KUNIT_EXPECT_EQ(test, 8000000, chain);2240}2241 2242static struct kunit_case vcap_api_rule_enable_test_cases[] = {2243 KUNIT_CASE(vcap_api_rule_chain_path_test),2244 {}2245};2246 2247static struct kunit_suite vcap_api_rule_enable_test_suite = {2248 .name = "VCAP_API_Rule_Enable_Testsuite",2249 .test_cases = vcap_api_rule_enable_test_cases,2250};2251 2252static struct kunit_suite vcap_api_rule_remove_test_suite = {2253 .name = "VCAP_API_Rule_Remove_Testsuite",2254 .test_cases = vcap_api_rule_remove_test_cases,2255};2256 2257static struct kunit_case vcap_api_rule_insert_test_cases[] = {2258 KUNIT_CASE(vcap_api_rule_insert_in_order_test),2259 KUNIT_CASE(vcap_api_rule_insert_reverse_order_test),2260 {}2261};2262 2263static struct kunit_suite vcap_api_rule_insert_test_suite = {2264 .name = "VCAP_API_Rule_Insert_Testsuite",2265 .test_cases = vcap_api_rule_insert_test_cases,2266};2267 2268static struct kunit_case vcap_api_rule_counter_test_cases[] = {2269 KUNIT_CASE(vcap_api_set_rule_counter_test),2270 KUNIT_CASE(vcap_api_get_rule_counter_test),2271 {}2272};2273 2274static struct kunit_suite vcap_api_rule_counter_test_suite = {2275 .name = "VCAP_API_Rule_Counter_Testsuite",2276 .test_cases = vcap_api_rule_counter_test_cases,2277};2278 2279static struct kunit_case vcap_api_support_test_cases[] = {2280 KUNIT_CASE(vcap_api_next_lookup_basic_test),2281 KUNIT_CASE(vcap_api_next_lookup_advanced_test),2282 KUNIT_CASE(vcap_api_filter_unsupported_keys_test),2283 KUNIT_CASE(vcap_api_filter_keylist_test),2284 {}2285};2286 2287static struct kunit_suite vcap_api_support_test_suite = {2288 .name = "VCAP_API_Support_Testsuite",2289 .test_cases = vcap_api_support_test_cases,2290};2291 2292static struct kunit_case vcap_api_full_rule_test_cases[] = {2293 KUNIT_CASE(vcap_api_rule_find_keyset_basic_test),2294 KUNIT_CASE(vcap_api_rule_find_keyset_failed_test),2295 KUNIT_CASE(vcap_api_rule_find_keyset_many_test),2296 KUNIT_CASE(vcap_api_encode_rule_test),2297 {}2298};2299 2300static struct kunit_suite vcap_api_full_rule_test_suite = {2301 .name = "VCAP_API_Full_Rule_Testsuite",2302 .test_cases = vcap_api_full_rule_test_cases,2303};2304 2305static struct kunit_case vcap_api_rule_value_test_cases[] = {2306 KUNIT_CASE(vcap_api_rule_add_keyvalue_test),2307 KUNIT_CASE(vcap_api_rule_add_actionvalue_test),2308 {}2309};2310 2311static struct kunit_suite vcap_api_rule_value_test_suite = {2312 .name = "VCAP_API_Rule_Value_Testsuite",2313 .test_cases = vcap_api_rule_value_test_cases,2314};2315 2316static struct kunit_case vcap_api_encoding_test_cases[] = {2317 KUNIT_CASE(vcap_api_set_bit_1_test),2318 KUNIT_CASE(vcap_api_set_bit_0_test),2319 KUNIT_CASE(vcap_api_iterator_init_test),2320 KUNIT_CASE(vcap_api_iterator_next_test),2321 KUNIT_CASE(vcap_api_encode_typegroups_test),2322 KUNIT_CASE(vcap_api_encode_bit_test),2323 KUNIT_CASE(vcap_api_encode_field_test),2324 KUNIT_CASE(vcap_api_encode_short_field_test),2325 KUNIT_CASE(vcap_api_encode_keyfield_test),2326 KUNIT_CASE(vcap_api_encode_max_keyfield_test),2327 KUNIT_CASE(vcap_api_encode_actionfield_test),2328 KUNIT_CASE(vcap_api_keyfield_typegroup_test),2329 KUNIT_CASE(vcap_api_actionfield_typegroup_test),2330 KUNIT_CASE(vcap_api_vcap_keyfields_test),2331 KUNIT_CASE(vcap_api_vcap_actionfields_test),2332 KUNIT_CASE(vcap_api_encode_rule_keyset_test),2333 KUNIT_CASE(vcap_api_encode_rule_actionset_test),2334 {}2335};2336 2337static struct kunit_suite vcap_api_encoding_test_suite = {2338 .name = "VCAP_API_Encoding_Testsuite",2339 .test_cases = vcap_api_encoding_test_cases,2340};2341 2342kunit_test_suite(vcap_api_rule_enable_test_suite);2343kunit_test_suite(vcap_api_rule_remove_test_suite);2344kunit_test_suite(vcap_api_rule_insert_test_suite);2345kunit_test_suite(vcap_api_rule_counter_test_suite);2346kunit_test_suite(vcap_api_support_test_suite);2347kunit_test_suite(vcap_api_full_rule_test_suite);2348kunit_test_suite(vcap_api_rule_value_test_suite);2349kunit_test_suite(vcap_api_encoding_test_suite);2350