1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation 3 */ 4 5 #ifndef RTE_EXEC_ENV_WINDOWS 6 7 #include <string.h> 8 #include <rte_byteorder.h> 9 #include <rte_table_lpm_ipv6.h> 10 #include <rte_lru.h> 11 #include <rte_cycles.h> 12 #include "test_table_tables.h" 13 #include "test_table.h" 14 15 table_test table_tests[] = { 16 test_table_stub, 17 test_table_array, 18 test_table_lpm, 19 test_table_lpm_ipv6, 20 test_table_hash_lru, 21 test_table_hash_ext, 22 test_table_hash_cuckoo, 23 }; 24 25 #define PREPARE_PACKET(mbuf, value) do { \ 26 uint32_t *k32, *signature; \ 27 uint8_t *key; \ 28 mbuf = rte_pktmbuf_alloc(pool); \ 29 signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \ 30 APP_METADATA_OFFSET(0)); \ 31 key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \ 32 APP_METADATA_OFFSET(32)); \ 33 if (mbuf->priv_size + mbuf->buf_len >= 64) \ 34 memset(key, 0, 32); \ 35 k32 = (uint32_t *) key; \ 36 k32[0] = (value); \ 37 *signature = pipeline_test_hash(key, NULL, 0, 0); \ 38 } while (0) 39 40 unsigned n_table_tests = RTE_DIM(table_tests); 41 42 /* Function prototypes */ 43 static int 44 test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size); 45 static int 46 test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size); 47 48 struct rte_bucket_4_8 { 49 /* Cache line 0 */ 50 uint64_t signature; 51 uint64_t lru_list; 52 struct rte_bucket_4_8 *next; 53 uint64_t next_valid; 54 uint64_t key[4]; 55 /* Cache line 1 */ 56 uint8_t data[]; 57 }; 58 59 #if RTE_TABLE_HASH_LRU_STRATEGY == 3 60 uint64_t shuffles = 0xfffffffdfffbfff9ULL; 61 #else 62 uint64_t shuffles = 0x0003000200010000ULL; 63 #endif 64 65 static int test_lru_update(void) 66 { 67 struct rte_bucket_4_8 b; 68 struct rte_bucket_4_8 *bucket; 69 uint32_t i; 70 uint64_t pos; 71 uint64_t iterations; 72 uint64_t j; 73 int poss; 74 75 printf("---------------------------\n"); 76 printf("Testing lru_update macro...\n"); 77 printf("---------------------------\n"); 78 bucket = &b; 79 iterations = 10; 80 #if RTE_TABLE_HASH_LRU_STRATEGY == 3 81 bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL; 82 #else 83 bucket->lru_list = 0x0000000100020003ULL; 84 #endif 85 poss = 0; 86 for (j = 0; j < iterations; j++) 87 for (i = 0; i < 9; i++) { 88 uint32_t idx = i >> 1; 89 lru_update(bucket, idx); 90 pos = lru_pos(bucket); 91 poss += pos; 92 printf("%s: %d lru_list=%016"PRIx64", upd=%d, " 93 "pos=%"PRIx64"\n", 94 __func__, i, bucket->lru_list, i>>1, pos); 95 } 96 97 if (bucket->lru_list != shuffles) { 98 printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016" 99 PRIx64"\n", 100 __func__, i, bucket->lru_list, shuffles); 101 return -1; 102 } 103 printf("%s: output checksum of results =%d\n", 104 __func__, poss); 105 #if 0 106 if (poss != 126) { 107 printf("%s: ERROR output checksum of results =%d expected %d\n", 108 __func__, poss, 126); 109 return -1; 110 } 111 #endif 112 113 fflush(stdout); 114 115 uint64_t sc_start = rte_rdtsc(); 116 iterations = 100000000; 117 poss = 0; 118 for (j = 0; j < iterations; j++) { 119 for (i = 0; i < 4; i++) { 120 lru_update(bucket, i); 121 pos |= bucket->lru_list; 122 } 123 } 124 uint64_t sc_end = rte_rdtsc(); 125 126 printf("%s: output checksum of results =%llu\n", 127 __func__, (long long unsigned int)pos); 128 printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n", 129 __func__, sc_start, sc_end); 130 printf("\nlru_update: %lu cycles per loop iteration.\n\n", 131 (long unsigned int)((sc_end-sc_start)/(iterations*4))); 132 133 return 0; 134 } 135 136 /* Table tests */ 137 int 138 test_table_stub(void) 139 { 140 int i; 141 uint64_t expected_mask = 0, result_mask; 142 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 143 void *table; 144 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 145 146 /* Create */ 147 table = rte_table_stub_ops.f_create(NULL, 0, 1); 148 if (table == NULL) 149 return -1; 150 151 /* Traffic flow */ 152 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 153 if (i % 2 == 0) 154 PREPARE_PACKET(mbufs[i], 0xadadadad); 155 else 156 PREPARE_PACKET(mbufs[i], 0xadadadab); 157 158 expected_mask = 0; 159 rte_table_stub_ops.f_lookup(table, mbufs, -1, 160 &result_mask, (void **)entries); 161 if (result_mask != expected_mask) 162 return -2; 163 164 /* Free resources */ 165 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 166 rte_pktmbuf_free(mbufs[i]); 167 168 return 0; 169 } 170 171 int 172 test_table_array(void) 173 { 174 int status, i; 175 uint64_t result_mask; 176 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 177 void *table; 178 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 179 char entry1, entry2; 180 void *entry_ptr; 181 int key_found; 182 183 /* Initialize params and create tables */ 184 struct rte_table_array_params array_params = { 185 .n_entries = 7, 186 .offset = APP_METADATA_OFFSET(1) 187 }; 188 189 table = rte_table_array_ops.f_create(NULL, 0, 1); 190 if (table != NULL) 191 return -1; 192 193 array_params.n_entries = 0; 194 195 table = rte_table_array_ops.f_create(&array_params, 0, 1); 196 if (table != NULL) 197 return -2; 198 199 array_params.n_entries = 7; 200 201 table = rte_table_array_ops.f_create(&array_params, 0, 1); 202 if (table != NULL) 203 return -3; 204 205 array_params.n_entries = 1 << 24; 206 array_params.offset = APP_METADATA_OFFSET(1); 207 208 table = rte_table_array_ops.f_create(&array_params, 0, 1); 209 if (table == NULL) 210 return -4; 211 212 array_params.offset = APP_METADATA_OFFSET(32); 213 214 table = rte_table_array_ops.f_create(&array_params, 0, 1); 215 if (table == NULL) 216 return -5; 217 218 /* Free */ 219 status = rte_table_array_ops.f_free(table); 220 if (status < 0) 221 return -6; 222 223 status = rte_table_array_ops.f_free(NULL); 224 if (status == 0) 225 return -7; 226 227 /* Add */ 228 struct rte_table_array_key array_key_1 = { 229 .pos = 10, 230 }; 231 struct rte_table_array_key array_key_2 = { 232 .pos = 20, 233 }; 234 entry1 = 'A'; 235 entry2 = 'B'; 236 237 table = rte_table_array_ops.f_create(&array_params, 0, 1); 238 if (table == NULL) 239 return -8; 240 241 status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1, 242 &key_found, &entry_ptr); 243 if (status == 0) 244 return -9; 245 246 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL, 247 &key_found, &entry_ptr); 248 if (status == 0) 249 return -10; 250 251 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, 252 &entry1, &key_found, &entry_ptr); 253 if (status != 0) 254 return -11; 255 256 /* Traffic flow */ 257 status = rte_table_array_ops.f_add(table, (void *) &array_key_2, 258 &entry2, &key_found, &entry_ptr); 259 if (status != 0) 260 return -12; 261 262 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 263 if (i % 2 == 0) 264 PREPARE_PACKET(mbufs[i], 10); 265 else 266 PREPARE_PACKET(mbufs[i], 20); 267 268 rte_table_array_ops.f_lookup(table, mbufs, -1, 269 &result_mask, (void **)entries); 270 271 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 272 if (i % 2 == 0 && *entries[i] != 'A') 273 return -13; 274 else 275 if (i % 2 == 1 && *entries[i] != 'B') 276 return -13; 277 278 /* Free resources */ 279 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 280 rte_pktmbuf_free(mbufs[i]); 281 282 status = rte_table_array_ops.f_free(table); 283 284 return 0; 285 } 286 287 int 288 test_table_lpm(void) 289 { 290 int status, i; 291 uint64_t expected_mask = 0, result_mask; 292 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 293 void *table; 294 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 295 uint64_t entry; 296 void *entry_ptr; 297 int key_found; 298 uint32_t entry_size = sizeof(entry); 299 300 /* Initialize params and create tables */ 301 struct rte_table_lpm_params lpm_params = { 302 .name = "LPM", 303 .n_rules = 1 << 24, 304 .number_tbl8s = 1 << 8, 305 .flags = 0, 306 .entry_unique_size = entry_size, 307 .offset = APP_METADATA_OFFSET(1) 308 }; 309 310 table = rte_table_lpm_ops.f_create(NULL, 0, entry_size); 311 if (table != NULL) 312 return -1; 313 314 lpm_params.name = NULL; 315 316 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 317 if (table != NULL) 318 return -2; 319 320 lpm_params.name = "LPM"; 321 lpm_params.n_rules = 0; 322 323 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 324 if (table != NULL) 325 return -3; 326 327 lpm_params.n_rules = 1 << 24; 328 lpm_params.offset = APP_METADATA_OFFSET(32); 329 lpm_params.entry_unique_size = 0; 330 331 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 332 if (table != NULL) 333 return -4; 334 335 lpm_params.entry_unique_size = entry_size + 1; 336 337 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 338 if (table != NULL) 339 return -5; 340 341 lpm_params.entry_unique_size = entry_size; 342 343 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 344 if (table == NULL) 345 return -6; 346 347 /* Free */ 348 status = rte_table_lpm_ops.f_free(table); 349 if (status < 0) 350 return -7; 351 352 status = rte_table_lpm_ops.f_free(NULL); 353 if (status == 0) 354 return -8; 355 356 /* Add */ 357 struct rte_table_lpm_key lpm_key; 358 lpm_key.ip = 0xadadadad; 359 360 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 361 if (table == NULL) 362 return -9; 363 364 status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found, 365 &entry_ptr); 366 if (status == 0) 367 return -10; 368 369 status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found, 370 &entry_ptr); 371 if (status == 0) 372 return -11; 373 374 status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found, 375 &entry_ptr); 376 if (status == 0) 377 return -12; 378 379 lpm_key.depth = 0; 380 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 381 &entry_ptr); 382 if (status == 0) 383 return -13; 384 385 lpm_key.depth = 33; 386 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 387 &entry_ptr); 388 if (status == 0) 389 return -14; 390 391 lpm_key.depth = 16; 392 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 393 &entry_ptr); 394 if (status != 0) 395 return -15; 396 397 /* Delete */ 398 status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL); 399 if (status == 0) 400 return -16; 401 402 status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL); 403 if (status == 0) 404 return -17; 405 406 lpm_key.depth = 0; 407 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 408 if (status == 0) 409 return -18; 410 411 lpm_key.depth = 33; 412 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 413 if (status == 0) 414 return -19; 415 416 lpm_key.depth = 16; 417 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 418 if (status != 0) 419 return -20; 420 421 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 422 if (status != 0) 423 return -21; 424 425 /* Traffic flow */ 426 entry = 'A'; 427 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 428 &entry_ptr); 429 if (status < 0) 430 return -22; 431 432 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 433 if (i % 2 == 0) { 434 expected_mask |= (uint64_t)1 << i; 435 PREPARE_PACKET(mbufs[i], 0xadadadad); 436 } else 437 PREPARE_PACKET(mbufs[i], 0xadadadab); 438 439 rte_table_lpm_ops.f_lookup(table, mbufs, -1, 440 &result_mask, (void **)entries); 441 if (result_mask != expected_mask) 442 return -23; 443 444 /* Free resources */ 445 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 446 rte_pktmbuf_free(mbufs[i]); 447 448 status = rte_table_lpm_ops.f_free(table); 449 450 return 0; 451 } 452 453 int 454 test_table_lpm_ipv6(void) 455 { 456 int status, i; 457 uint64_t expected_mask = 0, result_mask; 458 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 459 void *table; 460 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 461 uint64_t entry; 462 void *entry_ptr; 463 int key_found; 464 uint32_t entry_size = sizeof(entry); 465 466 /* Initialize params and create tables */ 467 struct rte_table_lpm_ipv6_params lpm_params = { 468 .name = "LPM", 469 .n_rules = 1 << 24, 470 .number_tbl8s = 1 << 18, 471 .entry_unique_size = entry_size, 472 .offset = APP_METADATA_OFFSET(32) 473 }; 474 475 table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size); 476 if (table != NULL) 477 return -1; 478 479 lpm_params.name = NULL; 480 481 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 482 if (table != NULL) 483 return -2; 484 485 lpm_params.name = "LPM"; 486 lpm_params.n_rules = 0; 487 488 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 489 if (table != NULL) 490 return -3; 491 492 lpm_params.n_rules = 1 << 24; 493 lpm_params.number_tbl8s = 0; 494 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 495 if (table != NULL) 496 return -4; 497 498 lpm_params.number_tbl8s = 1 << 18; 499 lpm_params.entry_unique_size = 0; 500 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 501 if (table != NULL) 502 return -5; 503 504 lpm_params.entry_unique_size = entry_size + 1; 505 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 506 if (table != NULL) 507 return -6; 508 509 lpm_params.entry_unique_size = entry_size; 510 lpm_params.offset = APP_METADATA_OFFSET(32); 511 512 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 513 if (table == NULL) 514 return -7; 515 516 /* Free */ 517 status = rte_table_lpm_ipv6_ops.f_free(table); 518 if (status < 0) 519 return -8; 520 521 status = rte_table_lpm_ipv6_ops.f_free(NULL); 522 if (status == 0) 523 return -9; 524 525 /* Add */ 526 struct rte_table_lpm_ipv6_key lpm_key; 527 528 lpm_key.ip.a[0] = 0xad; 529 lpm_key.ip.a[1] = 0xad; 530 lpm_key.ip.a[2] = 0xad; 531 lpm_key.ip.a[3] = 0xad; 532 533 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 534 if (table == NULL) 535 return -10; 536 537 status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry, 538 &key_found, &entry_ptr); 539 if (status == 0) 540 return -11; 541 542 status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found, 543 &entry_ptr); 544 if (status == 0) 545 return -12; 546 547 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found, 548 &entry_ptr); 549 if (status == 0) 550 return -13; 551 552 lpm_key.depth = 0; 553 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 554 &key_found, &entry_ptr); 555 if (status == 0) 556 return -14; 557 558 lpm_key.depth = 129; 559 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 560 &key_found, &entry_ptr); 561 if (status == 0) 562 return -15; 563 564 lpm_key.depth = 16; 565 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 566 &key_found, &entry_ptr); 567 if (status != 0) 568 return -16; 569 570 /* Delete */ 571 status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found, 572 NULL); 573 if (status == 0) 574 return -17; 575 576 status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL); 577 if (status == 0) 578 return -18; 579 580 lpm_key.depth = 0; 581 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 582 NULL); 583 if (status == 0) 584 return -19; 585 586 lpm_key.depth = 129; 587 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 588 NULL); 589 if (status == 0) 590 return -20; 591 592 lpm_key.depth = 16; 593 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 594 NULL); 595 if (status != 0) 596 return -21; 597 598 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 599 NULL); 600 if (status != 0) 601 return -22; 602 603 /* Traffic flow */ 604 entry = 'A'; 605 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 606 &key_found, &entry_ptr); 607 if (status < 0) 608 return -23; 609 610 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 611 if (i % 2 == 0) { 612 expected_mask |= (uint64_t)1 << i; 613 PREPARE_PACKET(mbufs[i], 0xadadadad); 614 } else 615 PREPARE_PACKET(mbufs[i], 0xadadadab); 616 617 rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1, 618 &result_mask, (void **)entries); 619 if (result_mask != expected_mask) 620 return -24; 621 622 /* Free resources */ 623 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 624 rte_pktmbuf_free(mbufs[i]); 625 626 status = rte_table_lpm_ipv6_ops.f_free(table); 627 628 return 0; 629 } 630 631 static int 632 test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size) 633 { 634 int status, i; 635 uint64_t expected_mask = 0, result_mask; 636 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 637 void *table; 638 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 639 char entry; 640 void *entry_ptr; 641 int key_found; 642 643 /* Initialize params and create tables */ 644 struct rte_table_hash_params hash_params = { 645 .name = "TABLE", 646 .key_size = key_size, 647 .key_offset = APP_METADATA_OFFSET(32), 648 .key_mask = NULL, 649 .n_keys = 1 << 10, 650 .n_buckets = 1 << 10, 651 .f_hash = pipeline_test_hash, 652 .seed = 0, 653 }; 654 655 hash_params.n_keys = 0; 656 657 table = ops->f_create(&hash_params, 0, 1); 658 if (table != NULL) 659 return -1; 660 661 hash_params.n_keys = 1 << 10; 662 hash_params.f_hash = NULL; 663 664 table = ops->f_create(&hash_params, 0, 1); 665 if (table != NULL) 666 return -4; 667 668 hash_params.f_hash = pipeline_test_hash; 669 670 table = ops->f_create(&hash_params, 0, 1); 671 if (table == NULL) 672 return -5; 673 674 /* Free */ 675 status = ops->f_free(table); 676 if (status < 0) 677 return -6; 678 679 status = ops->f_free(NULL); 680 if (status == 0) 681 return -7; 682 683 /* Add */ 684 uint8_t key[32]; 685 uint32_t *k32 = (uint32_t *) &key; 686 687 memset(key, 0, 32); 688 k32[0] = rte_be_to_cpu_32(0xadadadad); 689 690 table = ops->f_create(&hash_params, 0, 1); 691 if (table == NULL) 692 return -8; 693 694 entry = 'A'; 695 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 696 if (status != 0) 697 return -9; 698 699 /* Delete */ 700 status = ops->f_delete(table, &key, &key_found, NULL); 701 if (status != 0) 702 return -10; 703 704 status = ops->f_delete(table, &key, &key_found, NULL); 705 if (status != 0) 706 return -11; 707 708 /* Traffic flow */ 709 entry = 'A'; 710 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 711 if (status < 0) 712 return -12; 713 714 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 715 if (i % 2 == 0) { 716 expected_mask |= (uint64_t)1 << i; 717 PREPARE_PACKET(mbufs[i], 0xadadadad); 718 } else 719 PREPARE_PACKET(mbufs[i], 0xadadadab); 720 721 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); 722 if (result_mask != expected_mask) 723 return -13; 724 725 /* Free resources */ 726 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 727 rte_pktmbuf_free(mbufs[i]); 728 729 status = ops->f_free(table); 730 731 return 0; 732 } 733 734 static int 735 test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size) 736 { 737 int status, i; 738 uint64_t expected_mask = 0, result_mask; 739 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 740 void *table; 741 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 742 char entry; 743 int key_found; 744 void *entry_ptr; 745 746 /* Initialize params and create tables */ 747 struct rte_table_hash_params hash_params = { 748 .name = "TABLE", 749 .key_size = key_size, 750 .key_offset = APP_METADATA_OFFSET(32), 751 .key_mask = NULL, 752 .n_keys = 1 << 10, 753 .n_buckets = 1 << 10, 754 .f_hash = pipeline_test_hash, 755 .seed = 0, 756 }; 757 758 hash_params.n_keys = 0; 759 760 table = ops->f_create(&hash_params, 0, 1); 761 if (table != NULL) 762 return -1; 763 764 hash_params.n_keys = 1 << 10; 765 hash_params.key_offset = APP_METADATA_OFFSET(1); 766 767 table = ops->f_create(&hash_params, 0, 1); 768 if (table == NULL) 769 return -3; 770 771 hash_params.key_offset = APP_METADATA_OFFSET(32); 772 hash_params.f_hash = NULL; 773 774 table = ops->f_create(&hash_params, 0, 1); 775 if (table != NULL) 776 return -4; 777 778 hash_params.f_hash = pipeline_test_hash; 779 780 table = ops->f_create(&hash_params, 0, 1); 781 if (table == NULL) 782 return -5; 783 784 /* Free */ 785 status = ops->f_free(table); 786 if (status < 0) 787 return -6; 788 789 status = ops->f_free(NULL); 790 if (status == 0) 791 return -7; 792 793 /* Add */ 794 uint8_t key[32]; 795 uint32_t *k32 = (uint32_t *) &key; 796 797 memset(key, 0, 32); 798 k32[0] = rte_be_to_cpu_32(0xadadadad); 799 800 table = ops->f_create(&hash_params, 0, 1); 801 if (table == NULL) 802 return -8; 803 804 entry = 'A'; 805 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 806 if (status != 0) 807 return -9; 808 809 /* Delete */ 810 status = ops->f_delete(table, &key, &key_found, NULL); 811 if (status != 0) 812 return -10; 813 814 status = ops->f_delete(table, &key, &key_found, NULL); 815 if (status != 0) 816 return -11; 817 818 /* Traffic flow */ 819 entry = 'A'; 820 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 821 if (status < 0) 822 return -12; 823 824 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 825 if (i % 2 == 0) { 826 expected_mask |= (uint64_t)1 << i; 827 PREPARE_PACKET(mbufs[i], 0xadadadad); 828 } else 829 PREPARE_PACKET(mbufs[i], 0xadadadab); 830 831 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); 832 if (result_mask != expected_mask) 833 return -13; 834 835 /* Free resources */ 836 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 837 rte_pktmbuf_free(mbufs[i]); 838 839 status = ops->f_free(table); 840 841 return 0; 842 } 843 844 int 845 test_table_hash_lru(void) 846 { 847 int status; 848 849 status = test_table_hash_lru_generic( 850 &rte_table_hash_key8_lru_ops, 851 8); 852 if (status < 0) 853 return status; 854 855 status = test_table_hash_lru_generic( 856 &rte_table_hash_key16_lru_ops, 857 16); 858 if (status < 0) 859 return status; 860 861 status = test_table_hash_lru_generic( 862 &rte_table_hash_key32_lru_ops, 863 32); 864 if (status < 0) 865 return status; 866 867 status = test_lru_update(); 868 if (status < 0) 869 return status; 870 871 return 0; 872 } 873 874 int 875 test_table_hash_ext(void) 876 { 877 int status; 878 879 status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8); 880 if (status < 0) 881 return status; 882 883 status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16); 884 if (status < 0) 885 return status; 886 887 status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32); 888 if (status < 0) 889 return status; 890 891 return 0; 892 } 893 894 895 int 896 test_table_hash_cuckoo(void) 897 { 898 int status, i; 899 uint64_t expected_mask = 0, result_mask; 900 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 901 void *table; 902 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 903 char entry; 904 void *entry_ptr; 905 int key_found; 906 uint32_t entry_size = 1; 907 908 /* Initialize params and create tables */ 909 struct rte_table_hash_cuckoo_params cuckoo_params = { 910 .name = "TABLE", 911 .key_size = 32, 912 .key_offset = APP_METADATA_OFFSET(32), 913 .key_mask = NULL, 914 .n_keys = 1 << 16, 915 .n_buckets = 1 << 16, 916 .f_hash = pipeline_test_hash_cuckoo, 917 .seed = 0, 918 }; 919 920 table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size); 921 if (table != NULL) 922 return -1; 923 924 cuckoo_params.key_size = 0; 925 926 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 927 0, entry_size); 928 if (table != NULL) 929 return -2; 930 931 cuckoo_params.key_size = 32; 932 cuckoo_params.n_keys = 0; 933 934 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 935 0, entry_size); 936 if (table != NULL) 937 return -3; 938 939 cuckoo_params.n_keys = 1 << 24; 940 cuckoo_params.f_hash = NULL; 941 942 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 943 0, entry_size); 944 if (table != NULL) 945 return -4; 946 947 cuckoo_params.f_hash = pipeline_test_hash_cuckoo; 948 cuckoo_params.name = NULL; 949 950 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 951 0, entry_size); 952 if (table != NULL) 953 return -5; 954 955 cuckoo_params.name = "CUCKOO"; 956 957 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 958 0, entry_size); 959 if (table == NULL) 960 return -6; 961 962 /* Free */ 963 status = rte_table_hash_cuckoo_ops.f_free(table); 964 if (status < 0) 965 return -7; 966 967 status = rte_table_hash_cuckoo_ops.f_free(NULL); 968 if (status == 0) 969 return -8; 970 971 /* Add */ 972 uint8_t key_cuckoo[32]; 973 uint32_t *kcuckoo = (uint32_t *) &key_cuckoo; 974 975 memset(key_cuckoo, 0, 32); 976 kcuckoo[0] = rte_be_to_cpu_32(0xadadadad); 977 978 table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1); 979 if (table == NULL) 980 return -9; 981 982 entry = 'A'; 983 status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo, 984 &entry, &key_found, &entry_ptr); 985 if (status == 0) 986 return -10; 987 988 status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry, 989 &key_found, &entry_ptr); 990 if (status == 0) 991 return -11; 992 993 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, 994 NULL, &key_found, &entry_ptr); 995 if (status == 0) 996 return -12; 997 998 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, 999 &entry, &key_found, &entry_ptr); 1000 if (status != 0) 1001 return -13; 1002 1003 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, 1004 &entry, &key_found, &entry_ptr); 1005 if (status != 0) 1006 return -14; 1007 1008 /* Delete */ 1009 status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo, 1010 &key_found, NULL); 1011 if (status == 0) 1012 return -15; 1013 1014 status = rte_table_hash_cuckoo_ops.f_delete(table, NULL, 1015 &key_found, NULL); 1016 if (status == 0) 1017 return -16; 1018 1019 status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, 1020 &key_found, NULL); 1021 if (status != 0) 1022 return -17; 1023 1024 status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo, 1025 &key_found, NULL); 1026 if (status != -ENOENT) 1027 return -18; 1028 1029 /* Traffic flow */ 1030 entry = 'A'; 1031 status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo, 1032 &entry, &key_found, 1033 &entry_ptr); 1034 if (status < 0) 1035 return -19; 1036 1037 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 1038 if (i % 2 == 0) { 1039 expected_mask |= (uint64_t)1 << i; 1040 PREPARE_PACKET(mbufs[i], 0xadadadad); 1041 } else 1042 PREPARE_PACKET(mbufs[i], 0xadadadab); 1043 1044 rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1, 1045 &result_mask, (void **)entries); 1046 if (result_mask != expected_mask) 1047 return -20; 1048 1049 /* Free resources */ 1050 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 1051 rte_pktmbuf_free(mbufs[i]); 1052 1053 status = rte_table_hash_cuckoo_ops.f_free(table); 1054 1055 return 0; 1056 } 1057 1058 #endif /* !RTE_EXEC_ENV_WINDOWS */ 1059