4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
35 #include <rte_byteorder.h>
36 #include <rte_table_lpm_ipv6.h>
38 #include <rte_cycles.h>
39 #include "test_table_tables.h"
40 #include "test_table.h"
42 table_test table_tests[] = {
51 #define PREPARE_PACKET(mbuf, value) do { \
52 uint32_t *k32, *signature; \
54 mbuf = rte_pktmbuf_alloc(pool); \
55 signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
56 APP_METADATA_OFFSET(0)); \
57 key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
58 APP_METADATA_OFFSET(32)); \
60 k32 = (uint32_t *) key; \
62 *signature = pipeline_test_hash(key, 0, 0); \
65 unsigned n_table_tests = RTE_DIM(table_tests);
67 /* Function prototypes */
69 test_table_hash_lru_generic(struct rte_table_ops *ops);
71 test_table_hash_ext_generic(struct rte_table_ops *ops);
73 struct rte_bucket_4_8 {
77 struct rte_bucket_4_8 *next;
84 #if RTE_TABLE_HASH_LRU_STRATEGY == 3
85 uint64_t shuffles = 0xfffffffdfffbfff9ULL;
87 uint64_t shuffles = 0x0003000200010000ULL;
90 static int test_lru_update(void)
92 struct rte_bucket_4_8 b;
93 struct rte_bucket_4_8 *bucket;
100 printf("---------------------------\n");
101 printf("Testing lru_update macro...\n");
102 printf("---------------------------\n");
105 #if RTE_TABLE_HASH_LRU_STRATEGY == 3
106 bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
108 bucket->lru_list = 0x0000000100020003ULL;
111 for (j = 0; j < iterations; j++)
112 for (i = 0; i < 9; i++) {
113 uint32_t idx = i >> 1;
114 lru_update(bucket, idx);
115 pos = lru_pos(bucket);
117 printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
119 __func__, i, bucket->lru_list, i>>1, pos);
122 if (bucket->lru_list != shuffles) {
123 printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
125 __func__, i, bucket->lru_list, shuffles);
128 printf("%s: output checksum of results =%d\n",
132 printf("%s: ERROR output checksum of results =%d expected %d\n",
133 __func__, poss, 126);
140 uint64_t sc_start = rte_rdtsc();
141 iterations = 100000000;
143 for (j = 0; j < iterations; j++) {
144 for (i = 0; i < 4; i++) {
145 lru_update(bucket, i);
146 pos |= bucket->lru_list;
149 uint64_t sc_end = rte_rdtsc();
151 printf("%s: output checksum of results =%llu\n",
152 __func__, (long long unsigned int)pos);
153 printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
154 __func__, sc_start, sc_end);
155 printf("\nlru_update: %lu cycles per loop iteration.\n\n",
156 (long unsigned int)((sc_end-sc_start)/(iterations*4)));
163 test_table_stub(void)
166 uint64_t expected_mask = 0, result_mask;
167 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
169 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
172 table = rte_table_stub_ops.f_create(NULL, 0, 1);
177 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
179 PREPARE_PACKET(mbufs[i], 0xadadadad);
181 PREPARE_PACKET(mbufs[i], 0xadadadab);
184 rte_table_stub_ops.f_lookup(table, mbufs, -1,
185 &result_mask, (void **)entries);
186 if (result_mask != expected_mask)
190 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
191 rte_pktmbuf_free(mbufs[i]);
197 test_table_array(void)
200 uint64_t result_mask;
201 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
203 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
208 /* Initialize params and create tables */
209 struct rte_table_array_params array_params = {
211 .offset = APP_METADATA_OFFSET(1)
214 table = rte_table_array_ops.f_create(NULL, 0, 1);
218 array_params.n_entries = 0;
220 table = rte_table_array_ops.f_create(&array_params, 0, 1);
224 array_params.n_entries = 7;
226 table = rte_table_array_ops.f_create(&array_params, 0, 1);
230 array_params.n_entries = 1 << 24;
231 array_params.offset = APP_METADATA_OFFSET(1);
233 table = rte_table_array_ops.f_create(&array_params, 0, 1);
237 array_params.offset = APP_METADATA_OFFSET(32);
239 table = rte_table_array_ops.f_create(&array_params, 0, 1);
244 status = rte_table_array_ops.f_free(table);
248 status = rte_table_array_ops.f_free(NULL);
253 struct rte_table_array_key array_key_1 = {
256 struct rte_table_array_key array_key_2 = {
262 table = rte_table_array_ops.f_create(&array_params, 0, 1);
266 status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
267 &key_found, &entry_ptr);
271 status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
272 &key_found, &entry_ptr);
276 status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
277 &entry1, &key_found, &entry_ptr);
282 status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
283 &entry2, &key_found, &entry_ptr);
287 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
289 PREPARE_PACKET(mbufs[i], 10);
291 PREPARE_PACKET(mbufs[i], 20);
293 rte_table_array_ops.f_lookup(table, mbufs, -1,
294 &result_mask, (void **)entries);
296 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
297 if (i % 2 == 0 && *entries[i] != 'A')
300 if (i % 2 == 1 && *entries[i] != 'B')
304 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
305 rte_pktmbuf_free(mbufs[i]);
307 status = rte_table_array_ops.f_free(table);
316 uint64_t expected_mask = 0, result_mask;
317 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
319 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
323 uint32_t entry_size = 1;
325 /* Initialize params and create tables */
326 struct rte_table_lpm_params lpm_params = {
329 .entry_unique_size = entry_size,
330 .offset = APP_METADATA_OFFSET(1)
333 table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
337 lpm_params.name = NULL;
339 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
343 lpm_params.name = "LPM";
344 lpm_params.n_rules = 0;
346 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
350 lpm_params.n_rules = 1 << 24;
351 lpm_params.offset = APP_METADATA_OFFSET(32);
352 lpm_params.entry_unique_size = 0;
354 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
358 lpm_params.entry_unique_size = entry_size + 1;
360 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
364 lpm_params.entry_unique_size = entry_size;
366 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
371 status = rte_table_lpm_ops.f_free(table);
375 status = rte_table_lpm_ops.f_free(NULL);
380 struct rte_table_lpm_key lpm_key;
381 lpm_key.ip = 0xadadadad;
383 table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1);
387 status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
392 status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
397 status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
403 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
409 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
415 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
421 status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
425 status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
430 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
435 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
440 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
444 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
450 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
455 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
457 expected_mask |= (uint64_t)1 << i;
458 PREPARE_PACKET(mbufs[i], 0xadadadad);
460 PREPARE_PACKET(mbufs[i], 0xadadadab);
462 rte_table_lpm_ops.f_lookup(table, mbufs, -1,
463 &result_mask, (void **)entries);
464 if (result_mask != expected_mask)
468 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
469 rte_pktmbuf_free(mbufs[i]);
471 status = rte_table_lpm_ops.f_free(table);
477 test_table_lpm_ipv6(void)
480 uint64_t expected_mask = 0, result_mask;
481 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
483 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
487 uint32_t entry_size = 1;
489 /* Initialize params and create tables */
490 struct rte_table_lpm_ipv6_params lpm_params = {
493 .number_tbl8s = 1 << 21,
494 .entry_unique_size = entry_size,
495 .offset = APP_METADATA_OFFSET(32)
498 table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
502 lpm_params.name = NULL;
504 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
508 lpm_params.name = "LPM";
509 lpm_params.n_rules = 0;
511 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
515 lpm_params.n_rules = 1 << 24;
516 lpm_params.number_tbl8s = 0;
517 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
521 lpm_params.number_tbl8s = 1 << 21;
522 lpm_params.entry_unique_size = 0;
523 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
527 lpm_params.entry_unique_size = entry_size + 1;
528 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
532 lpm_params.entry_unique_size = entry_size;
533 lpm_params.offset = APP_METADATA_OFFSET(32);
535 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
540 status = rte_table_lpm_ipv6_ops.f_free(table);
544 status = rte_table_lpm_ipv6_ops.f_free(NULL);
549 struct rte_table_lpm_ipv6_key lpm_key;
551 lpm_key.ip[0] = 0xad;
552 lpm_key.ip[1] = 0xad;
553 lpm_key.ip[2] = 0xad;
554 lpm_key.ip[3] = 0xad;
556 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
560 status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
561 &key_found, &entry_ptr);
565 status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
570 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
576 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
577 &key_found, &entry_ptr);
582 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
583 &key_found, &entry_ptr);
588 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
589 &key_found, &entry_ptr);
594 status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
599 status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
604 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
610 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
616 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
621 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
628 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
629 &key_found, &entry_ptr);
633 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
635 expected_mask |= (uint64_t)1 << i;
636 PREPARE_PACKET(mbufs[i], 0xadadadad);
638 PREPARE_PACKET(mbufs[i], 0xadadadab);
640 rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
641 &result_mask, (void **)entries);
642 if (result_mask != expected_mask)
646 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
647 rte_pktmbuf_free(mbufs[i]);
649 status = rte_table_lpm_ipv6_ops.f_free(table);
655 test_table_hash_lru_generic(struct rte_table_ops *ops)
658 uint64_t expected_mask = 0, result_mask;
659 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
661 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
666 /* Initialize params and create tables */
667 struct rte_table_hash_key8_lru_params hash_params = {
668 .n_entries = 1 << 10,
669 .f_hash = pipeline_test_hash,
671 .signature_offset = APP_METADATA_OFFSET(1),
672 .key_offset = APP_METADATA_OFFSET(32),
676 hash_params.n_entries = 0;
678 table = ops->f_create(&hash_params, 0, 1);
682 hash_params.n_entries = 1 << 10;
683 hash_params.signature_offset = APP_METADATA_OFFSET(1);
685 table = ops->f_create(&hash_params, 0, 1);
689 hash_params.signature_offset = APP_METADATA_OFFSET(0);
690 hash_params.key_offset = APP_METADATA_OFFSET(1);
692 table = ops->f_create(&hash_params, 0, 1);
696 hash_params.key_offset = APP_METADATA_OFFSET(32);
697 hash_params.f_hash = NULL;
699 table = ops->f_create(&hash_params, 0, 1);
703 hash_params.f_hash = pipeline_test_hash;
705 table = ops->f_create(&hash_params, 0, 1);
710 status = ops->f_free(table);
714 status = ops->f_free(NULL);
720 uint32_t *k32 = (uint32_t *) &key;
723 k32[0] = rte_be_to_cpu_32(0xadadadad);
725 table = ops->f_create(&hash_params, 0, 1);
730 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
735 status = ops->f_delete(table, &key, &key_found, NULL);
739 status = ops->f_delete(table, &key, &key_found, NULL);
745 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
749 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
751 expected_mask |= (uint64_t)1 << i;
752 PREPARE_PACKET(mbufs[i], 0xadadadad);
754 PREPARE_PACKET(mbufs[i], 0xadadadab);
756 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
757 if (result_mask != expected_mask)
761 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
762 rte_pktmbuf_free(mbufs[i]);
764 status = ops->f_free(table);
770 test_table_hash_ext_generic(struct rte_table_ops *ops)
773 uint64_t expected_mask = 0, result_mask;
774 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
776 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
781 /* Initialize params and create tables */
782 struct rte_table_hash_key8_ext_params hash_params = {
783 .n_entries = 1 << 10,
784 .n_entries_ext = 1 << 4,
785 .f_hash = pipeline_test_hash,
787 .signature_offset = APP_METADATA_OFFSET(1),
788 .key_offset = APP_METADATA_OFFSET(32),
792 hash_params.n_entries = 0;
794 table = ops->f_create(&hash_params, 0, 1);
798 hash_params.n_entries = 1 << 10;
799 hash_params.n_entries_ext = 0;
800 table = ops->f_create(&hash_params, 0, 1);
804 hash_params.n_entries_ext = 1 << 4;
805 hash_params.signature_offset = APP_METADATA_OFFSET(1);
806 table = ops->f_create(&hash_params, 0, 1);
810 hash_params.signature_offset = APP_METADATA_OFFSET(0);
811 hash_params.key_offset = APP_METADATA_OFFSET(1);
813 table = ops->f_create(&hash_params, 0, 1);
817 hash_params.key_offset = APP_METADATA_OFFSET(32);
818 hash_params.f_hash = NULL;
820 table = ops->f_create(&hash_params, 0, 1);
824 hash_params.f_hash = pipeline_test_hash;
826 table = ops->f_create(&hash_params, 0, 1);
831 status = ops->f_free(table);
835 status = ops->f_free(NULL);
841 uint32_t *k32 = (uint32_t *) &key;
844 k32[0] = rte_be_to_cpu_32(0xadadadad);
846 table = ops->f_create(&hash_params, 0, 1);
851 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
856 status = ops->f_delete(table, &key, &key_found, NULL);
860 status = ops->f_delete(table, &key, &key_found, NULL);
866 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
870 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
872 expected_mask |= (uint64_t)1 << i;
873 PREPARE_PACKET(mbufs[i], 0xadadadad);
875 PREPARE_PACKET(mbufs[i], 0xadadadab);
877 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
878 if (result_mask != expected_mask)
882 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
883 rte_pktmbuf_free(mbufs[i]);
885 status = ops->f_free(table);
891 test_table_hash_lru(void)
895 status = test_table_hash_lru_generic(&rte_table_hash_key8_lru_ops);
899 status = test_table_hash_lru_generic(
900 &rte_table_hash_key8_lru_dosig_ops);
904 status = test_table_hash_lru_generic(&rte_table_hash_key16_lru_ops);
908 status = test_table_hash_lru_generic(&rte_table_hash_key32_lru_ops);
912 status = test_lru_update();
920 test_table_hash_ext(void)
924 status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops);
928 status = test_table_hash_ext_generic(
929 &rte_table_hash_key8_ext_dosig_ops);
933 status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops);
937 status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops);