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 .number_tbl8s = 1 << 8,
331 .entry_unique_size = entry_size,
332 .offset = APP_METADATA_OFFSET(1)
335 table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
339 lpm_params.name = NULL;
341 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
345 lpm_params.name = "LPM";
346 lpm_params.n_rules = 0;
348 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
352 lpm_params.n_rules = 1 << 24;
353 lpm_params.offset = APP_METADATA_OFFSET(32);
354 lpm_params.entry_unique_size = 0;
356 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
360 lpm_params.entry_unique_size = entry_size + 1;
362 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
366 lpm_params.entry_unique_size = entry_size;
368 table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
373 status = rte_table_lpm_ops.f_free(table);
377 status = rte_table_lpm_ops.f_free(NULL);
382 struct rte_table_lpm_key lpm_key;
383 lpm_key.ip = 0xadadadad;
385 table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1);
389 status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
394 status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
399 status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
405 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
411 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
417 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
423 status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
427 status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
432 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
437 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
442 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
446 status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
452 status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
457 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
459 expected_mask |= (uint64_t)1 << i;
460 PREPARE_PACKET(mbufs[i], 0xadadadad);
462 PREPARE_PACKET(mbufs[i], 0xadadadab);
464 rte_table_lpm_ops.f_lookup(table, mbufs, -1,
465 &result_mask, (void **)entries);
466 if (result_mask != expected_mask)
470 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
471 rte_pktmbuf_free(mbufs[i]);
473 status = rte_table_lpm_ops.f_free(table);
479 test_table_lpm_ipv6(void)
482 uint64_t expected_mask = 0, result_mask;
483 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
485 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
489 uint32_t entry_size = 1;
491 /* Initialize params and create tables */
492 struct rte_table_lpm_ipv6_params lpm_params = {
495 .number_tbl8s = 1 << 21,
496 .entry_unique_size = entry_size,
497 .offset = APP_METADATA_OFFSET(32)
500 table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
504 lpm_params.name = NULL;
506 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
510 lpm_params.name = "LPM";
511 lpm_params.n_rules = 0;
513 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
517 lpm_params.n_rules = 1 << 24;
518 lpm_params.number_tbl8s = 0;
519 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
523 lpm_params.number_tbl8s = 1 << 21;
524 lpm_params.entry_unique_size = 0;
525 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
529 lpm_params.entry_unique_size = entry_size + 1;
530 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
534 lpm_params.entry_unique_size = entry_size;
535 lpm_params.offset = APP_METADATA_OFFSET(32);
537 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
542 status = rte_table_lpm_ipv6_ops.f_free(table);
546 status = rte_table_lpm_ipv6_ops.f_free(NULL);
551 struct rte_table_lpm_ipv6_key lpm_key;
553 lpm_key.ip[0] = 0xad;
554 lpm_key.ip[1] = 0xad;
555 lpm_key.ip[2] = 0xad;
556 lpm_key.ip[3] = 0xad;
558 table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
562 status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
563 &key_found, &entry_ptr);
567 status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
572 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
578 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
579 &key_found, &entry_ptr);
584 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
585 &key_found, &entry_ptr);
590 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
591 &key_found, &entry_ptr);
596 status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
601 status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
606 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
612 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
618 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
623 status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
630 status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
631 &key_found, &entry_ptr);
635 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
637 expected_mask |= (uint64_t)1 << i;
638 PREPARE_PACKET(mbufs[i], 0xadadadad);
640 PREPARE_PACKET(mbufs[i], 0xadadadab);
642 rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
643 &result_mask, (void **)entries);
644 if (result_mask != expected_mask)
648 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
649 rte_pktmbuf_free(mbufs[i]);
651 status = rte_table_lpm_ipv6_ops.f_free(table);
657 test_table_hash_lru_generic(struct rte_table_ops *ops)
660 uint64_t expected_mask = 0, result_mask;
661 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
663 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
668 /* Initialize params and create tables */
669 struct rte_table_hash_key8_lru_params hash_params = {
670 .n_entries = 1 << 10,
671 .f_hash = pipeline_test_hash,
673 .signature_offset = APP_METADATA_OFFSET(1),
674 .key_offset = APP_METADATA_OFFSET(32),
678 hash_params.n_entries = 0;
680 table = ops->f_create(&hash_params, 0, 1);
684 hash_params.n_entries = 1 << 10;
685 hash_params.signature_offset = APP_METADATA_OFFSET(1);
687 table = ops->f_create(&hash_params, 0, 1);
691 hash_params.signature_offset = APP_METADATA_OFFSET(0);
692 hash_params.key_offset = APP_METADATA_OFFSET(1);
694 table = ops->f_create(&hash_params, 0, 1);
698 hash_params.key_offset = APP_METADATA_OFFSET(32);
699 hash_params.f_hash = NULL;
701 table = ops->f_create(&hash_params, 0, 1);
705 hash_params.f_hash = pipeline_test_hash;
707 table = ops->f_create(&hash_params, 0, 1);
712 status = ops->f_free(table);
716 status = ops->f_free(NULL);
722 uint32_t *k32 = (uint32_t *) &key;
725 k32[0] = rte_be_to_cpu_32(0xadadadad);
727 table = ops->f_create(&hash_params, 0, 1);
732 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
737 status = ops->f_delete(table, &key, &key_found, NULL);
741 status = ops->f_delete(table, &key, &key_found, NULL);
747 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
751 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
753 expected_mask |= (uint64_t)1 << i;
754 PREPARE_PACKET(mbufs[i], 0xadadadad);
756 PREPARE_PACKET(mbufs[i], 0xadadadab);
758 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
759 if (result_mask != expected_mask)
763 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
764 rte_pktmbuf_free(mbufs[i]);
766 status = ops->f_free(table);
772 test_table_hash_ext_generic(struct rte_table_ops *ops)
775 uint64_t expected_mask = 0, result_mask;
776 struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
778 char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
783 /* Initialize params and create tables */
784 struct rte_table_hash_key8_ext_params hash_params = {
785 .n_entries = 1 << 10,
786 .n_entries_ext = 1 << 4,
787 .f_hash = pipeline_test_hash,
789 .signature_offset = APP_METADATA_OFFSET(1),
790 .key_offset = APP_METADATA_OFFSET(32),
794 hash_params.n_entries = 0;
796 table = ops->f_create(&hash_params, 0, 1);
800 hash_params.n_entries = 1 << 10;
801 hash_params.n_entries_ext = 0;
802 table = ops->f_create(&hash_params, 0, 1);
806 hash_params.n_entries_ext = 1 << 4;
807 hash_params.signature_offset = APP_METADATA_OFFSET(1);
808 table = ops->f_create(&hash_params, 0, 1);
812 hash_params.signature_offset = APP_METADATA_OFFSET(0);
813 hash_params.key_offset = APP_METADATA_OFFSET(1);
815 table = ops->f_create(&hash_params, 0, 1);
819 hash_params.key_offset = APP_METADATA_OFFSET(32);
820 hash_params.f_hash = NULL;
822 table = ops->f_create(&hash_params, 0, 1);
826 hash_params.f_hash = pipeline_test_hash;
828 table = ops->f_create(&hash_params, 0, 1);
833 status = ops->f_free(table);
837 status = ops->f_free(NULL);
843 uint32_t *k32 = (uint32_t *) &key;
846 k32[0] = rte_be_to_cpu_32(0xadadadad);
848 table = ops->f_create(&hash_params, 0, 1);
853 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
858 status = ops->f_delete(table, &key, &key_found, NULL);
862 status = ops->f_delete(table, &key, &key_found, NULL);
868 status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
872 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
874 expected_mask |= (uint64_t)1 << i;
875 PREPARE_PACKET(mbufs[i], 0xadadadad);
877 PREPARE_PACKET(mbufs[i], 0xadadadab);
879 ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
880 if (result_mask != expected_mask)
884 for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
885 rte_pktmbuf_free(mbufs[i]);
887 status = ops->f_free(table);
893 test_table_hash_lru(void)
897 status = test_table_hash_lru_generic(&rte_table_hash_key8_lru_ops);
901 status = test_table_hash_lru_generic(
902 &rte_table_hash_key8_lru_dosig_ops);
906 status = test_table_hash_lru_generic(&rte_table_hash_key16_lru_ops);
910 status = test_table_hash_lru_generic(&rte_table_hash_key32_lru_ops);
914 status = test_lru_update();
922 test_table_hash_ext(void)
926 status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops);
930 status = test_table_hash_ext_generic(
931 &rte_table_hash_key8_ext_dosig_ops);
935 status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops);
939 status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops);