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