1 // SPDX-License-Identifier: BSD-3-Clause 2 /* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries. 3 * Microchip VCAP API kunit test suite 4 */ 5 6 #include <kunit/test.h> 7 #include "vcap_api.h" 8 #include "vcap_api_client.h" 9 #include "vcap_model_kunit.h" 10 11 /* First we have the test infrastructure that emulates the platform 12 * implementation 13 */ 14 #define TEST_BUF_CNT 100 15 #define TEST_BUF_SZ 350 16 #define STREAMWSIZE 64 17 18 static u32 test_updateaddr[STREAMWSIZE] = {}; 19 static int test_updateaddridx; 20 static int test_cache_erase_count; 21 static u32 test_init_start; 22 static u32 test_init_count; 23 static u32 test_hw_counter_id; 24 static struct vcap_cache_data test_hw_cache; 25 static struct net_device test_netdev = {}; 26 static int test_move_addr; 27 static int test_move_offset; 28 static int test_move_count; 29 30 /* Callback used by the VCAP API */ 31 static enum vcap_keyfield_set test_val_keyset(struct net_device *ndev, 32 struct vcap_admin *admin, 33 struct vcap_rule *rule, 34 struct vcap_keyset_list *kslist, 35 u16 l3_proto) 36 { 37 int idx; 38 39 if (kslist->cnt > 0) { 40 switch (admin->vtype) { 41 case VCAP_TYPE_IS0: 42 for (idx = 0; idx < kslist->cnt; idx++) { 43 if (kslist->keysets[idx] == VCAP_KFS_ETAG) 44 return kslist->keysets[idx]; 45 if (kslist->keysets[idx] == VCAP_KFS_PURE_5TUPLE_IP4) 46 return kslist->keysets[idx]; 47 if (kslist->keysets[idx] == VCAP_KFS_NORMAL_5TUPLE_IP4) 48 return kslist->keysets[idx]; 49 if (kslist->keysets[idx] == VCAP_KFS_NORMAL_7TUPLE) 50 return kslist->keysets[idx]; 51 } 52 break; 53 case VCAP_TYPE_IS2: 54 for (idx = 0; idx < kslist->cnt; idx++) { 55 if (kslist->keysets[idx] == VCAP_KFS_MAC_ETYPE) 56 return kslist->keysets[idx]; 57 if (kslist->keysets[idx] == VCAP_KFS_ARP) 58 return kslist->keysets[idx]; 59 if (kslist->keysets[idx] == VCAP_KFS_IP_7TUPLE) 60 return kslist->keysets[idx]; 61 } 62 break; 63 default: 64 pr_info("%s:%d: no validation for VCAP %d\n", 65 __func__, __LINE__, admin->vtype); 66 break; 67 } 68 } 69 return -EINVAL; 70 } 71 72 /* Callback used by the VCAP API */ 73 static void test_add_def_fields(struct net_device *ndev, 74 struct vcap_admin *admin, 75 struct vcap_rule *rule) 76 { 77 if (admin->vinst == 0 || admin->vinst == 2) 78 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); 79 else 80 vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0); 81 } 82 83 /* Callback used by the VCAP API */ 84 static void test_cache_erase(struct vcap_admin *admin) 85 { 86 if (test_cache_erase_count) { 87 memset(admin->cache.keystream, 0, test_cache_erase_count); 88 memset(admin->cache.maskstream, 0, test_cache_erase_count); 89 memset(admin->cache.actionstream, 0, test_cache_erase_count); 90 test_cache_erase_count = 0; 91 } 92 } 93 94 /* Callback used by the VCAP API */ 95 static void test_cache_init(struct net_device *ndev, struct vcap_admin *admin, 96 u32 start, u32 count) 97 { 98 test_init_start = start; 99 test_init_count = count; 100 } 101 102 /* Callback used by the VCAP API */ 103 static void test_cache_read(struct net_device *ndev, struct vcap_admin *admin, 104 enum vcap_selection sel, u32 start, u32 count) 105 { 106 u32 *keystr, *mskstr, *actstr; 107 int idx; 108 109 pr_debug("%s:%d: %d %d\n", __func__, __LINE__, start, count); 110 switch (sel) { 111 case VCAP_SEL_ENTRY: 112 keystr = &admin->cache.keystream[start]; 113 mskstr = &admin->cache.maskstream[start]; 114 for (idx = 0; idx < count; ++idx) { 115 pr_debug("%s:%d: keydata[%02d]: 0x%08x\n", __func__, 116 __LINE__, start + idx, keystr[idx]); 117 } 118 for (idx = 0; idx < count; ++idx) { 119 /* Invert the mask before decoding starts */ 120 mskstr[idx] = ~mskstr[idx]; 121 pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n", __func__, 122 __LINE__, start + idx, mskstr[idx]); 123 } 124 break; 125 case VCAP_SEL_ACTION: 126 actstr = &admin->cache.actionstream[start]; 127 for (idx = 0; idx < count; ++idx) { 128 pr_debug("%s:%d: actdata[%02d]: 0x%08x\n", __func__, 129 __LINE__, start + idx, actstr[idx]); 130 } 131 break; 132 case VCAP_SEL_COUNTER: 133 pr_debug("%s:%d\n", __func__, __LINE__); 134 test_hw_counter_id = start; 135 admin->cache.counter = test_hw_cache.counter; 136 admin->cache.sticky = test_hw_cache.sticky; 137 break; 138 case VCAP_SEL_ALL: 139 pr_debug("%s:%d\n", __func__, __LINE__); 140 break; 141 } 142 } 143 144 /* Callback used by the VCAP API */ 145 static void test_cache_write(struct net_device *ndev, struct vcap_admin *admin, 146 enum vcap_selection sel, u32 start, u32 count) 147 { 148 u32 *keystr, *mskstr, *actstr; 149 int idx; 150 151 switch (sel) { 152 case VCAP_SEL_ENTRY: 153 keystr = &admin->cache.keystream[start]; 154 mskstr = &admin->cache.maskstream[start]; 155 for (idx = 0; idx < count; ++idx) { 156 pr_debug("%s:%d: keydata[%02d]: 0x%08x\n", __func__, 157 __LINE__, start + idx, keystr[idx]); 158 } 159 for (idx = 0; idx < count; ++idx) { 160 /* Invert the mask before encoding starts */ 161 mskstr[idx] = ~mskstr[idx]; 162 pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n", __func__, 163 __LINE__, start + idx, mskstr[idx]); 164 } 165 break; 166 case VCAP_SEL_ACTION: 167 actstr = &admin->cache.actionstream[start]; 168 for (idx = 0; idx < count; ++idx) { 169 pr_debug("%s:%d: actdata[%02d]: 0x%08x\n", __func__, 170 __LINE__, start + idx, actstr[idx]); 171 } 172 break; 173 case VCAP_SEL_COUNTER: 174 pr_debug("%s:%d\n", __func__, __LINE__); 175 test_hw_counter_id = start; 176 test_hw_cache.counter = admin->cache.counter; 177 test_hw_cache.sticky = admin->cache.sticky; 178 break; 179 case VCAP_SEL_ALL: 180 pr_err("%s:%d: cannot write all streams at once\n", 181 __func__, __LINE__); 182 break; 183 } 184 } 185 186 /* Callback used by the VCAP API */ 187 static void test_cache_update(struct net_device *ndev, struct vcap_admin *admin, 188 enum vcap_command cmd, 189 enum vcap_selection sel, u32 addr) 190 { 191 if (test_updateaddridx < ARRAY_SIZE(test_updateaddr)) 192 test_updateaddr[test_updateaddridx] = addr; 193 else 194 pr_err("%s:%d: overflow: %d\n", __func__, __LINE__, test_updateaddridx); 195 test_updateaddridx++; 196 } 197 198 static void test_cache_move(struct net_device *ndev, struct vcap_admin *admin, 199 u32 addr, int offset, int count) 200 { 201 test_move_addr = addr; 202 test_move_offset = offset; 203 test_move_count = count; 204 } 205 206 /* Provide port information via a callback interface */ 207 static int vcap_test_port_info(struct net_device *ndev, 208 struct vcap_admin *admin, 209 struct vcap_output_print *out) 210 { 211 return 0; 212 } 213 214 static struct vcap_operations test_callbacks = { 215 .validate_keyset = test_val_keyset, 216 .add_default_fields = test_add_def_fields, 217 .cache_erase = test_cache_erase, 218 .cache_write = test_cache_write, 219 .cache_read = test_cache_read, 220 .init = test_cache_init, 221 .update = test_cache_update, 222 .move = test_cache_move, 223 .port_info = vcap_test_port_info, 224 }; 225 226 static struct vcap_control test_vctrl = { 227 .vcaps = kunit_test_vcaps, 228 .stats = &kunit_test_vcap_stats, 229 .ops = &test_callbacks, 230 }; 231 232 static void vcap_test_api_init(struct vcap_admin *admin) 233 { 234 /* Initialize the shared objects */ 235 INIT_LIST_HEAD(&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 void test_vcap_xn_rule_creator(struct kunit *test, int cid, 247 enum vcap_user user, u16 priority, 248 int id, int size, int expected_addr) 249 { 250 struct vcap_rule *rule; 251 struct vcap_rule_internal *ri; 252 enum vcap_keyfield_set keyset = VCAP_KFS_NO_VALUE; 253 enum vcap_actionfield_set actionset = VCAP_AFS_NO_VALUE; 254 int ret; 255 256 /* init before testing */ 257 memset(test_updateaddr, 0, sizeof(test_updateaddr)); 258 test_updateaddridx = 0; 259 test_move_addr = 0; 260 test_move_offset = 0; 261 test_move_count = 0; 262 263 switch (size) { 264 case 2: 265 keyset = VCAP_KFS_ETAG; 266 actionset = VCAP_AFS_CLASS_REDUCED; 267 break; 268 case 3: 269 keyset = VCAP_KFS_PURE_5TUPLE_IP4; 270 actionset = VCAP_AFS_CLASSIFICATION; 271 break; 272 case 6: 273 keyset = VCAP_KFS_NORMAL_5TUPLE_IP4; 274 actionset = VCAP_AFS_CLASSIFICATION; 275 break; 276 case 12: 277 keyset = VCAP_KFS_NORMAL_7TUPLE; 278 actionset = VCAP_AFS_FULL; 279 break; 280 default: 281 break; 282 } 283 284 /* Check that a valid size was used */ 285 KUNIT_ASSERT_NE(test, VCAP_KFS_NO_VALUE, keyset); 286 287 /* Allocate the rule */ 288 rule = vcap_alloc_rule(&test_vctrl, &test_netdev, cid, user, priority, 289 id); 290 KUNIT_EXPECT_PTR_NE(test, NULL, rule); 291 292 ri = (struct vcap_rule_internal *)rule; 293 294 /* Override rule keyset */ 295 ret = vcap_set_rule_set_keyset(rule, keyset); 296 297 /* Add rule actions : there must be at least one action */ 298 ret = vcap_rule_add_action_u32(rule, VCAP_AF_ISDX_VAL, 0); 299 300 /* Override rule actionset */ 301 ret = vcap_set_rule_set_actionset(rule, actionset); 302 303 ret = vcap_val_rule(rule, ETH_P_ALL); 304 KUNIT_EXPECT_EQ(test, 0, ret); 305 KUNIT_EXPECT_EQ(test, keyset, rule->keyset); 306 KUNIT_EXPECT_EQ(test, actionset, rule->actionset); 307 KUNIT_EXPECT_EQ(test, size, ri->size); 308 309 /* Add rule with write callback */ 310 ret = vcap_add_rule(rule); 311 KUNIT_EXPECT_EQ(test, 0, ret); 312 KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); 313 vcap_free_rule(rule); 314 } 315 316 /* Prepare testing rule deletion */ 317 static void test_init_rule_deletion(void) 318 { 319 test_move_addr = 0; 320 test_move_offset = 0; 321 test_move_count = 0; 322 test_init_start = 0; 323 test_init_count = 0; 324 } 325 326 /* Define the test cases. */ 327 328 static void vcap_api_set_bit_1_test(struct kunit *test) 329 { 330 struct vcap_stream_iter iter = { 331 .offset = 35, 332 .sw_width = 52, 333 .reg_idx = 1, 334 .reg_bitpos = 20, 335 .tg = NULL, 336 }; 337 u32 stream[2] = {0}; 338 339 vcap_set_bit(stream, &iter, 1); 340 341 KUNIT_EXPECT_EQ(test, (u32)0x0, stream[0]); 342 KUNIT_EXPECT_EQ(test, (u32)BIT(20), stream[1]); 343 } 344 345 static void vcap_api_set_bit_0_test(struct kunit *test) 346 { 347 struct vcap_stream_iter iter = { 348 .offset = 35, 349 .sw_width = 52, 350 .reg_idx = 2, 351 .reg_bitpos = 11, 352 .tg = NULL, 353 }; 354 u32 stream[3] = {~0, ~0, ~0}; 355 356 vcap_set_bit(stream, &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 363 static void vcap_api_iterator_init_test(struct kunit *test) 364 { 365 struct vcap_stream_iter iter; 366 struct vcap_typegroup typegroups[] = { 367 { .offset = 0, .width = 2, .value = 2, }, 368 { .offset = 156, .width = 1, .value = 0, }, 369 { .offset = 0, .width = 0, .value = 0, }, 370 }; 371 struct vcap_typegroup typegroups2[] = { 372 { .offset = 0, .width = 3, .value = 4, }, 373 { .offset = 49, .width = 2, .value = 0, }, 374 { .offset = 98, .width = 2, .value = 0, }, 375 }; 376 377 vcap_iter_init(&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 392 static void vcap_api_iterator_next_test(struct kunit *test) 393 { 394 struct vcap_stream_iter iter; 395 struct vcap_typegroup typegroups[] = { 396 { .offset = 0, .width = 4, .value = 8, }, 397 { .offset = 49, .width = 1, .value = 0, }, 398 { .offset = 98, .width = 2, .value = 0, }, 399 { .offset = 147, .width = 3, .value = 0, }, 400 { .offset = 196, .width = 2, .value = 0, }, 401 { .offset = 245, .width = 1, .value = 0, }, 402 }; 403 int idx; 404 405 vcap_iter_init(&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 426 static void vcap_api_encode_typegroups_test(struct kunit *test) 427 { 428 u32 stream[12] = {0}; 429 struct vcap_typegroup typegroups[] = { 430 { .offset = 0, .width = 4, .value = 8, }, 431 { .offset = 49, .width = 1, .value = 1, }, 432 { .offset = 98, .width = 2, .value = 3, }, 433 { .offset = 147, .width = 3, .value = 5, }, 434 { .offset = 196, .width = 2, .value = 2, }, 435 { .offset = 245, .width = 5, .value = 27, }, 436 { .offset = 0, .width = 0, .value = 0, }, 437 }; 438 439 vcap_encode_typegroups(stream, 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 455 static void vcap_api_encode_bit_test(struct kunit *test) 456 { 457 struct vcap_stream_iter iter; 458 u32 stream[4] = {0}; 459 struct vcap_typegroup typegroups[] = { 460 { .offset = 0, .width = 4, .value = 8, }, 461 { .offset = 49, .width = 1, .value = 1, }, 462 { .offset = 98, .width = 2, .value = 3, }, 463 { .offset = 147, .width = 3, .value = 5, }, 464 { .offset = 196, .width = 2, .value = 2, }, 465 { .offset = 245, .width = 1, .value = 0, }, 466 }; 467 468 vcap_iter_init(&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 481 static void vcap_api_encode_field_test(struct kunit *test) 482 { 483 struct vcap_stream_iter iter; 484 u32 stream[16] = {0}; 485 struct vcap_typegroup typegroups[] = { 486 { .offset = 0, .width = 4, .value = 8, }, 487 { .offset = 49, .width = 1, .value = 1, }, 488 { .offset = 98, .width = 2, .value = 3, }, 489 { .offset = 147, .width = 3, .value = 5, }, 490 { .offset = 196, .width = 2, .value = 2, }, 491 { .offset = 245, .width = 5, .value = 27, }, 492 { .offset = 0, .width = 0, .value = 0, }, 493 }; 494 struct vcap_field rf = { 495 .type = VCAP_FIELD_U32, 496 .offset = 86, 497 .width = 4, 498 }; 499 u8 value[] = {0x5}; 500 501 vcap_iter_init(&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 */ 532 static void vcap_api_encode_short_field_test(struct kunit *test) 533 { 534 struct vcap_stream_iter iter; 535 int sw_width = 21; 536 u32 stream[6] = {0}; 537 struct vcap_typegroup tgt[] = { 538 { .offset = 0, .width = 3, .value = 7, }, 539 { .offset = 21, .width = 2, .value = 3, }, 540 { .offset = 42, .width = 1, .value = 1, }, 541 { .offset = 0, .width = 0, .value = 0, }, 542 }; 543 struct vcap_field rf = { 544 .type = VCAP_FIELD_U32, 545 .offset = 25, 546 .width = 4, 547 }; 548 u8 value[] = {0x5}; 549 550 vcap_iter_init(&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 577 static void vcap_api_encode_keyfield_test(struct kunit *test) 578 { 579 u32 keywords[16] = {0}; 580 u32 maskwords[16] = {0}; 581 struct vcap_admin admin = { 582 .vtype = VCAP_TYPE_IS2, 583 .cache = { 584 .keystream = keywords, 585 .maskstream = maskwords, 586 .actionstream = keywords, 587 }, 588 }; 589 struct vcap_rule_internal rule = { 590 .admin = &admin, 591 .data = { 592 .keyset = VCAP_KFS_MAC_ETYPE, 593 }, 594 .vctrl = &test_vctrl, 595 }; 596 struct vcap_client_keyfield ckf = { 597 .ctrl.list = {}, 598 .ctrl.key = VCAP_KF_ISDX_CLS, 599 .ctrl.type = VCAP_FIELD_U32, 600 .data.u32.value = 0xeef014a1, 601 .data.u32.mask = 0xfff, 602 }; 603 struct vcap_field rf = { 604 .type = VCAP_FIELD_U32, 605 .offset = 56, 606 .width = 12, 607 }; 608 struct vcap_typegroup tgt[] = { 609 { .offset = 0, .width = 2, .value = 2, }, 610 { .offset = 156, .width = 1, .value = 1, }, 611 { .offset = 0, .width = 0, .value = 0, }, 612 }; 613 614 vcap_test_api_init(&admin); 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 636 static void vcap_api_encode_max_keyfield_test(struct kunit *test) 637 { 638 int idx; 639 u32 keywords[6] = {0}; 640 u32 maskwords[6] = {0}; 641 struct vcap_admin admin = { 642 .vtype = VCAP_TYPE_IS2, 643 /* IS2 sw_width = 52 bit */ 644 .cache = { 645 .keystream = keywords, 646 .maskstream = maskwords, 647 .actionstream = keywords, 648 }, 649 }; 650 struct vcap_rule_internal rule = { 651 .admin = &admin, 652 .data = { 653 .keyset = VCAP_KFS_IP_7TUPLE, 654 }, 655 .vctrl = &test_vctrl, 656 }; 657 struct vcap_client_keyfield ckf = { 658 .ctrl.list = {}, 659 .ctrl.key = VCAP_KF_L3_IP6_DIP, 660 .ctrl.type = VCAP_FIELD_U128, 661 .data.u128.value = { 0xa1, 0xa2, 0xa3, 0xa4, 0, 0, 0x43, 0, 662 0, 0, 0, 0, 0, 0, 0x78, 0x8e, }, 663 .data.u128.mask = { 0xff, 0xff, 0xff, 0xff, 0, 0, 0xff, 0, 664 0, 0, 0, 0, 0, 0, 0xff, 0xff }, 665 }; 666 struct vcap_field rf = { 667 .type = VCAP_FIELD_U128, 668 .offset = 0, 669 .width = 128, 670 }; 671 struct vcap_typegroup tgt[] = { 672 { .offset = 0, .width = 2, .value = 2, }, 673 { .offset = 156, .width = 1, .value = 1, }, 674 { .offset = 0, .width = 0, .value = 0, }, 675 }; 676 u32 keyres[] = { 677 0x928e8a84, 678 0x000c0002, 679 0x00000010, 680 0x00000000, 681 0x0239e000, 682 0x00000000, 683 }; 684 u32 mskres[] = { 685 0xfffffffc, 686 0x000c0003, 687 0x0000003f, 688 0x00000000, 689 0x03fffc00, 690 0x00000000, 691 }; 692 693 vcap_encode_keyfield(&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 703 static void vcap_api_encode_actionfield_test(struct kunit *test) 704 { 705 u32 actwords[16] = {0}; 706 int sw_width = 21; 707 struct vcap_admin admin = { 708 .vtype = VCAP_TYPE_ES2, /* act_width = 21 */ 709 .cache = { 710 .actionstream = actwords, 711 }, 712 }; 713 struct vcap_rule_internal rule = { 714 .admin = &admin, 715 .data = { 716 .actionset = VCAP_AFS_BASE_TYPE, 717 }, 718 .vctrl = &test_vctrl, 719 }; 720 struct vcap_client_actionfield caf = { 721 .ctrl.list = {}, 722 .ctrl.action = VCAP_AF_POLICE_IDX, 723 .ctrl.type = VCAP_FIELD_U32, 724 .data.u32.value = 0x67908032, 725 }; 726 struct vcap_field rf = { 727 .type = VCAP_FIELD_U32, 728 .offset = 35, 729 .width = 6, 730 }; 731 struct vcap_typegroup tgt[] = { 732 { .offset = 0, .width = 2, .value = 2, }, 733 { .offset = 21, .width = 1, .value = 1, }, 734 { .offset = 42, .width = 1, .value = 0, }, 735 { .offset = 0, .width = 0, .value = 0, }, 736 }; 737 738 vcap_encode_actionfield(&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 750 static 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 770 static 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 793 static 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 809 static 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 823 static void vcap_api_encode_rule_keyset_test(struct kunit *test) 824 { 825 u32 keywords[16] = {0}; 826 u32 maskwords[16] = {0}; 827 struct vcap_admin admin = { 828 .vtype = VCAP_TYPE_IS2, 829 .cache = { 830 .keystream = keywords, 831 .maskstream = maskwords, 832 }, 833 }; 834 struct vcap_rule_internal rule = { 835 .admin = &admin, 836 .data = { 837 .keyset = VCAP_KFS_MAC_ETYPE, 838 }, 839 .vctrl = &test_vctrl, 840 }; 841 struct vcap_client_keyfield ckf[] = { 842 { 843 .ctrl.key = VCAP_KF_TYPE, 844 .ctrl.type = VCAP_FIELD_U32, 845 .data.u32.value = 0x00, 846 .data.u32.mask = 0x0f, 847 }, 848 { 849 .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, 850 .ctrl.type = VCAP_FIELD_BIT, 851 .data.u1.value = 0x01, 852 .data.u1.mask = 0x01, 853 }, 854 { 855 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_L3, 856 .ctrl.type = VCAP_FIELD_BIT, 857 .data.u1.value = 0x00, 858 .data.u1.mask = 0x01, 859 }, 860 { 861 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_RNG, 862 .ctrl.type = VCAP_FIELD_U32, 863 .data.u32.value = 0x00, 864 .data.u32.mask = 0x0f, 865 }, 866 { 867 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK, 868 .ctrl.type = VCAP_FIELD_U72, 869 .data.u72.value = {0x0, 0x00, 0x00, 0x00}, 870 .data.u72.mask = {0xfd, 0xff, 0xff, 0xff}, 871 }, 872 { 873 .ctrl.key = VCAP_KF_L2_DMAC, 874 .ctrl.type = VCAP_FIELD_U48, 875 /* Opposite endianness */ 876 .data.u48.value = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, 877 .data.u48.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 878 }, 879 { 880 .ctrl.key = VCAP_KF_ETYPE_LEN_IS, 881 .ctrl.type = VCAP_FIELD_BIT, 882 .data.u1.value = 0x01, 883 .data.u1.mask = 0x01, 884 }, 885 { 886 .ctrl.key = VCAP_KF_ETYPE, 887 .ctrl.type = VCAP_FIELD_U32, 888 .data.u32.value = 0xaabb, 889 .data.u32.mask = 0xffff, 890 }, 891 }; 892 int idx; 893 int ret; 894 895 /* Empty entry list */ 896 INIT_LIST_HEAD(&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 935 static void vcap_api_encode_rule_actionset_test(struct kunit *test) 936 { 937 u32 actwords[16] = {0}; 938 struct vcap_admin admin = { 939 .vtype = VCAP_TYPE_IS2, 940 .cache = { 941 .actionstream = actwords, 942 }, 943 }; 944 struct vcap_rule_internal rule = { 945 .admin = &admin, 946 .data = { 947 .actionset = VCAP_AFS_BASE_TYPE, 948 }, 949 .vctrl = &test_vctrl, 950 }; 951 struct vcap_client_actionfield caf[] = { 952 { 953 .ctrl.action = VCAP_AF_MATCH_ID, 954 .ctrl.type = VCAP_FIELD_U32, 955 .data.u32.value = 0x01, 956 }, 957 { 958 .ctrl.action = VCAP_AF_MATCH_ID_MASK, 959 .ctrl.type = VCAP_FIELD_U32, 960 .data.u32.value = 0x01, 961 }, 962 { 963 .ctrl.action = VCAP_AF_CNT_ID, 964 .ctrl.type = VCAP_FIELD_U32, 965 .data.u32.value = 0x64, 966 }, 967 }; 968 int idx; 969 int ret; 970 971 /* Empty entry list */ 972 INIT_LIST_HEAD(&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 997 static void vcap_free_ckf(struct vcap_rule *rule) 998 { 999 struct vcap_client_keyfield *ckf, *next_ckf; 1000 1001 list_for_each_entry_safe(ckf, next_ckf, &rule->keyfields, ctrl.list) { 1002 list_del(&ckf->ctrl.list); 1003 kfree(ckf); 1004 } 1005 } 1006 1007 static void vcap_api_rule_add_keyvalue_test(struct kunit *test) 1008 { 1009 struct vcap_admin admin = { 1010 .vtype = VCAP_TYPE_IS2, 1011 }; 1012 struct vcap_rule_internal ri = { 1013 .admin = &admin, 1014 .data = { 1015 .keyset = VCAP_KFS_NO_VALUE, 1016 }, 1017 .vctrl = &test_vctrl, 1018 }; 1019 struct vcap_rule *rule = (struct vcap_rule *)&ri; 1020 struct vcap_client_keyfield *kf; 1021 int ret; 1022 struct vcap_u128_key dip = { 1023 .value = {0x17, 0x26, 0x35, 0x44, 0x63, 0x62, 0x71}, 1024 .mask = {0xf1, 0xf2, 0xf3, 0xf4, 0x4f, 0x3f, 0x2f, 0x1f}, 1025 }; 1026 int idx; 1027 1028 INIT_LIST_HEAD(&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 1097 static void vcap_free_caf(struct vcap_rule *rule) 1098 { 1099 struct vcap_client_actionfield *caf, *next_caf; 1100 1101 list_for_each_entry_safe(caf, next_caf, 1102 &rule->actionfields, ctrl.list) { 1103 list_del(&caf->ctrl.list); 1104 kfree(caf); 1105 } 1106 } 1107 1108 static void vcap_api_rule_add_actionvalue_test(struct kunit *test) 1109 { 1110 struct vcap_admin admin = { 1111 .vtype = VCAP_TYPE_IS2, 1112 }; 1113 struct vcap_rule_internal ri = { 1114 .admin = &admin, 1115 .data = { 1116 .actionset = VCAP_AFS_NO_VALUE, 1117 }, 1118 }; 1119 struct vcap_rule *rule = (struct vcap_rule *)&ri; 1120 struct vcap_client_actionfield *af; 1121 int ret; 1122 1123 INIT_LIST_HEAD(&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 1184 static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) 1185 { 1186 struct vcap_keyset_list matches = {}; 1187 struct vcap_admin admin = { 1188 .vtype = VCAP_TYPE_IS2, 1189 }; 1190 struct vcap_rule_internal ri = { 1191 .admin = &admin, 1192 .vctrl = &test_vctrl, 1193 }; 1194 struct vcap_client_keyfield ckf[] = { 1195 { 1196 .ctrl.key = VCAP_KF_TYPE, 1197 }, { 1198 .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, 1199 }, { 1200 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_L3, 1201 }, { 1202 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK_RNG, 1203 }, { 1204 .ctrl.key = VCAP_KF_IF_IGR_PORT_MASK, 1205 }, { 1206 .ctrl.key = VCAP_KF_L2_DMAC, 1207 }, { 1208 .ctrl.key = VCAP_KF_ETYPE_LEN_IS, 1209 }, { 1210 .ctrl.key = VCAP_KF_ETYPE, 1211 }, 1212 }; 1213 int idx; 1214 bool ret; 1215 enum vcap_keyfield_set keysets[10] = {}; 1216 1217 matches.keysets = keysets; 1218 matches.max = ARRAY_SIZE(keysets); 1219 1220 INIT_LIST_HEAD(&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 1231 static void vcap_api_rule_find_keyset_failed_test(struct kunit *test) 1232 { 1233 struct vcap_keyset_list matches = {}; 1234 struct vcap_admin admin = { 1235 .vtype = VCAP_TYPE_IS2, 1236 }; 1237 struct vcap_rule_internal ri = { 1238 .admin = &admin, 1239 .vctrl = &test_vctrl, 1240 }; 1241 struct vcap_client_keyfield ckf[] = { 1242 { 1243 .ctrl.key = VCAP_KF_TYPE, 1244 }, { 1245 .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, 1246 }, { 1247 .ctrl.key = VCAP_KF_ARP_OPCODE, 1248 }, { 1249 .ctrl.key = VCAP_KF_L3_IP4_SIP, 1250 }, { 1251 .ctrl.key = VCAP_KF_L3_IP4_DIP, 1252 }, { 1253 .ctrl.key = VCAP_KF_8021Q_PCP_CLS, 1254 }, { 1255 .ctrl.key = VCAP_KF_ETYPE_LEN_IS, /* Not with ARP */ 1256 }, { 1257 .ctrl.key = VCAP_KF_ETYPE, /* Not with ARP */ 1258 }, 1259 }; 1260 int idx; 1261 bool ret; 1262 enum vcap_keyfield_set keysets[10] = {}; 1263 1264 matches.keysets = keysets; 1265 matches.max = ARRAY_SIZE(keysets); 1266 1267 INIT_LIST_HEAD(&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 1278 static void vcap_api_rule_find_keyset_many_test(struct kunit *test) 1279 { 1280 struct vcap_keyset_list matches = {}; 1281 struct vcap_admin admin = { 1282 .vtype = VCAP_TYPE_IS2, 1283 }; 1284 struct vcap_rule_internal ri = { 1285 .admin = &admin, 1286 .vctrl = &test_vctrl, 1287 }; 1288 struct vcap_client_keyfield ckf[] = { 1289 { 1290 .ctrl.key = VCAP_KF_TYPE, 1291 }, { 1292 .ctrl.key = VCAP_KF_LOOKUP_FIRST_IS, 1293 }, { 1294 .ctrl.key = VCAP_KF_8021Q_DEI_CLS, 1295 }, { 1296 .ctrl.key = VCAP_KF_8021Q_PCP_CLS, 1297 }, { 1298 .ctrl.key = VCAP_KF_8021Q_VID_CLS, 1299 }, { 1300 .ctrl.key = VCAP_KF_ISDX_CLS, 1301 }, { 1302 .ctrl.key = VCAP_KF_L2_MC_IS, 1303 }, { 1304 .ctrl.key = VCAP_KF_L2_BC_IS, 1305 }, 1306 }; 1307 int idx; 1308 bool ret; 1309 enum vcap_keyfield_set keysets[10] = {}; 1310 1311 matches.keysets = keysets; 1312 matches.max = ARRAY_SIZE(keysets); 1313 1314 INIT_LIST_HEAD(&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 1330 static void vcap_api_encode_rule_test(struct kunit *test) 1331 { 1332 /* Data used by VCAP Library callback */ 1333 static u32 keydata[32] = {}; 1334 static u32 mskdata[32] = {}; 1335 static u32 actdata[32] = {}; 1336 1337 struct vcap_admin is2_admin = { 1338 .vtype = VCAP_TYPE_IS2, 1339 .first_cid = 8000000, 1340 .last_cid = 8099999, 1341 .lookups = 4, 1342 .last_valid_addr = 3071, 1343 .first_valid_addr = 0, 1344 .last_used_addr = 800, 1345 .cache = { 1346 .keystream = keydata, 1347 .maskstream = mskdata, 1348 .actionstream = actdata, 1349 }, 1350 }; 1351 struct vcap_rule *rule; 1352 struct vcap_rule_internal *ri; 1353 int vcap_chain_id = 8000000; 1354 enum vcap_user user = VCAP_USER_VCAP_UTIL; 1355 u16 priority = 10; 1356 int id = 100; 1357 int ret; 1358 struct vcap_u48_key smac = { 1359 .value = { 0x88, 0x75, 0x32, 0x34, 0x9e, 0xb1 }, 1360 .mask = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } 1361 }; 1362 struct vcap_u48_key dmac = { 1363 .value = { 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }, 1364 .mask = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } 1365 }; 1366 u32 port_mask_rng_value = 0x05; 1367 u32 port_mask_rng_mask = 0x0f; 1368 u32 igr_port_mask_value = 0xffabcd01; 1369 u32 igr_port_mask_mask = ~0; 1370 /* counter is written as the first operation */ 1371 u32 expwriteaddr[] = {792, 792, 793, 794, 795, 796, 797}; 1372 int idx; 1373 1374 vcap_test_api_init(&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 vcap_free_rule(rule); 1446 1447 /* Check that the rule has been freed: tricky to access since this 1448 * memory should not be accessible anymore 1449 */ 1450 KUNIT_EXPECT_PTR_NE(test, NULL, rule); 1451 ret = list_empty(&rule->keyfields); 1452 KUNIT_EXPECT_EQ(test, true, ret); 1453 ret = list_empty(&rule->actionfields); 1454 KUNIT_EXPECT_EQ(test, true, ret); 1455 1456 vcap_del_rule(&test_vctrl, &test_netdev, id); 1457 } 1458 1459 static void vcap_api_set_rule_counter_test(struct kunit *test) 1460 { 1461 struct vcap_admin is2_admin = { 1462 .cache = { 1463 .counter = 100, 1464 .sticky = true, 1465 }, 1466 }; 1467 struct vcap_rule_internal ri = { 1468 .data = { 1469 .id = 1001, 1470 }, 1471 .addr = 600, 1472 .admin = &is2_admin, 1473 .counter_id = 1002, 1474 .vctrl = &test_vctrl, 1475 }; 1476 struct vcap_rule_internal ri2 = { 1477 .data = { 1478 .id = 2001, 1479 }, 1480 .addr = 700, 1481 .admin = &is2_admin, 1482 .counter_id = 2002, 1483 .vctrl = &test_vctrl, 1484 }; 1485 struct vcap_counter ctr = { .value = 0, .sticky = false}; 1486 struct vcap_counter ctr2 = { .value = 101, .sticky = true}; 1487 int ret; 1488 1489 vcap_test_api_init(&is2_admin); 1490 list_add_tail(&ri.list, &is2_admin.rules); 1491 list_add_tail(&ri2.list, &is2_admin.rules); 1492 1493 pr_info("%s:%d\n", __func__, __LINE__); 1494 ret = vcap_rule_set_counter(&ri.data, &ctr); 1495 pr_info("%s:%d\n", __func__, __LINE__); 1496 KUNIT_EXPECT_EQ(test, 0, ret); 1497 1498 KUNIT_EXPECT_EQ(test, 1002, test_hw_counter_id); 1499 KUNIT_EXPECT_EQ(test, 0, test_hw_cache.counter); 1500 KUNIT_EXPECT_EQ(test, false, test_hw_cache.sticky); 1501 KUNIT_EXPECT_EQ(test, 600, test_updateaddr[0]); 1502 1503 ret = vcap_rule_set_counter(&ri2.data, &ctr2); 1504 KUNIT_EXPECT_EQ(test, 0, ret); 1505 1506 KUNIT_EXPECT_EQ(test, 2002, test_hw_counter_id); 1507 KUNIT_EXPECT_EQ(test, 101, test_hw_cache.counter); 1508 KUNIT_EXPECT_EQ(test, true, test_hw_cache.sticky); 1509 KUNIT_EXPECT_EQ(test, 700, test_updateaddr[1]); 1510 } 1511 1512 static void vcap_api_get_rule_counter_test(struct kunit *test) 1513 { 1514 struct vcap_admin is2_admin = { 1515 .cache = { 1516 .counter = 100, 1517 .sticky = true, 1518 }, 1519 }; 1520 struct vcap_rule_internal ri = { 1521 .data = { 1522 .id = 1010, 1523 }, 1524 .addr = 400, 1525 .admin = &is2_admin, 1526 .counter_id = 1011, 1527 .vctrl = &test_vctrl, 1528 }; 1529 struct vcap_rule_internal ri2 = { 1530 .data = { 1531 .id = 2011, 1532 }, 1533 .addr = 300, 1534 .admin = &is2_admin, 1535 .counter_id = 2012, 1536 .vctrl = &test_vctrl, 1537 }; 1538 struct vcap_counter ctr = {}; 1539 struct vcap_counter ctr2 = {}; 1540 int ret; 1541 1542 vcap_test_api_init(&is2_admin); 1543 test_hw_cache.counter = 55; 1544 test_hw_cache.sticky = true; 1545 1546 list_add_tail(&ri.list, &is2_admin.rules); 1547 list_add_tail(&ri2.list, &is2_admin.rules); 1548 1549 ret = vcap_rule_get_counter(&ri.data, &ctr); 1550 KUNIT_EXPECT_EQ(test, 0, ret); 1551 1552 KUNIT_EXPECT_EQ(test, 1011, test_hw_counter_id); 1553 KUNIT_EXPECT_EQ(test, 55, ctr.value); 1554 KUNIT_EXPECT_EQ(test, true, ctr.sticky); 1555 KUNIT_EXPECT_EQ(test, 400, test_updateaddr[0]); 1556 1557 test_hw_cache.counter = 22; 1558 test_hw_cache.sticky = false; 1559 1560 ret = vcap_rule_get_counter(&ri2.data, &ctr2); 1561 KUNIT_EXPECT_EQ(test, 0, ret); 1562 1563 KUNIT_EXPECT_EQ(test, 2012, test_hw_counter_id); 1564 KUNIT_EXPECT_EQ(test, 22, ctr2.value); 1565 KUNIT_EXPECT_EQ(test, false, ctr2.sticky); 1566 KUNIT_EXPECT_EQ(test, 300, test_updateaddr[1]); 1567 } 1568 1569 static void vcap_api_rule_insert_in_order_test(struct kunit *test) 1570 { 1571 /* Data used by VCAP Library callback */ 1572 static u32 keydata[32] = {}; 1573 static u32 mskdata[32] = {}; 1574 static u32 actdata[32] = {}; 1575 1576 struct vcap_admin admin = { 1577 .vtype = VCAP_TYPE_IS0, 1578 .first_cid = 10000, 1579 .last_cid = 19999, 1580 .lookups = 4, 1581 .last_valid_addr = 3071, 1582 .first_valid_addr = 0, 1583 .last_used_addr = 800, 1584 .cache = { 1585 .keystream = keydata, 1586 .maskstream = mskdata, 1587 .actionstream = actdata, 1588 }, 1589 }; 1590 1591 vcap_test_api_init(&admin); 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, 10, 500, 12, 780); 1597 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); 1598 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); 1599 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); 1600 1601 vcap_del_rule(&test_vctrl, &test_netdev, 200); 1602 vcap_del_rule(&test_vctrl, &test_netdev, 300); 1603 vcap_del_rule(&test_vctrl, &test_netdev, 400); 1604 vcap_del_rule(&test_vctrl, &test_netdev, 500); 1605 } 1606 1607 static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) 1608 { 1609 /* Data used by VCAP Library callback */ 1610 static u32 keydata[32] = {}; 1611 static u32 mskdata[32] = {}; 1612 static u32 actdata[32] = {}; 1613 1614 struct vcap_admin admin = { 1615 .vtype = VCAP_TYPE_IS0, 1616 .first_cid = 10000, 1617 .last_cid = 19999, 1618 .lookups = 4, 1619 .last_valid_addr = 3071, 1620 .first_valid_addr = 0, 1621 .last_used_addr = 800, 1622 .cache = { 1623 .keystream = keydata, 1624 .maskstream = mskdata, 1625 .actionstream = actdata, 1626 }, 1627 }; 1628 struct vcap_rule_internal *elem; 1629 u32 exp_addr[] = {780, 774, 771, 768, 767}; 1630 int idx; 1631 1632 vcap_test_api_init(&admin); 1633 1634 /* Create rules with different sizes and check that they are placed 1635 * at the correct address in the VCAP according to size 1636 */ 1637 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 200, 2, 798); 1638 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1639 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1640 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1641 1642 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 795); 1643 KUNIT_EXPECT_EQ(test, 6, test_move_offset); 1644 KUNIT_EXPECT_EQ(test, 3, test_move_count); 1645 KUNIT_EXPECT_EQ(test, 798, test_move_addr); 1646 1647 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 400, 6, 792); 1648 KUNIT_EXPECT_EQ(test, 6, test_move_offset); 1649 KUNIT_EXPECT_EQ(test, 6, test_move_count); 1650 KUNIT_EXPECT_EQ(test, 792, test_move_addr); 1651 1652 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 50, 500, 12, 780); 1653 KUNIT_EXPECT_EQ(test, 18, test_move_offset); 1654 KUNIT_EXPECT_EQ(test, 12, test_move_count); 1655 KUNIT_EXPECT_EQ(test, 786, test_move_addr); 1656 1657 idx = 0; 1658 list_for_each_entry(elem, &admin.rules, list) { 1659 KUNIT_EXPECT_EQ(test, exp_addr[idx], elem->addr); 1660 ++idx; 1661 } 1662 KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); 1663 1664 vcap_del_rule(&test_vctrl, &test_netdev, 500); 1665 vcap_del_rule(&test_vctrl, &test_netdev, 400); 1666 vcap_del_rule(&test_vctrl, &test_netdev, 300); 1667 vcap_del_rule(&test_vctrl, &test_netdev, 200); 1668 } 1669 1670 static void vcap_api_rule_remove_at_end_test(struct kunit *test) 1671 { 1672 /* Data used by VCAP Library callback */ 1673 static u32 keydata[32] = {}; 1674 static u32 mskdata[32] = {}; 1675 static u32 actdata[32] = {}; 1676 1677 struct vcap_admin admin = { 1678 .vtype = VCAP_TYPE_IS0, 1679 .first_cid = 10000, 1680 .last_cid = 19999, 1681 .lookups = 4, 1682 .last_valid_addr = 3071, 1683 .first_valid_addr = 0, 1684 .last_used_addr = 800, 1685 .cache = { 1686 .keystream = keydata, 1687 .maskstream = mskdata, 1688 .actionstream = actdata, 1689 }, 1690 }; 1691 int ret; 1692 1693 vcap_test_api_init(&admin); 1694 test_init_rule_deletion(); 1695 1696 /* Create rules with different sizes and check that they are placed 1697 * at the correct address in the VCAP according to size 1698 */ 1699 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); 1700 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); 1701 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); 1702 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); 1703 1704 /* Remove rules again from the end */ 1705 ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); 1706 KUNIT_EXPECT_EQ(test, 0, ret); 1707 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1708 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1709 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1710 KUNIT_EXPECT_EQ(test, 768, test_init_start); 1711 KUNIT_EXPECT_EQ(test, 2, test_init_count); 1712 KUNIT_EXPECT_EQ(test, 771, admin.last_used_addr); 1713 1714 ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); 1715 KUNIT_EXPECT_EQ(test, ret, 0); 1716 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1717 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1718 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1719 KUNIT_EXPECT_EQ(test, 771, test_init_start); 1720 KUNIT_EXPECT_EQ(test, 3, test_init_count); 1721 KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); 1722 1723 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); 1724 KUNIT_EXPECT_EQ(test, ret, 0); 1725 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1726 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1727 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1728 KUNIT_EXPECT_EQ(test, 774, test_init_start); 1729 KUNIT_EXPECT_EQ(test, 6, test_init_count); 1730 KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); 1731 1732 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); 1733 KUNIT_EXPECT_EQ(test, ret, 0); 1734 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1735 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1736 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1737 KUNIT_EXPECT_EQ(test, 780, test_init_start); 1738 KUNIT_EXPECT_EQ(test, 12, test_init_count); 1739 KUNIT_EXPECT_EQ(test, 3072, admin.last_used_addr); 1740 } 1741 1742 static void vcap_api_rule_remove_in_middle_test(struct kunit *test) 1743 { 1744 /* Data used by VCAP Library callback */ 1745 static u32 keydata[32] = {}; 1746 static u32 mskdata[32] = {}; 1747 static u32 actdata[32] = {}; 1748 1749 struct vcap_admin admin = { 1750 .vtype = VCAP_TYPE_IS0, 1751 .first_cid = 10000, 1752 .last_cid = 19999, 1753 .lookups = 4, 1754 .first_valid_addr = 0, 1755 .last_used_addr = 800, 1756 .last_valid_addr = 800 - 1, 1757 .cache = { 1758 .keystream = keydata, 1759 .maskstream = mskdata, 1760 .actionstream = actdata, 1761 }, 1762 }; 1763 int ret; 1764 1765 vcap_test_api_init(&admin); 1766 1767 /* Create rules with different sizes and check that they are placed 1768 * at the correct address in the VCAP according to size 1769 */ 1770 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); 1771 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); 1772 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); 1773 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); 1774 1775 /* Remove rules in the middle */ 1776 test_init_rule_deletion(); 1777 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); 1778 KUNIT_EXPECT_EQ(test, 0, ret); 1779 KUNIT_EXPECT_EQ(test, 768, test_move_addr); 1780 KUNIT_EXPECT_EQ(test, -6, test_move_offset); 1781 KUNIT_EXPECT_EQ(test, 6, test_move_count); 1782 KUNIT_EXPECT_EQ(test, 768, test_init_start); 1783 KUNIT_EXPECT_EQ(test, 6, test_init_count); 1784 KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); 1785 1786 test_init_rule_deletion(); 1787 ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); 1788 KUNIT_EXPECT_EQ(test, 0, ret); 1789 KUNIT_EXPECT_EQ(test, 774, test_move_addr); 1790 KUNIT_EXPECT_EQ(test, -4, test_move_offset); 1791 KUNIT_EXPECT_EQ(test, 2, test_move_count); 1792 KUNIT_EXPECT_EQ(test, 774, test_init_start); 1793 KUNIT_EXPECT_EQ(test, 4, test_init_count); 1794 KUNIT_EXPECT_EQ(test, 778, admin.last_used_addr); 1795 1796 test_init_rule_deletion(); 1797 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); 1798 KUNIT_EXPECT_EQ(test, 0, ret); 1799 KUNIT_EXPECT_EQ(test, 778, test_move_addr); 1800 KUNIT_EXPECT_EQ(test, -20, test_move_offset); 1801 KUNIT_EXPECT_EQ(test, 2, test_move_count); 1802 KUNIT_EXPECT_EQ(test, 778, test_init_start); 1803 KUNIT_EXPECT_EQ(test, 20, test_init_count); 1804 KUNIT_EXPECT_EQ(test, 798, admin.last_used_addr); 1805 1806 test_init_rule_deletion(); 1807 ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); 1808 KUNIT_EXPECT_EQ(test, 0, ret); 1809 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1810 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1811 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1812 KUNIT_EXPECT_EQ(test, 798, test_init_start); 1813 KUNIT_EXPECT_EQ(test, 2, test_init_count); 1814 KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr); 1815 } 1816 1817 static void vcap_api_rule_remove_in_front_test(struct kunit *test) 1818 { 1819 /* Data used by VCAP Library callback */ 1820 static u32 keydata[32] = {}; 1821 static u32 mskdata[32] = {}; 1822 static u32 actdata[32] = {}; 1823 1824 struct vcap_admin admin = { 1825 .vtype = VCAP_TYPE_IS0, 1826 .first_cid = 10000, 1827 .last_cid = 19999, 1828 .lookups = 4, 1829 .first_valid_addr = 0, 1830 .last_used_addr = 800, 1831 .last_valid_addr = 800 - 1, 1832 .cache = { 1833 .keystream = keydata, 1834 .maskstream = mskdata, 1835 .actionstream = actdata, 1836 }, 1837 }; 1838 int ret; 1839 1840 vcap_test_api_init(&admin); 1841 1842 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); 1843 KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); 1844 1845 test_init_rule_deletion(); 1846 ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); 1847 KUNIT_EXPECT_EQ(test, 0, ret); 1848 KUNIT_EXPECT_EQ(test, 0, test_move_addr); 1849 KUNIT_EXPECT_EQ(test, 0, test_move_offset); 1850 KUNIT_EXPECT_EQ(test, 0, test_move_count); 1851 KUNIT_EXPECT_EQ(test, 780, test_init_start); 1852 KUNIT_EXPECT_EQ(test, 12, test_init_count); 1853 KUNIT_EXPECT_EQ(test, 800, admin.last_used_addr); 1854 1855 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 792); 1856 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 789); 1857 test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 786); 1858 1859 test_init_rule_deletion(); 1860 ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); 1861 KUNIT_EXPECT_EQ(test, 0, ret); 1862 KUNIT_EXPECT_EQ(test, 786, test_move_addr); 1863 KUNIT_EXPECT_EQ(test, -8, test_move_offset); 1864 KUNIT_EXPECT_EQ(test, 6, test_move_count); 1865 KUNIT_EXPECT_EQ(test, 786, test_init_start); 1866 KUNIT_EXPECT_EQ(test, 8, test_init_count); 1867 KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); 1868 1869 vcap_del_rule(&test_vctrl, &test_netdev, 200); 1870 vcap_del_rule(&test_vctrl, &test_netdev, 300); 1871 } 1872 1873 static struct kunit_case vcap_api_rule_remove_test_cases[] = { 1874 KUNIT_CASE(vcap_api_rule_remove_at_end_test), 1875 KUNIT_CASE(vcap_api_rule_remove_in_middle_test), 1876 KUNIT_CASE(vcap_api_rule_remove_in_front_test), 1877 {} 1878 }; 1879 1880 static void vcap_api_next_lookup_basic_test(struct kunit *test) 1881 { 1882 struct vcap_admin admin1 = { 1883 .vtype = VCAP_TYPE_IS2, 1884 .vinst = 0, 1885 .first_cid = 8000000, 1886 .last_cid = 8199999, 1887 .lookups = 4, 1888 .lookups_per_instance = 2, 1889 }; 1890 struct vcap_admin admin2 = { 1891 .vtype = VCAP_TYPE_IS2, 1892 .vinst = 1, 1893 .first_cid = 8200000, 1894 .last_cid = 8399999, 1895 .lookups = 4, 1896 .lookups_per_instance = 2, 1897 }; 1898 bool ret; 1899 1900 vcap_test_api_init(&admin1); 1901 list_add_tail(&admin2.list, &test_vctrl.list); 1902 1903 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 1001000); 1904 KUNIT_EXPECT_EQ(test, false, ret); 1905 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000); 1906 KUNIT_EXPECT_EQ(test, false, ret); 1907 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000); 1908 KUNIT_EXPECT_EQ(test, true, ret); 1909 1910 ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8101000); 1911 KUNIT_EXPECT_EQ(test, false, ret); 1912 ret = vcap_is_next_lookup(&test_vctrl, 8100000, 8201000); 1913 KUNIT_EXPECT_EQ(test, true, ret); 1914 1915 ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8201000); 1916 KUNIT_EXPECT_EQ(test, false, ret); 1917 ret = vcap_is_next_lookup(&test_vctrl, 8200000, 8301000); 1918 KUNIT_EXPECT_EQ(test, true, ret); 1919 1920 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000); 1921 KUNIT_EXPECT_EQ(test, false, ret); 1922 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000); 1923 KUNIT_EXPECT_EQ(test, false, ret); 1924 } 1925 1926 static void vcap_api_next_lookup_advanced_test(struct kunit *test) 1927 { 1928 struct vcap_admin admin[] = { 1929 { 1930 .vtype = VCAP_TYPE_IS0, 1931 .vinst = 0, 1932 .first_cid = 1000000, 1933 .last_cid = 1199999, 1934 .lookups = 6, 1935 .lookups_per_instance = 2, 1936 }, { 1937 .vtype = VCAP_TYPE_IS0, 1938 .vinst = 1, 1939 .first_cid = 1200000, 1940 .last_cid = 1399999, 1941 .lookups = 6, 1942 .lookups_per_instance = 2, 1943 }, { 1944 .vtype = VCAP_TYPE_IS0, 1945 .vinst = 2, 1946 .first_cid = 1400000, 1947 .last_cid = 1599999, 1948 .lookups = 6, 1949 .lookups_per_instance = 2, 1950 }, { 1951 .vtype = VCAP_TYPE_IS2, 1952 .vinst = 0, 1953 .first_cid = 8000000, 1954 .last_cid = 8199999, 1955 .lookups = 4, 1956 .lookups_per_instance = 2, 1957 }, { 1958 .vtype = VCAP_TYPE_IS2, 1959 .vinst = 1, 1960 .first_cid = 8200000, 1961 .last_cid = 8399999, 1962 .lookups = 4, 1963 .lookups_per_instance = 2, 1964 } 1965 }; 1966 bool ret; 1967 1968 vcap_test_api_init(&admin[0]); 1969 list_add_tail(&admin[1].list, &test_vctrl.list); 1970 list_add_tail(&admin[2].list, &test_vctrl.list); 1971 list_add_tail(&admin[3].list, &test_vctrl.list); 1972 list_add_tail(&admin[4].list, &test_vctrl.list); 1973 1974 ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1001000); 1975 KUNIT_EXPECT_EQ(test, false, ret); 1976 ret = vcap_is_next_lookup(&test_vctrl, 1000000, 1101000); 1977 KUNIT_EXPECT_EQ(test, true, ret); 1978 1979 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1201000); 1980 KUNIT_EXPECT_EQ(test, true, ret); 1981 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 1301000); 1982 KUNIT_EXPECT_EQ(test, true, ret); 1983 ret = vcap_is_next_lookup(&test_vctrl, 1100000, 8101000); 1984 KUNIT_EXPECT_EQ(test, true, ret); 1985 ret = vcap_is_next_lookup(&test_vctrl, 1300000, 1401000); 1986 KUNIT_EXPECT_EQ(test, true, ret); 1987 ret = vcap_is_next_lookup(&test_vctrl, 1400000, 1501000); 1988 KUNIT_EXPECT_EQ(test, true, ret); 1989 ret = vcap_is_next_lookup(&test_vctrl, 1500000, 8001000); 1990 KUNIT_EXPECT_EQ(test, true, ret); 1991 1992 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8001000); 1993 KUNIT_EXPECT_EQ(test, false, ret); 1994 ret = vcap_is_next_lookup(&test_vctrl, 8000000, 8101000); 1995 KUNIT_EXPECT_EQ(test, true, ret); 1996 1997 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8301000); 1998 KUNIT_EXPECT_EQ(test, false, ret); 1999 ret = vcap_is_next_lookup(&test_vctrl, 8300000, 8401000); 2000 KUNIT_EXPECT_EQ(test, false, ret); 2001 } 2002 2003 static void vcap_api_filter_unsupported_keys_test(struct kunit *test) 2004 { 2005 struct vcap_admin admin = { 2006 .vtype = VCAP_TYPE_IS2, 2007 }; 2008 struct vcap_rule_internal ri = { 2009 .admin = &admin, 2010 .vctrl = &test_vctrl, 2011 .data.keyset = VCAP_KFS_MAC_ETYPE, 2012 }; 2013 enum vcap_key_field keylist[] = { 2014 VCAP_KF_TYPE, 2015 VCAP_KF_LOOKUP_FIRST_IS, 2016 VCAP_KF_ARP_ADDR_SPACE_OK_IS, /* arp keys are not in keyset */ 2017 VCAP_KF_ARP_PROTO_SPACE_OK_IS, 2018 VCAP_KF_ARP_LEN_OK_IS, 2019 VCAP_KF_ARP_TGT_MATCH_IS, 2020 VCAP_KF_ARP_SENDER_MATCH_IS, 2021 VCAP_KF_ARP_OPCODE_UNKNOWN_IS, 2022 VCAP_KF_ARP_OPCODE, 2023 VCAP_KF_8021Q_DEI_CLS, 2024 VCAP_KF_8021Q_PCP_CLS, 2025 VCAP_KF_8021Q_VID_CLS, 2026 VCAP_KF_L2_MC_IS, 2027 VCAP_KF_L2_BC_IS, 2028 }; 2029 enum vcap_key_field expected[] = { 2030 VCAP_KF_TYPE, 2031 VCAP_KF_LOOKUP_FIRST_IS, 2032 VCAP_KF_8021Q_DEI_CLS, 2033 VCAP_KF_8021Q_PCP_CLS, 2034 VCAP_KF_8021Q_VID_CLS, 2035 VCAP_KF_L2_MC_IS, 2036 VCAP_KF_L2_BC_IS, 2037 }; 2038 struct vcap_client_keyfield *ckf, *next; 2039 bool ret; 2040 int idx; 2041 2042 /* Add all keys to the rule */ 2043 INIT_LIST_HEAD(&ri.data.keyfields); 2044 for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { 2045 ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); 2046 if (ckf) { 2047 ckf->ctrl.key = keylist[idx]; 2048 list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); 2049 } 2050 } 2051 2052 KUNIT_EXPECT_EQ(test, 14, ARRAY_SIZE(keylist)); 2053 2054 /* Drop unsupported keys from the rule */ 2055 ret = vcap_filter_rule_keys(&ri.data, NULL, 0, true); 2056 2057 KUNIT_EXPECT_EQ(test, 0, ret); 2058 2059 /* Check remaining keys in the rule */ 2060 idx = 0; 2061 list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { 2062 KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); 2063 list_del(&ckf->ctrl.list); 2064 kfree(ckf); 2065 ++idx; 2066 } 2067 KUNIT_EXPECT_EQ(test, 7, idx); 2068 } 2069 2070 static void vcap_api_filter_keylist_test(struct kunit *test) 2071 { 2072 struct vcap_admin admin = { 2073 .vtype = VCAP_TYPE_IS0, 2074 }; 2075 struct vcap_rule_internal ri = { 2076 .admin = &admin, 2077 .vctrl = &test_vctrl, 2078 .data.keyset = VCAP_KFS_NORMAL_7TUPLE, 2079 }; 2080 enum vcap_key_field keylist[] = { 2081 VCAP_KF_TYPE, 2082 VCAP_KF_LOOKUP_FIRST_IS, 2083 VCAP_KF_LOOKUP_GEN_IDX_SEL, 2084 VCAP_KF_LOOKUP_GEN_IDX, 2085 VCAP_KF_IF_IGR_PORT_MASK_SEL, 2086 VCAP_KF_IF_IGR_PORT_MASK, 2087 VCAP_KF_L2_MC_IS, 2088 VCAP_KF_L2_BC_IS, 2089 VCAP_KF_8021Q_VLAN_TAGS, 2090 VCAP_KF_8021Q_TPID0, 2091 VCAP_KF_8021Q_PCP0, 2092 VCAP_KF_8021Q_DEI0, 2093 VCAP_KF_8021Q_VID0, 2094 VCAP_KF_8021Q_TPID1, 2095 VCAP_KF_8021Q_PCP1, 2096 VCAP_KF_8021Q_DEI1, 2097 VCAP_KF_8021Q_VID1, 2098 VCAP_KF_8021Q_TPID2, 2099 VCAP_KF_8021Q_PCP2, 2100 VCAP_KF_8021Q_DEI2, 2101 VCAP_KF_8021Q_VID2, 2102 VCAP_KF_L2_DMAC, 2103 VCAP_KF_L2_SMAC, 2104 VCAP_KF_IP_MC_IS, 2105 VCAP_KF_ETYPE_LEN_IS, 2106 VCAP_KF_ETYPE, 2107 VCAP_KF_IP_SNAP_IS, 2108 VCAP_KF_IP4_IS, 2109 VCAP_KF_L3_FRAGMENT_TYPE, 2110 VCAP_KF_L3_FRAG_INVLD_L4_LEN, 2111 VCAP_KF_L3_OPTIONS_IS, 2112 VCAP_KF_L3_DSCP, 2113 VCAP_KF_L3_IP6_DIP, 2114 VCAP_KF_L3_IP6_SIP, 2115 VCAP_KF_TCP_UDP_IS, 2116 VCAP_KF_TCP_IS, 2117 VCAP_KF_L4_SPORT, 2118 VCAP_KF_L4_RNG, 2119 }; 2120 enum vcap_key_field droplist[] = { 2121 VCAP_KF_8021Q_TPID1, 2122 VCAP_KF_8021Q_PCP1, 2123 VCAP_KF_8021Q_DEI1, 2124 VCAP_KF_8021Q_VID1, 2125 VCAP_KF_8021Q_TPID2, 2126 VCAP_KF_8021Q_PCP2, 2127 VCAP_KF_8021Q_DEI2, 2128 VCAP_KF_8021Q_VID2, 2129 VCAP_KF_L3_IP6_DIP, 2130 VCAP_KF_L3_IP6_SIP, 2131 VCAP_KF_L4_SPORT, 2132 VCAP_KF_L4_RNG, 2133 }; 2134 enum vcap_key_field expected[] = { 2135 VCAP_KF_TYPE, 2136 VCAP_KF_LOOKUP_FIRST_IS, 2137 VCAP_KF_LOOKUP_GEN_IDX_SEL, 2138 VCAP_KF_LOOKUP_GEN_IDX, 2139 VCAP_KF_IF_IGR_PORT_MASK_SEL, 2140 VCAP_KF_IF_IGR_PORT_MASK, 2141 VCAP_KF_L2_MC_IS, 2142 VCAP_KF_L2_BC_IS, 2143 VCAP_KF_8021Q_VLAN_TAGS, 2144 VCAP_KF_8021Q_TPID0, 2145 VCAP_KF_8021Q_PCP0, 2146 VCAP_KF_8021Q_DEI0, 2147 VCAP_KF_8021Q_VID0, 2148 VCAP_KF_L2_DMAC, 2149 VCAP_KF_L2_SMAC, 2150 VCAP_KF_IP_MC_IS, 2151 VCAP_KF_ETYPE_LEN_IS, 2152 VCAP_KF_ETYPE, 2153 VCAP_KF_IP_SNAP_IS, 2154 VCAP_KF_IP4_IS, 2155 VCAP_KF_L3_FRAGMENT_TYPE, 2156 VCAP_KF_L3_FRAG_INVLD_L4_LEN, 2157 VCAP_KF_L3_OPTIONS_IS, 2158 VCAP_KF_L3_DSCP, 2159 VCAP_KF_TCP_UDP_IS, 2160 VCAP_KF_TCP_IS, 2161 }; 2162 struct vcap_client_keyfield *ckf, *next; 2163 bool ret; 2164 int idx; 2165 2166 /* Add all keys to the rule */ 2167 INIT_LIST_HEAD(&ri.data.keyfields); 2168 for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { 2169 ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); 2170 if (ckf) { 2171 ckf->ctrl.key = keylist[idx]; 2172 list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); 2173 } 2174 } 2175 2176 KUNIT_EXPECT_EQ(test, 38, ARRAY_SIZE(keylist)); 2177 2178 /* Drop listed keys from the rule */ 2179 ret = vcap_filter_rule_keys(&ri.data, droplist, ARRAY_SIZE(droplist), 2180 false); 2181 2182 KUNIT_EXPECT_EQ(test, 0, ret); 2183 2184 /* Check remaining keys in the rule */ 2185 idx = 0; 2186 list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { 2187 KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); 2188 list_del(&ckf->ctrl.list); 2189 kfree(ckf); 2190 ++idx; 2191 } 2192 KUNIT_EXPECT_EQ(test, 26, idx); 2193 } 2194 2195 static void vcap_api_rule_chain_path_test(struct kunit *test) 2196 { 2197 struct vcap_admin admin1 = { 2198 .vtype = VCAP_TYPE_IS0, 2199 .vinst = 0, 2200 .first_cid = 1000000, 2201 .last_cid = 1199999, 2202 .lookups = 6, 2203 .lookups_per_instance = 2, 2204 }; 2205 struct vcap_enabled_port eport3 = { 2206 .ndev = &test_netdev, 2207 .cookie = 0x100, 2208 .src_cid = 0, 2209 .dst_cid = 1000000, 2210 }; 2211 struct vcap_enabled_port eport2 = { 2212 .ndev = &test_netdev, 2213 .cookie = 0x200, 2214 .src_cid = 1000000, 2215 .dst_cid = 1100000, 2216 }; 2217 struct vcap_enabled_port eport1 = { 2218 .ndev = &test_netdev, 2219 .cookie = 0x300, 2220 .src_cid = 1100000, 2221 .dst_cid = 8000000, 2222 }; 2223 bool ret; 2224 int chain; 2225 2226 vcap_test_api_init(&admin1); 2227 list_add_tail(&eport1.list, &admin1.enabled); 2228 list_add_tail(&eport2.list, &admin1.enabled); 2229 list_add_tail(&eport3.list, &admin1.enabled); 2230 2231 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1000000); 2232 KUNIT_EXPECT_EQ(test, true, ret); 2233 2234 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1100000); 2235 KUNIT_EXPECT_EQ(test, true, ret); 2236 2237 ret = vcap_path_exist(&test_vctrl, &test_netdev, 1200000); 2238 KUNIT_EXPECT_EQ(test, false, ret); 2239 2240 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 0); 2241 KUNIT_EXPECT_EQ(test, 1000000, chain); 2242 2243 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 1000000); 2244 KUNIT_EXPECT_EQ(test, 1100000, chain); 2245 2246 chain = vcap_get_next_chain(&test_vctrl, &test_netdev, 1100000); 2247 KUNIT_EXPECT_EQ(test, 8000000, chain); 2248 } 2249 2250 static struct kunit_case vcap_api_rule_enable_test_cases[] = { 2251 KUNIT_CASE(vcap_api_rule_chain_path_test), 2252 {} 2253 }; 2254 2255 static struct kunit_suite vcap_api_rule_enable_test_suite = { 2256 .name = "VCAP_API_Rule_Enable_Testsuite", 2257 .test_cases = vcap_api_rule_enable_test_cases, 2258 }; 2259 2260 static struct kunit_suite vcap_api_rule_remove_test_suite = { 2261 .name = "VCAP_API_Rule_Remove_Testsuite", 2262 .test_cases = vcap_api_rule_remove_test_cases, 2263 }; 2264 2265 static struct kunit_case vcap_api_rule_insert_test_cases[] = { 2266 KUNIT_CASE(vcap_api_rule_insert_in_order_test), 2267 KUNIT_CASE(vcap_api_rule_insert_reverse_order_test), 2268 {} 2269 }; 2270 2271 static struct kunit_suite vcap_api_rule_insert_test_suite = { 2272 .name = "VCAP_API_Rule_Insert_Testsuite", 2273 .test_cases = vcap_api_rule_insert_test_cases, 2274 }; 2275 2276 static struct kunit_case vcap_api_rule_counter_test_cases[] = { 2277 KUNIT_CASE(vcap_api_set_rule_counter_test), 2278 KUNIT_CASE(vcap_api_get_rule_counter_test), 2279 {} 2280 }; 2281 2282 static struct kunit_suite vcap_api_rule_counter_test_suite = { 2283 .name = "VCAP_API_Rule_Counter_Testsuite", 2284 .test_cases = vcap_api_rule_counter_test_cases, 2285 }; 2286 2287 static struct kunit_case vcap_api_support_test_cases[] = { 2288 KUNIT_CASE(vcap_api_next_lookup_basic_test), 2289 KUNIT_CASE(vcap_api_next_lookup_advanced_test), 2290 KUNIT_CASE(vcap_api_filter_unsupported_keys_test), 2291 KUNIT_CASE(vcap_api_filter_keylist_test), 2292 {} 2293 }; 2294 2295 static struct kunit_suite vcap_api_support_test_suite = { 2296 .name = "VCAP_API_Support_Testsuite", 2297 .test_cases = vcap_api_support_test_cases, 2298 }; 2299 2300 static struct kunit_case vcap_api_full_rule_test_cases[] = { 2301 KUNIT_CASE(vcap_api_rule_find_keyset_basic_test), 2302 KUNIT_CASE(vcap_api_rule_find_keyset_failed_test), 2303 KUNIT_CASE(vcap_api_rule_find_keyset_many_test), 2304 KUNIT_CASE(vcap_api_encode_rule_test), 2305 {} 2306 }; 2307 2308 static struct kunit_suite vcap_api_full_rule_test_suite = { 2309 .name = "VCAP_API_Full_Rule_Testsuite", 2310 .test_cases = vcap_api_full_rule_test_cases, 2311 }; 2312 2313 static struct kunit_case vcap_api_rule_value_test_cases[] = { 2314 KUNIT_CASE(vcap_api_rule_add_keyvalue_test), 2315 KUNIT_CASE(vcap_api_rule_add_actionvalue_test), 2316 {} 2317 }; 2318 2319 static struct kunit_suite vcap_api_rule_value_test_suite = { 2320 .name = "VCAP_API_Rule_Value_Testsuite", 2321 .test_cases = vcap_api_rule_value_test_cases, 2322 }; 2323 2324 static struct kunit_case vcap_api_encoding_test_cases[] = { 2325 KUNIT_CASE(vcap_api_set_bit_1_test), 2326 KUNIT_CASE(vcap_api_set_bit_0_test), 2327 KUNIT_CASE(vcap_api_iterator_init_test), 2328 KUNIT_CASE(vcap_api_iterator_next_test), 2329 KUNIT_CASE(vcap_api_encode_typegroups_test), 2330 KUNIT_CASE(vcap_api_encode_bit_test), 2331 KUNIT_CASE(vcap_api_encode_field_test), 2332 KUNIT_CASE(vcap_api_encode_short_field_test), 2333 KUNIT_CASE(vcap_api_encode_keyfield_test), 2334 KUNIT_CASE(vcap_api_encode_max_keyfield_test), 2335 KUNIT_CASE(vcap_api_encode_actionfield_test), 2336 KUNIT_CASE(vcap_api_keyfield_typegroup_test), 2337 KUNIT_CASE(vcap_api_actionfield_typegroup_test), 2338 KUNIT_CASE(vcap_api_vcap_keyfields_test), 2339 KUNIT_CASE(vcap_api_vcap_actionfields_test), 2340 KUNIT_CASE(vcap_api_encode_rule_keyset_test), 2341 KUNIT_CASE(vcap_api_encode_rule_actionset_test), 2342 {} 2343 }; 2344 2345 static struct kunit_suite vcap_api_encoding_test_suite = { 2346 .name = "VCAP_API_Encoding_Testsuite", 2347 .test_cases = vcap_api_encoding_test_cases, 2348 }; 2349 2350 kunit_test_suite(vcap_api_rule_enable_test_suite); 2351 kunit_test_suite(vcap_api_rule_remove_test_suite); 2352 kunit_test_suite(vcap_api_rule_insert_test_suite); 2353 kunit_test_suite(vcap_api_rule_counter_test_suite); 2354 kunit_test_suite(vcap_api_support_test_suite); 2355 kunit_test_suite(vcap_api_full_rule_test_suite); 2356 kunit_test_suite(vcap_api_rule_value_test_suite); 2357 kunit_test_suite(vcap_api_encoding_test_suite); 2358