xref: /f-stack/dpdk/app/test/test_table_tables.c (revision 4418919f)
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