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