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