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