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