1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <string.h> 35 #include <rte_byteorder.h> 36 #include <rte_table_lpm_ipv6.h> 37 #include <rte_lru.h> 38 #include <rte_cycles.h> 39 #include "test_table_tables.h" 40 #include "test_table.h" 41 42 table_test table_tests[] = { 43 test_table_stub, 44 test_table_array, 45 test_table_lpm, 46 test_table_lpm_ipv6, 47 test_table_hash_lru, 48 test_table_hash_ext, 49 }; 50 51 #define PREPARE_PACKET(mbuf, value) do { \ 52 uint32_t *k32, *signature; \ 53 uint8_t *key; \ 54 mbuf = rte_pktmbuf_alloc(pool); \ 55 signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, 0); \ 56 key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, 32); \ 57 memset(key, 0, 32); \ 58 k32 = (uint32_t *) key; \ 59 k32[0] = (value); \ 60 *signature = pipeline_test_hash(key, 0, 0); \ 61 } while (0) 62 63 unsigned n_table_tests = RTE_DIM(table_tests); 64 65 /* Function prototypes */ 66 static int 67 test_table_hash_lru_generic(struct rte_table_ops *ops); 68 static int 69 test_table_hash_ext_generic(struct rte_table_ops *ops); 70 71 struct rte_bucket_4_8 { 72 /* Cache line 0 */ 73 uint64_t signature; 74 uint64_t lru_list; 75 struct rte_bucket_4_8 *next; 76 uint64_t next_valid; 77 uint64_t key[4]; 78 /* Cache line 1 */ 79 uint8_t data[0]; 80 }; 81 82 #if RTE_TABLE_HASH_LRU_STRATEGY == 3 83 uint64_t shuffles = 0xfffffffdfffbfff9ULL; 84 #else 85 uint64_t shuffles = 0x0003000200010000ULL; 86 #endif 87 88 static int test_lru_update(void) 89 { 90 struct rte_bucket_4_8 b; 91 struct rte_bucket_4_8 *bucket; 92 uint32_t i; 93 uint64_t pos; 94 uint64_t iterations; 95 uint64_t j; 96 int poss; 97 98 printf("---------------------------\n"); 99 printf("Testing lru_update macro...\n"); 100 printf("---------------------------\n"); 101 bucket = &b; 102 iterations = 10; 103 #if RTE_TABLE_HASH_LRU_STRATEGY == 3 104 bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL; 105 #else 106 bucket->lru_list = 0x0000000100020003ULL; 107 #endif 108 poss = 0; 109 for (j = 0; j < iterations; j++) 110 for (i = 0; i < 9; i++) { 111 uint32_t idx = i >> 1; 112 lru_update(bucket, idx); 113 pos = lru_pos(bucket); 114 poss += pos; 115 printf("%s: %d lru_list=%016"PRIx64", upd=%d, " 116 "pos=%"PRIx64"\n", 117 __func__, i, bucket->lru_list, i>>1, pos); 118 } 119 120 if (bucket->lru_list != shuffles) { 121 printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016" 122 PRIx64"\n", 123 __func__, i, bucket->lru_list, shuffles); 124 return -1; 125 } 126 printf("%s: output checksum of results =%d\n", 127 __func__, poss); 128 #if 0 129 if (poss != 126) { 130 printf("%s: ERROR output checksum of results =%d expected %d\n", 131 __func__, poss, 126); 132 return -1; 133 } 134 #endif 135 136 fflush(stdout); 137 138 uint64_t sc_start = rte_rdtsc(); 139 iterations = 100000000; 140 poss = 0; 141 for (j = 0; j < iterations; j++) { 142 for (i = 0; i < 4; i++) { 143 lru_update(bucket, i); 144 pos |= bucket->lru_list; 145 } 146 } 147 uint64_t sc_end = rte_rdtsc(); 148 149 printf("%s: output checksum of results =%llu\n", 150 __func__, (long long unsigned int)pos); 151 printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n", 152 __func__, sc_start, sc_end); 153 printf("\nlru_update: %lu cycles per loop iteration.\n\n", 154 (long unsigned int)((sc_end-sc_start)/(iterations*4))); 155 156 return 0; 157 } 158 159 /* Table tests */ 160 int 161 test_table_stub(void) 162 { 163 int i; 164 uint64_t expected_mask = 0, result_mask; 165 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 166 void *table; 167 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 168 169 /* Create */ 170 table = rte_table_stub_ops.f_create(NULL, 0, 1); 171 if (table == NULL) 172 return -1; 173 174 /* Traffic flow */ 175 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 176 if (i % 2 == 0) 177 PREPARE_PACKET(mbufs[i], 0xadadadad); 178 else 179 PREPARE_PACKET(mbufs[i], 0xadadadab); 180 181 expected_mask = 0; 182 rte_table_stub_ops.f_lookup(table, mbufs, -1, 183 &result_mask, (void **)entries); 184 if (result_mask != expected_mask) 185 return -2; 186 187 /* Free resources */ 188 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 189 rte_pktmbuf_free(mbufs[i]); 190 191 return 0; 192 } 193 194 int 195 test_table_array(void) 196 { 197 int status, i; 198 uint64_t result_mask; 199 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 200 void *table; 201 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 202 char entry1, entry2; 203 void *entry_ptr; 204 int key_found; 205 206 /* Create */ 207 struct rte_table_array_params array_params; 208 209 table = rte_table_array_ops.f_create(NULL, 0, 1); 210 if (table != NULL) 211 return -1; 212 213 array_params.n_entries = 0; 214 215 table = rte_table_array_ops.f_create(&array_params, 0, 1); 216 if (table != NULL) 217 return -2; 218 219 array_params.n_entries = 7; 220 221 table = rte_table_array_ops.f_create(&array_params, 0, 1); 222 if (table != NULL) 223 return -3; 224 225 array_params.n_entries = 1 << 24; 226 array_params.offset = 1; 227 228 table = rte_table_array_ops.f_create(&array_params, 0, 1); 229 if (table != NULL) 230 return -4; 231 232 array_params.offset = 32; 233 234 table = rte_table_array_ops.f_create(&array_params, 0, 1); 235 if (table == NULL) 236 return -5; 237 238 /* Free */ 239 status = rte_table_array_ops.f_free(table); 240 if (status < 0) 241 return -6; 242 243 status = rte_table_array_ops.f_free(NULL); 244 if (status == 0) 245 return -7; 246 247 /* Add */ 248 struct rte_table_array_key array_key_1 = { 249 .pos = 10, 250 }; 251 struct rte_table_array_key array_key_2 = { 252 .pos = 20, 253 }; 254 entry1 = 'A'; 255 entry2 = 'B'; 256 257 table = rte_table_array_ops.f_create(&array_params, 0, 1); 258 if (table == NULL) 259 return -8; 260 261 status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1, 262 &key_found, &entry_ptr); 263 if (status == 0) 264 return -9; 265 266 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL, 267 &key_found, &entry_ptr); 268 if (status == 0) 269 return -10; 270 271 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, 272 &entry1, &key_found, &entry_ptr); 273 if (status != 0) 274 return -11; 275 276 /* Traffic flow */ 277 status = rte_table_array_ops.f_add(table, (void *) &array_key_2, 278 &entry2, &key_found, &entry_ptr); 279 if (status != 0) 280 return -12; 281 282 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 283 if (i % 2 == 0) 284 PREPARE_PACKET(mbufs[i], 10); 285 else 286 PREPARE_PACKET(mbufs[i], 20); 287 288 rte_table_array_ops.f_lookup(table, mbufs, -1, 289 &result_mask, (void **)entries); 290 291 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 292 if (i % 2 == 0 && *entries[i] != 'A') 293 return -13; 294 else 295 if (i % 2 == 1 && *entries[i] != 'B') 296 return -13; 297 298 /* Free resources */ 299 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 300 rte_pktmbuf_free(mbufs[i]); 301 302 status = rte_table_array_ops.f_free(table); 303 304 return 0; 305 } 306 307 int 308 test_table_lpm(void) 309 { 310 int status, i; 311 uint64_t expected_mask = 0, result_mask; 312 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 313 void *table; 314 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 315 char entry; 316 void *entry_ptr; 317 int key_found; 318 uint32_t entry_size = 1; 319 320 /* Create */ 321 struct rte_table_lpm_params lpm_params; 322 323 table = rte_table_lpm_ops.f_create(NULL, 0, entry_size); 324 if (table != NULL) 325 return -1; 326 327 lpm_params.n_rules = 0; 328 329 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 330 if (table != NULL) 331 return -2; 332 333 lpm_params.n_rules = 1 << 24; 334 lpm_params.offset = 1; 335 336 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 337 if (table != NULL) 338 return -3; 339 340 lpm_params.offset = 32; 341 lpm_params.entry_unique_size = 0; 342 343 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 344 if (table != NULL) 345 return -4; 346 347 lpm_params.entry_unique_size = entry_size + 1; 348 349 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 350 if (table != NULL) 351 return -5; 352 353 lpm_params.entry_unique_size = entry_size; 354 355 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); 356 if (table == NULL) 357 return -6; 358 359 /* Free */ 360 status = rte_table_lpm_ops.f_free(table); 361 if (status < 0) 362 return -7; 363 364 status = rte_table_lpm_ops.f_free(NULL); 365 if (status == 0) 366 return -8; 367 368 /* Add */ 369 struct rte_table_lpm_key lpm_key; 370 lpm_key.ip = 0xadadadad; 371 372 table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1); 373 if (table == NULL) 374 return -9; 375 376 status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found, 377 &entry_ptr); 378 if (status == 0) 379 return -10; 380 381 status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found, 382 &entry_ptr); 383 if (status == 0) 384 return -11; 385 386 status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found, 387 &entry_ptr); 388 if (status == 0) 389 return -12; 390 391 lpm_key.depth = 0; 392 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 393 &entry_ptr); 394 if (status == 0) 395 return -13; 396 397 lpm_key.depth = 33; 398 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 399 &entry_ptr); 400 if (status == 0) 401 return -14; 402 403 lpm_key.depth = 16; 404 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 405 &entry_ptr); 406 if (status != 0) 407 return -15; 408 409 /* Delete */ 410 status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL); 411 if (status == 0) 412 return -16; 413 414 status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL); 415 if (status == 0) 416 return -17; 417 418 lpm_key.depth = 0; 419 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 420 if (status == 0) 421 return -18; 422 423 lpm_key.depth = 33; 424 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 425 if (status == 0) 426 return -19; 427 428 lpm_key.depth = 16; 429 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 430 if (status != 0) 431 return -20; 432 433 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL); 434 if (status != 0) 435 return -21; 436 437 /* Traffic flow */ 438 entry = 'A'; 439 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found, 440 &entry_ptr); 441 if (status < 0) 442 return -22; 443 444 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 445 if (i % 2 == 0) { 446 expected_mask |= (uint64_t)1 << i; 447 PREPARE_PACKET(mbufs[i], 0xadadadad); 448 } else 449 PREPARE_PACKET(mbufs[i], 0xadadadab); 450 451 rte_table_lpm_ops.f_lookup(table, mbufs, -1, 452 &result_mask, (void **)entries); 453 if (result_mask != expected_mask) 454 return -21; 455 456 /* Free resources */ 457 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 458 rte_pktmbuf_free(mbufs[i]); 459 460 status = rte_table_lpm_ops.f_free(table); 461 462 return 0; 463 } 464 465 int 466 test_table_lpm_ipv6(void) 467 { 468 int status, i; 469 uint64_t expected_mask = 0, result_mask; 470 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 471 void *table; 472 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 473 char entry; 474 void *entry_ptr; 475 int key_found; 476 uint32_t entry_size = 1; 477 478 /* Create */ 479 struct rte_table_lpm_ipv6_params lpm_params; 480 481 table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size); 482 if (table != NULL) 483 return -1; 484 485 lpm_params.n_rules = 0; 486 487 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 488 if (table != NULL) 489 return -2; 490 491 lpm_params.n_rules = 1 << 24; 492 lpm_params.number_tbl8s = 0; 493 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 494 if (table != NULL) 495 return -2; 496 497 lpm_params.number_tbl8s = 1 << 21; 498 lpm_params.entry_unique_size = 0; 499 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 500 if (table != NULL) 501 return -2; 502 503 lpm_params.entry_unique_size = entry_size + 1; 504 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 505 if (table != NULL) 506 return -2; 507 508 lpm_params.entry_unique_size = entry_size; 509 lpm_params.offset = 32; 510 511 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 512 if (table == NULL) 513 return -3; 514 515 /* Free */ 516 status = rte_table_lpm_ipv6_ops.f_free(table); 517 if (status < 0) 518 return -4; 519 520 status = rte_table_lpm_ipv6_ops.f_free(NULL); 521 if (status == 0) 522 return -5; 523 524 /* Add */ 525 struct rte_table_lpm_ipv6_key lpm_key; 526 527 lpm_key.ip[0] = 0xad; 528 lpm_key.ip[1] = 0xad; 529 lpm_key.ip[2] = 0xad; 530 lpm_key.ip[3] = 0xad; 531 532 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size); 533 if (table == NULL) 534 return -6; 535 536 status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry, 537 &key_found, &entry_ptr); 538 if (status == 0) 539 return -7; 540 541 status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found, 542 &entry_ptr); 543 if (status == 0) 544 return -8; 545 546 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found, 547 &entry_ptr); 548 if (status == 0) 549 return -9; 550 551 lpm_key.depth = 0; 552 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 553 &key_found, &entry_ptr); 554 if (status == 0) 555 return -10; 556 557 lpm_key.depth = 129; 558 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 559 &key_found, &entry_ptr); 560 if (status == 0) 561 return -11; 562 563 lpm_key.depth = 16; 564 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 565 &key_found, &entry_ptr); 566 if (status != 0) 567 return -12; 568 569 /* Delete */ 570 status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found, 571 NULL); 572 if (status == 0) 573 return -13; 574 575 status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL); 576 if (status == 0) 577 return -14; 578 579 lpm_key.depth = 0; 580 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 581 NULL); 582 if (status == 0) 583 return -15; 584 585 lpm_key.depth = 129; 586 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 587 NULL); 588 if (status == 0) 589 return -16; 590 591 lpm_key.depth = 16; 592 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 593 NULL); 594 if (status != 0) 595 return -17; 596 597 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found, 598 NULL); 599 if (status != 0) 600 return -18; 601 602 /* Traffic flow */ 603 entry = 'A'; 604 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry, 605 &key_found, &entry_ptr); 606 if (status < 0) 607 return -19; 608 609 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 610 if (i % 2 == 0) { 611 expected_mask |= (uint64_t)1 << i; 612 PREPARE_PACKET(mbufs[i], 0xadadadad); 613 } else 614 PREPARE_PACKET(mbufs[i], 0xadadadab); 615 616 rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1, 617 &result_mask, (void **)entries); 618 if (result_mask != expected_mask) 619 return -20; 620 621 /* Free resources */ 622 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 623 rte_pktmbuf_free(mbufs[i]); 624 625 status = rte_table_lpm_ipv6_ops.f_free(table); 626 627 return 0; 628 } 629 630 static int 631 test_table_hash_lru_generic(struct rte_table_ops *ops) 632 { 633 int status, i; 634 uint64_t expected_mask = 0, result_mask; 635 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 636 void *table; 637 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 638 char entry; 639 void *entry_ptr; 640 int key_found; 641 642 /* Create */ 643 struct rte_table_hash_key8_lru_params hash_params; 644 645 hash_params.n_entries = 0; 646 647 table = ops->f_create(&hash_params, 0, 1); 648 if (table != NULL) 649 return -1; 650 651 hash_params.n_entries = 1 << 10; 652 hash_params.signature_offset = 1; 653 654 table = ops->f_create(&hash_params, 0, 1); 655 if (table != NULL) 656 return -2; 657 658 hash_params.signature_offset = 0; 659 hash_params.key_offset = 1; 660 661 table = ops->f_create(&hash_params, 0, 1); 662 if (table != NULL) 663 return -3; 664 665 hash_params.key_offset = 32; 666 hash_params.f_hash = NULL; 667 668 table = ops->f_create(&hash_params, 0, 1); 669 if (table != NULL) 670 return -4; 671 672 hash_params.f_hash = pipeline_test_hash; 673 674 table = ops->f_create(&hash_params, 0, 1); 675 if (table == NULL) 676 return -5; 677 678 /* Free */ 679 status = ops->f_free(table); 680 if (status < 0) 681 return -6; 682 683 status = ops->f_free(NULL); 684 if (status == 0) 685 return -7; 686 687 /* Add */ 688 uint8_t key[32]; 689 uint32_t *k32 = (uint32_t *) &key; 690 691 memset(key, 0, 32); 692 k32[0] = rte_be_to_cpu_32(0xadadadad); 693 694 table = ops->f_create(&hash_params, 0, 1); 695 if (table == NULL) 696 return -8; 697 698 entry = 'A'; 699 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 700 if (status != 0) 701 return -9; 702 703 /* Delete */ 704 status = ops->f_delete(table, &key, &key_found, NULL); 705 if (status != 0) 706 return -10; 707 708 status = ops->f_delete(table, &key, &key_found, NULL); 709 if (status != 0) 710 return -11; 711 712 /* Traffic flow */ 713 entry = 'A'; 714 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 715 if (status < 0) 716 return -12; 717 718 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 719 if (i % 2 == 0) { 720 expected_mask |= (uint64_t)1 << i; 721 PREPARE_PACKET(mbufs[i], 0xadadadad); 722 } else 723 PREPARE_PACKET(mbufs[i], 0xadadadab); 724 725 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); 726 if (result_mask != expected_mask) 727 return -13; 728 729 /* Free resources */ 730 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 731 rte_pktmbuf_free(mbufs[i]); 732 733 status = ops->f_free(table); 734 735 return 0; 736 } 737 738 static int 739 test_table_hash_ext_generic(struct rte_table_ops *ops) 740 { 741 int status, i; 742 uint64_t expected_mask = 0, result_mask; 743 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; 744 void *table; 745 char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; 746 char entry; 747 int key_found; 748 void *entry_ptr; 749 750 /* Create */ 751 struct rte_table_hash_key8_ext_params hash_params; 752 753 hash_params.n_entries = 0; 754 755 table = ops->f_create(&hash_params, 0, 1); 756 if (table != NULL) 757 return -1; 758 759 hash_params.n_entries = 1 << 10; 760 hash_params.n_entries_ext = 0; 761 table = ops->f_create(&hash_params, 0, 1); 762 if (table != NULL) 763 return -2; 764 765 hash_params.n_entries_ext = 1 << 4; 766 hash_params.signature_offset = 1; 767 table = ops->f_create(&hash_params, 0, 1); 768 if (table != NULL) 769 return -2; 770 771 hash_params.signature_offset = 0; 772 hash_params.key_offset = 1; 773 774 table = ops->f_create(&hash_params, 0, 1); 775 if (table != NULL) 776 return -3; 777 778 hash_params.key_offset = 32; 779 hash_params.f_hash = NULL; 780 781 table = ops->f_create(&hash_params, 0, 1); 782 if (table != NULL) 783 return -4; 784 785 hash_params.f_hash = pipeline_test_hash; 786 787 table = ops->f_create(&hash_params, 0, 1); 788 if (table == NULL) 789 return -5; 790 791 /* Free */ 792 status = ops->f_free(table); 793 if (status < 0) 794 return -6; 795 796 status = ops->f_free(NULL); 797 if (status == 0) 798 return -7; 799 800 /* Add */ 801 uint8_t key[32]; 802 uint32_t *k32 = (uint32_t *) &key; 803 804 memset(key, 0, 32); 805 k32[0] = rte_be_to_cpu_32(0xadadadad); 806 807 table = ops->f_create(&hash_params, 0, 1); 808 if (table == NULL) 809 return -8; 810 811 entry = 'A'; 812 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 813 if (status != 0) 814 return -9; 815 816 /* Delete */ 817 status = ops->f_delete(table, &key, &key_found, NULL); 818 if (status != 0) 819 return -10; 820 821 status = ops->f_delete(table, &key, &key_found, NULL); 822 if (status != 0) 823 return -11; 824 825 /* Traffic flow */ 826 entry = 'A'; 827 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr); 828 if (status < 0) 829 return -12; 830 831 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 832 if (i % 2 == 0) { 833 expected_mask |= (uint64_t)1 << i; 834 PREPARE_PACKET(mbufs[i], 0xadadadad); 835 } else 836 PREPARE_PACKET(mbufs[i], 0xadadadab); 837 838 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries); 839 if (result_mask != expected_mask) 840 return -13; 841 842 /* Free resources */ 843 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) 844 rte_pktmbuf_free(mbufs[i]); 845 846 status = ops->f_free(table); 847 848 return 0; 849 } 850 851 int 852 test_table_hash_lru(void) 853 { 854 int status; 855 856 status = test_table_hash_lru_generic(&rte_table_hash_key8_lru_ops); 857 if (status < 0) 858 return status; 859 860 status = test_table_hash_lru_generic( 861 &rte_table_hash_key8_lru_dosig_ops); 862 if (status < 0) 863 return status; 864 865 status = test_table_hash_lru_generic(&rte_table_hash_key16_lru_ops); 866 if (status < 0) 867 return status; 868 869 status = test_table_hash_lru_generic(&rte_table_hash_key32_lru_ops); 870 if (status < 0) 871 return status; 872 873 status = test_lru_update(); 874 if (status < 0) 875 return status; 876 877 return 0; 878 } 879 880 int 881 test_table_hash_ext(void) 882 { 883 int status; 884 885 status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops); 886 if (status < 0) 887 return status; 888 889 status = test_table_hash_ext_generic( 890 &rte_table_hash_key8_ext_dosig_ops); 891 if (status < 0) 892 return status; 893 894 status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops); 895 if (status < 0) 896 return status; 897 898 status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops); 899 if (status < 0) 900 return status; 901 902 return 0; 903 } 904