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