Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include "test.h"
6 : :
7 : : #include <stdio.h>
8 : : #include <stdint.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : :
12 : : #include <rte_memory.h>
13 : : #include <rte_lpm6.h>
14 : :
15 : : #include "test_lpm6_data.h"
16 : :
17 : : #define TEST_LPM_ASSERT(cond) do { \
18 : : if (!(cond)) { \
19 : : printf("Error at line %d: \n", __LINE__); \
20 : : return -1; \
21 : : } \
22 : : } while(0)
23 : :
24 : : typedef int32_t (* rte_lpm6_test)(void);
25 : :
26 : : static int32_t test0(void);
27 : : static int32_t test1(void);
28 : : static int32_t test2(void);
29 : : static int32_t test3(void);
30 : : static int32_t test4(void);
31 : : static int32_t test5(void);
32 : : static int32_t test6(void);
33 : : static int32_t test7(void);
34 : : static int32_t test8(void);
35 : : static int32_t test9(void);
36 : : static int32_t test10(void);
37 : : static int32_t test11(void);
38 : : static int32_t test12(void);
39 : : static int32_t test13(void);
40 : : static int32_t test14(void);
41 : : static int32_t test15(void);
42 : : static int32_t test16(void);
43 : : static int32_t test17(void);
44 : : static int32_t test18(void);
45 : : static int32_t test19(void);
46 : : static int32_t test20(void);
47 : : static int32_t test21(void);
48 : : static int32_t test22(void);
49 : : static int32_t test23(void);
50 : : static int32_t test24(void);
51 : : static int32_t test25(void);
52 : : static int32_t test26(void);
53 : : static int32_t test27(void);
54 : : static int32_t test28(void);
55 : :
56 : : rte_lpm6_test tests6[] = {
57 : : /* Test Cases */
58 : : test0,
59 : : test1,
60 : : test2,
61 : : test3,
62 : : test4,
63 : : test5,
64 : : test6,
65 : : test7,
66 : : test8,
67 : : test9,
68 : : test10,
69 : : test11,
70 : : test12,
71 : : test13,
72 : : test14,
73 : : test15,
74 : : test16,
75 : : test17,
76 : : test18,
77 : : test19,
78 : : test20,
79 : : test21,
80 : : test22,
81 : : test23,
82 : : test24,
83 : : test25,
84 : : test26,
85 : : test27,
86 : : test28,
87 : : };
88 : :
89 : : #define MAX_DEPTH 128
90 : : #define MAX_RULES 1000000
91 : : #define NUMBER_TBL8S (1 << 16)
92 : : #define MAX_NUM_TBL8S (1 << 21)
93 : : #define PASS 0
94 : :
95 : : static void
96 : : IPv6(uint8_t *ip, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5,
97 : : uint8_t b6, uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10,
98 : : uint8_t b11, uint8_t b12, uint8_t b13, uint8_t b14, uint8_t b15,
99 : : uint8_t b16)
100 : : {
101 : 34 : ip[0] = b1;
102 : 34 : ip[1] = b2;
103 : 34 : ip[2] = b3;
104 : 34 : ip[3] = b4;
105 : 34 : ip[4] = b5;
106 : 34 : ip[5] = b6;
107 : 34 : ip[6] = b7;
108 : 34 : ip[7] = b8;
109 : 34 : ip[8] = b9;
110 : 34 : ip[9] = b10;
111 : 34 : ip[10] = b11;
112 : 34 : ip[11] = b12;
113 : 34 : ip[12] = b13;
114 : 34 : ip[13] = b14;
115 : 34 : ip[14] = b15;
116 : 34 : ip[15] = b16;
117 : : }
118 : :
119 : : /*
120 : : * Check that rte_lpm6_create fails gracefully for incorrect user input
121 : : * arguments
122 : : */
123 : : int32_t
124 : 1 : test0(void)
125 : : {
126 : : struct rte_lpm6 *lpm = NULL;
127 : : struct rte_lpm6_config config;
128 : :
129 : 1 : config.max_rules = MAX_RULES;
130 : 1 : config.number_tbl8s = NUMBER_TBL8S;
131 : 1 : config.flags = 0;
132 : :
133 : : /* rte_lpm6_create: lpm name == NULL */
134 : 1 : lpm = rte_lpm6_create(NULL, SOCKET_ID_ANY, &config);
135 [ - + ]: 1 : TEST_LPM_ASSERT(lpm == NULL);
136 : :
137 : : /* rte_lpm6_create: max_rules = 0 */
138 : : /* Note: __func__ inserts the function name, in this case "test0". */
139 : 1 : config.max_rules = 0;
140 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
141 [ - + ]: 1 : TEST_LPM_ASSERT(lpm == NULL);
142 : :
143 : : /* socket_id < -1 is invalid */
144 : 1 : config.max_rules = MAX_RULES;
145 : 1 : lpm = rte_lpm6_create(__func__, -2, &config);
146 [ - + ]: 1 : TEST_LPM_ASSERT(lpm == NULL);
147 : :
148 : : /* rte_lpm6_create: number_tbl8s is bigger than the maximum */
149 : 1 : config.number_tbl8s = MAX_NUM_TBL8S + 1;
150 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
151 [ - + ]: 1 : TEST_LPM_ASSERT(lpm == NULL);
152 : :
153 : : /* rte_lpm6_create: config = NULL */
154 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, NULL);
155 [ - + ]: 1 : TEST_LPM_ASSERT(lpm == NULL);
156 : :
157 : : return PASS;
158 : : }
159 : :
160 : : /*
161 : : * Creates two different LPM tables. Tries to create a third one with the same
162 : : * name as the first one and expects the create function to return the same
163 : : * pointer.
164 : : */
165 : : int32_t
166 : 1 : test1(void)
167 : : {
168 : : struct rte_lpm6 *lpm1 = NULL, *lpm2 = NULL, *lpm3 = NULL;
169 : : struct rte_lpm6_config config;
170 : :
171 : 1 : config.max_rules = MAX_RULES;
172 : 1 : config.number_tbl8s = NUMBER_TBL8S;
173 : 1 : config.flags = 0;
174 : :
175 : : /* rte_lpm6_create: lpm name == LPM1 */
176 : 1 : lpm1 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
177 [ - + ]: 1 : TEST_LPM_ASSERT(lpm1 != NULL);
178 : :
179 : : /* rte_lpm6_create: lpm name == LPM2 */
180 : 1 : lpm2 = rte_lpm6_create("LPM2", SOCKET_ID_ANY, &config);
181 [ - + ]: 1 : TEST_LPM_ASSERT(lpm2 != NULL);
182 : :
183 : : /* rte_lpm6_create: lpm name == LPM2 */
184 : 1 : lpm3 = rte_lpm6_create("LPM1", SOCKET_ID_ANY, &config);
185 [ - + ]: 1 : TEST_LPM_ASSERT(lpm3 == NULL);
186 : :
187 : 1 : rte_lpm6_free(lpm1);
188 : 1 : rte_lpm6_free(lpm2);
189 : :
190 : 1 : return PASS;
191 : : }
192 : :
193 : : /*
194 : : * Create lpm table then delete lpm table 20 times
195 : : * Use a slightly different rules size each time
196 : : */
197 : : int32_t
198 : 1 : test2(void)
199 : : {
200 : : struct rte_lpm6 *lpm = NULL;
201 : : struct rte_lpm6_config config;
202 : : int32_t i;
203 : :
204 : 1 : config.number_tbl8s = NUMBER_TBL8S;
205 : 1 : config.flags = 0;
206 : :
207 : : /* rte_lpm6_free: Free NULL */
208 [ + + ]: 21 : for (i = 0; i < 20; i++) {
209 : 20 : config.max_rules = MAX_RULES - i;
210 : 20 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
211 [ - + ]: 20 : TEST_LPM_ASSERT(lpm != NULL);
212 : :
213 : 20 : rte_lpm6_free(lpm);
214 : : }
215 : :
216 : : /* Can not test free so return success */
217 : : return PASS;
218 : : }
219 : :
220 : : /*
221 : : * Call rte_lpm6_free for NULL pointer user input. Note: free has no return and
222 : : * therefore it is impossible to check for failure but this test is added to
223 : : * increase function coverage metrics and to validate that freeing null does
224 : : * not crash.
225 : : */
226 : : int32_t
227 : 1 : test3(void)
228 : : {
229 : : struct rte_lpm6 *lpm = NULL;
230 : : struct rte_lpm6_config config;
231 : :
232 : 1 : config.max_rules = MAX_RULES;
233 : 1 : config.number_tbl8s = NUMBER_TBL8S;
234 : 1 : config.flags = 0;
235 : :
236 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
237 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
238 : :
239 : 1 : rte_lpm6_free(lpm);
240 : 1 : rte_lpm6_free(NULL);
241 : 1 : return PASS;
242 : : }
243 : :
244 : : /*
245 : : * Check that rte_lpm6_add fails gracefully for incorrect user input arguments
246 : : */
247 : : int32_t
248 : 1 : test4(void)
249 : : {
250 : : struct rte_lpm6 *lpm = NULL;
251 : : struct rte_lpm6_config config;
252 : :
253 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
254 : : uint8_t depth = 24, next_hop = 100;
255 : : int32_t status = 0;
256 : :
257 : 1 : config.max_rules = MAX_RULES;
258 : 1 : config.number_tbl8s = NUMBER_TBL8S;
259 : 1 : config.flags = 0;
260 : :
261 : : /* rte_lpm6_add: lpm == NULL */
262 : 1 : status = rte_lpm6_add(NULL, ip, depth, next_hop);
263 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
264 : :
265 : : /*Create valid lpm to use in rest of test. */
266 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
267 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
268 : :
269 : : /* rte_lpm6_add: depth < 1 */
270 : 1 : status = rte_lpm6_add(lpm, ip, 0, next_hop);
271 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
272 : :
273 : : /* rte_lpm6_add: depth > MAX_DEPTH */
274 : 1 : status = rte_lpm6_add(lpm, ip, (MAX_DEPTH + 1), next_hop);
275 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
276 : :
277 : 1 : rte_lpm6_free(lpm);
278 : :
279 : 1 : return PASS;
280 : : }
281 : :
282 : : /*
283 : : * Check that rte_lpm6_delete fails gracefully for incorrect user input
284 : : * arguments
285 : : */
286 : : int32_t
287 : 1 : test5(void)
288 : : {
289 : : struct rte_lpm6 *lpm = NULL;
290 : : struct rte_lpm6_config config;
291 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
292 : : uint8_t depth = 24;
293 : : int32_t status = 0;
294 : :
295 : 1 : config.max_rules = MAX_RULES;
296 : 1 : config.number_tbl8s = NUMBER_TBL8S;
297 : 1 : config.flags = 0;
298 : :
299 : : /* rte_lpm_delete: lpm == NULL */
300 : 1 : status = rte_lpm6_delete(NULL, ip, depth);
301 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
302 : :
303 : : /*Create valid lpm to use in rest of test. */
304 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
305 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
306 : :
307 : : /* rte_lpm_delete: depth < 1 */
308 : 1 : status = rte_lpm6_delete(lpm, ip, 0);
309 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
310 : :
311 : : /* rte_lpm_delete: depth > MAX_DEPTH */
312 : 1 : status = rte_lpm6_delete(lpm, ip, (MAX_DEPTH + 1));
313 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
314 : :
315 : 1 : rte_lpm6_free(lpm);
316 : :
317 : 1 : return PASS;
318 : : }
319 : :
320 : : /*
321 : : * Check that rte_lpm6_lookup fails gracefully for incorrect user input
322 : : * arguments
323 : : */
324 : : int32_t
325 : 1 : test6(void)
326 : : {
327 : : struct rte_lpm6 *lpm = NULL;
328 : : struct rte_lpm6_config config;
329 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
330 : 1 : uint32_t next_hop_return = 0;
331 : : int32_t status = 0;
332 : :
333 : 1 : config.max_rules = MAX_RULES;
334 : 1 : config.number_tbl8s = NUMBER_TBL8S;
335 : 1 : config.flags = 0;
336 : :
337 : : /* rte_lpm6_lookup: lpm == NULL */
338 : 1 : status = rte_lpm6_lookup(NULL, ip, &next_hop_return);
339 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
340 : :
341 : : /*Create valid lpm to use in rest of test. */
342 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
343 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
344 : :
345 : : /* rte_lpm6_lookup: ip = NULL */
346 : 1 : status = rte_lpm6_lookup(lpm, NULL, &next_hop_return);
347 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
348 : :
349 : : /* rte_lpm6_lookup: next_hop = NULL */
350 : 1 : status = rte_lpm6_lookup(lpm, ip, NULL);
351 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
352 : :
353 : 1 : rte_lpm6_free(lpm);
354 : :
355 : 1 : return PASS;
356 : : }
357 : :
358 : : /*
359 : : * Checks that rte_lpm6_lookup_bulk_func fails gracefully for incorrect user
360 : : * input arguments
361 : : */
362 : : int32_t
363 : 1 : test7(void)
364 : : {
365 : : struct rte_lpm6 *lpm = NULL;
366 : : struct rte_lpm6_config config;
367 : : uint8_t ip[10][16];
368 : : int32_t next_hop_return[10];
369 : : int32_t status = 0;
370 : :
371 : 1 : config.max_rules = MAX_RULES;
372 : 1 : config.number_tbl8s = NUMBER_TBL8S;
373 : 1 : config.flags = 0;
374 : :
375 : : /* rte_lpm6_lookup: lpm == NULL */
376 : 1 : status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10);
377 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
378 : :
379 : : /*Create valid lpm to use in rest of test. */
380 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
381 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
382 : :
383 : : /* rte_lpm6_lookup: ip = NULL */
384 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, NULL, next_hop_return, 10);
385 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
386 : :
387 : : /* rte_lpm6_lookup: next_hop = NULL */
388 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip, NULL, 10);
389 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
390 : :
391 : 1 : rte_lpm6_free(lpm);
392 : :
393 : 1 : return PASS;
394 : : }
395 : :
396 : : /*
397 : : * Checks that rte_lpm6_delete_bulk_func fails gracefully for incorrect user
398 : : * input arguments
399 : : */
400 : : int32_t
401 : 1 : test8(void)
402 : : {
403 : : struct rte_lpm6 *lpm = NULL;
404 : : struct rte_lpm6_config config;
405 : : uint8_t ip[10][16];
406 : : uint8_t depth[10];
407 : : int32_t status = 0;
408 : :
409 : 1 : config.max_rules = MAX_RULES;
410 : 1 : config.number_tbl8s = NUMBER_TBL8S;
411 : 1 : config.flags = 0;
412 : :
413 : : /* rte_lpm6_delete: lpm == NULL */
414 : 1 : status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10);
415 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
416 : :
417 : : /*Create valid lpm to use in rest of test. */
418 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
419 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
420 : :
421 : : /* rte_lpm6_delete: ip = NULL */
422 : 1 : status = rte_lpm6_delete_bulk_func(lpm, NULL, depth, 10);
423 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
424 : :
425 : : /* rte_lpm6_delete: next_hop = NULL */
426 : 1 : status = rte_lpm6_delete_bulk_func(lpm, ip, NULL, 10);
427 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
428 : :
429 : 1 : rte_lpm6_free(lpm);
430 : :
431 : 1 : return PASS;
432 : : }
433 : :
434 : : /*
435 : : * Call add, lookup and delete for a single rule with depth < 24.
436 : : * Check all the combinations for the first three bytes that result in a hit.
437 : : * Delete the rule and check that the same test returns a miss.
438 : : */
439 : : int32_t
440 : 1 : test9(void)
441 : : {
442 : : struct rte_lpm6 *lpm = NULL;
443 : : struct rte_lpm6_config config;
444 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
445 : : uint8_t depth = 16;
446 : 1 : uint32_t next_hop_add = 100, next_hop_return = 0;
447 : : int32_t status = 0;
448 : : uint8_t i;
449 : :
450 : 1 : config.max_rules = MAX_RULES;
451 : 1 : config.number_tbl8s = NUMBER_TBL8S;
452 : 1 : config.flags = 0;
453 : :
454 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
455 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
456 : :
457 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
458 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
459 : :
460 [ + + ]: 256 : for (i = 0; i < UINT8_MAX; i++) {
461 : 255 : ip[2] = i;
462 : 255 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
463 [ + - - + ]: 255 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
464 : : }
465 : :
466 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
467 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
468 : :
469 [ + + ]: 256 : for (i = 0; i < UINT8_MAX; i++) {
470 : 255 : ip[2] = i;
471 : 255 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
472 [ - + ]: 255 : TEST_LPM_ASSERT(status == -ENOENT);
473 : : }
474 : :
475 : 1 : rte_lpm6_free(lpm);
476 : :
477 : 1 : return PASS;
478 : : }
479 : :
480 : : /*
481 : : * Adds max_rules + 1 and expects a failure. Deletes a rule, then adds
482 : : * another one and expects success.
483 : : */
484 : : int32_t
485 : 1 : test10(void)
486 : : {
487 : : struct rte_lpm6 *lpm = NULL;
488 : : struct rte_lpm6_config config;
489 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
490 : : uint8_t depth;
491 : : uint32_t next_hop_add = 100;
492 : : int32_t status = 0;
493 : : int i;
494 : :
495 : 1 : config.max_rules = 127;
496 : 1 : config.number_tbl8s = NUMBER_TBL8S;
497 : 1 : config.flags = 0;
498 : :
499 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
500 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
501 : :
502 [ + + ]: 128 : for (i = 1; i < 128; i++) {
503 : : depth = (uint8_t)i;
504 : 127 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
505 [ - + ]: 127 : TEST_LPM_ASSERT(status == 0);
506 : : }
507 : :
508 : : depth = 128;
509 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
510 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOSPC);
511 : :
512 : : depth = 127;
513 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
514 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
515 : :
516 : : depth = 128;
517 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
518 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
519 : :
520 : 1 : rte_lpm6_free(lpm);
521 : :
522 : 1 : return PASS;
523 : : }
524 : :
525 : : /*
526 : : * Creates an LPM table with a small number of tbl8s and exhaust them in the
527 : : * middle of the process of creating a rule.
528 : : */
529 : : int32_t
530 : 1 : test11(void)
531 : : {
532 : : struct rte_lpm6 *lpm = NULL;
533 : : struct rte_lpm6_config config;
534 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
535 : : uint8_t depth;
536 : : uint32_t next_hop_add = 100;
537 : : int32_t status = 0;
538 : :
539 : 1 : config.max_rules = MAX_RULES;
540 : 1 : config.number_tbl8s = 16;
541 : 1 : config.flags = 0;
542 : :
543 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
544 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
545 : :
546 : : depth = 128;
547 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
548 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
549 : :
550 : 1 : ip[0] = 1;
551 : : depth = 25;
552 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
553 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
554 : :
555 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
556 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
557 : :
558 : : depth = 33;
559 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
560 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
561 : :
562 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
563 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
564 : :
565 : : depth = 41;
566 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
567 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
568 : :
569 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
570 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
571 : :
572 : : depth = 49;
573 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
574 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOSPC);
575 : :
576 : : depth = 41;
577 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
578 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
579 : :
580 : 1 : rte_lpm6_free(lpm);
581 : :
582 : 1 : return PASS;
583 : : }
584 : :
585 : : /*
586 : : * Creates an LPM table with a small number of tbl8s and exhaust them in the
587 : : * middle of the process of adding a rule when there is already an existing rule
588 : : * in that position and needs to be extended.
589 : : */
590 : : int32_t
591 : 1 : test12(void)
592 : : {
593 : : struct rte_lpm6 *lpm = NULL;
594 : : struct rte_lpm6_config config;
595 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
596 : : uint8_t depth;
597 : : uint32_t next_hop_add = 100;
598 : : int32_t status = 0;
599 : :
600 : 1 : config.max_rules = MAX_RULES;
601 : 1 : config.number_tbl8s = 16;
602 : 1 : config.flags = 0;
603 : :
604 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
605 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
606 : :
607 : : depth = 128;
608 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
609 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
610 : :
611 : 1 : ip[0] = 1;
612 : : depth = 41;
613 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
614 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
615 : :
616 : : depth = 49;
617 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
618 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOSPC);
619 : :
620 : 1 : rte_lpm6_free(lpm);
621 : :
622 : 1 : return PASS;
623 : : }
624 : :
625 : : /*
626 : : * Creates an LPM table with max_rules = 2 and tries to add 3 rules.
627 : : * Delete one of the rules and tries to add the third one again.
628 : : */
629 : : int32_t
630 : 1 : test13(void)
631 : : {
632 : : struct rte_lpm6 *lpm = NULL;
633 : : struct rte_lpm6_config config;
634 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
635 : : uint8_t depth;
636 : : uint32_t next_hop_add = 100;
637 : : int32_t status = 0;
638 : :
639 : 1 : config.max_rules = 2;
640 : 1 : config.number_tbl8s = NUMBER_TBL8S;
641 : 1 : config.flags = 0;
642 : :
643 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
644 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
645 : :
646 : : depth = 1;
647 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
648 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
649 : :
650 : : depth = 2;
651 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
652 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
653 : :
654 : : depth = 3;
655 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
656 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOSPC);
657 : :
658 : : depth = 2;
659 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
660 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
661 : :
662 : : depth = 3;
663 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
664 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
665 : :
666 : 1 : rte_lpm6_free(lpm);
667 : :
668 : 1 : return PASS;
669 : : }
670 : :
671 : : /*
672 : : * Add 2^12 routes with different first 12 bits and depth 25.
673 : : * Add one more route with the same depth and check that results in a failure.
674 : : * After that delete the last rule and create the one that was attempted to be
675 : : * created. This checks tbl8 exhaustion.
676 : : */
677 : : int32_t
678 : 1 : test14(void)
679 : : {
680 : : struct rte_lpm6 *lpm = NULL;
681 : : struct rte_lpm6_config config;
682 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
683 : : uint8_t depth = 25;
684 : : uint32_t next_hop_add = 100;
685 : : int32_t status = 0;
686 : : int i;
687 : :
688 : 1 : config.max_rules = MAX_RULES;
689 : 1 : config.number_tbl8s = 256;
690 : 1 : config.flags = 0;
691 : :
692 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
693 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
694 : :
695 [ + + ]: 257 : for (i = 0; i < 256; i++) {
696 : 256 : ip[0] = (uint8_t)i;
697 : 256 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
698 [ - + ]: 256 : TEST_LPM_ASSERT(status == 0);
699 : : }
700 : :
701 : 1 : ip[0] = 255;
702 : 1 : ip[1] = 1;
703 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
704 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOSPC);
705 : :
706 : 1 : ip[0] = 255;
707 : 1 : ip[1] = 0;
708 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
709 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
710 : :
711 : 1 : ip[0] = 255;
712 : 1 : ip[1] = 1;
713 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
714 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
715 : :
716 : 1 : rte_lpm6_free(lpm);
717 : :
718 : 1 : return PASS;
719 : : }
720 : :
721 : : /*
722 : : * Call add, lookup and delete for a single rule with depth = 24
723 : : */
724 : : int32_t
725 : 1 : test15(void)
726 : : {
727 : : struct rte_lpm6 *lpm = NULL;
728 : : struct rte_lpm6_config config;
729 : 1 : uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
730 : : uint8_t depth = 24;
731 : 1 : uint32_t next_hop_add = 100, next_hop_return = 0;
732 : : int32_t status = 0;
733 : :
734 : 1 : config.max_rules = MAX_RULES;
735 : 1 : config.number_tbl8s = NUMBER_TBL8S;
736 : 1 : config.flags = 0;
737 : :
738 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
739 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
740 : :
741 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
742 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
743 : :
744 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
745 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
746 : :
747 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
748 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
749 : :
750 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
751 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
752 : :
753 : 1 : rte_lpm6_free(lpm);
754 : :
755 : 1 : return PASS;
756 : : }
757 : :
758 : : /*
759 : : * Call add, lookup and delete for a single rule with depth > 24
760 : : */
761 : : int32_t
762 : 1 : test16(void)
763 : : {
764 : : struct rte_lpm6 *lpm = NULL;
765 : : struct rte_lpm6_config config;
766 : 1 : uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
767 : : uint8_t depth = 128;
768 : 1 : uint32_t next_hop_add = 100, next_hop_return = 0;
769 : : int32_t status = 0;
770 : :
771 : 1 : config.max_rules = MAX_RULES;
772 : 1 : config.number_tbl8s = NUMBER_TBL8S;
773 : 1 : config.flags = 0;
774 : :
775 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
776 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
777 : :
778 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
779 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
780 : :
781 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
782 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
783 : :
784 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
785 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
786 : :
787 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
788 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
789 : :
790 : 1 : rte_lpm6_free(lpm);
791 : :
792 : 1 : return PASS;
793 : : }
794 : :
795 : : /*
796 : : * Use rte_lpm6_add to add rules which effect only the second half of the lpm
797 : : * table. Use all possible depths ranging from 1..32. Set the next hop = to the
798 : : * depth. Check lookup hit for on every add and check for lookup miss on the
799 : : * first half of the lpm table after each add. Finally delete all rules going
800 : : * backwards (i.e. from depth = 32 ..1) and carry out a lookup after each
801 : : * delete. The lookup should return the next_hop_add value related to the
802 : : * previous depth value (i.e. depth -1).
803 : : */
804 : : int32_t
805 : 1 : test17(void)
806 : : {
807 : : struct rte_lpm6 *lpm = NULL;
808 : : struct rte_lpm6_config config;
809 : 1 : uint8_t ip1[] = {127,255,255,255,255,255,255,255,255,
810 : : 255,255,255,255,255,255,255};
811 : 1 : uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
812 : : uint8_t depth;
813 : : uint32_t next_hop_add, next_hop_return;
814 : : int32_t status = 0;
815 : :
816 : 1 : config.max_rules = MAX_RULES;
817 : 1 : config.number_tbl8s = NUMBER_TBL8S;
818 : 1 : config.flags = 0;
819 : :
820 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
821 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
822 : :
823 : : /* Loop with rte_lpm6_add. */
824 [ + + ]: 17 : for (depth = 1; depth <= 16; depth++) {
825 : : /* Let the next_hop_add value = depth. Just for change. */
826 : 16 : next_hop_add = depth;
827 : :
828 : 16 : status = rte_lpm6_add(lpm, ip2, depth, next_hop_add);
829 [ - + ]: 16 : TEST_LPM_ASSERT(status == 0);
830 : :
831 : : /* Check IP in first half of tbl24 which should be empty. */
832 : 16 : status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
833 [ - + ]: 16 : TEST_LPM_ASSERT(status == -ENOENT);
834 : :
835 : 16 : status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
836 [ + - - + ]: 16 : TEST_LPM_ASSERT((status == 0) &&
837 : : (next_hop_return == next_hop_add));
838 : : }
839 : :
840 : : /* Loop with rte_lpm6_delete. */
841 [ + + ]: 17 : for (depth = 16; depth >= 1; depth--) {
842 : 16 : next_hop_add = (depth - 1);
843 : :
844 : 16 : status = rte_lpm6_delete(lpm, ip2, depth);
845 [ - + ]: 16 : TEST_LPM_ASSERT(status == 0);
846 : :
847 : 16 : status = rte_lpm6_lookup(lpm, ip2, &next_hop_return);
848 : :
849 [ + + ]: 16 : if (depth != 1) {
850 [ + - - + ]: 15 : TEST_LPM_ASSERT((status == 0) &&
851 : : (next_hop_return == next_hop_add));
852 : : }
853 : : else {
854 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
855 : : }
856 : :
857 : 16 : status = rte_lpm6_lookup(lpm, ip1, &next_hop_return);
858 [ - + ]: 16 : TEST_LPM_ASSERT(status == -ENOENT);
859 : : }
860 : :
861 : 1 : rte_lpm6_free(lpm);
862 : :
863 : 1 : return PASS;
864 : : }
865 : :
866 : : /*
867 : : * - Add & lookup to hit invalid TBL24 entry
868 : : * - Add & lookup to hit valid TBL24 entry not extended
869 : : * - Add & lookup to hit valid extended TBL24 entry with invalid TBL8 entry
870 : : * - Add & lookup to hit valid extended TBL24 entry with valid TBL8 entry
871 : : */
872 : : int32_t
873 : 1 : test18(void)
874 : : {
875 : : struct rte_lpm6 *lpm = NULL;
876 : : struct rte_lpm6_config config;
877 : : uint8_t ip[16], ip_1[16], ip_2[16];
878 : : uint8_t depth, depth_1, depth_2;
879 : : uint32_t next_hop_add, next_hop_add_1,
880 : : next_hop_add_2, next_hop_return;
881 : : int32_t status = 0;
882 : :
883 : 1 : config.max_rules = MAX_RULES;
884 : 1 : config.number_tbl8s = NUMBER_TBL8S;
885 : 1 : config.flags = 0;
886 : :
887 : : /* Add & lookup to hit invalid TBL24 entry */
888 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
889 : : depth = 24;
890 : : next_hop_add = 100;
891 : :
892 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
893 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
894 : :
895 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
896 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
897 : :
898 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
899 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
900 : :
901 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
902 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
903 : :
904 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
905 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
906 : :
907 : 1 : rte_lpm6_delete_all(lpm);
908 : :
909 : : /* Add & lookup to hit valid TBL24 entry not extended */
910 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
911 : : depth = 23;
912 : : next_hop_add = 100;
913 : :
914 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
915 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
916 : :
917 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
918 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
919 : :
920 : : depth = 24;
921 : : next_hop_add = 101;
922 : :
923 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
924 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
925 : :
926 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
927 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
928 : :
929 : : depth = 24;
930 : :
931 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
932 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
933 : :
934 : : depth = 23;
935 : :
936 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
937 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
938 : :
939 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
940 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
941 : :
942 : 1 : rte_lpm6_delete_all(lpm);
943 : :
944 : : /* Add & lookup to hit valid extended TBL24 entry with invalid TBL8
945 : : * entry.
946 : : */
947 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
948 : : depth = 32;
949 : : next_hop_add = 100;
950 : :
951 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
952 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
953 : :
954 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
955 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
956 : :
957 : : IPv6(ip, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
958 : : depth = 32;
959 : : next_hop_add = 101;
960 : :
961 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
962 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
963 : :
964 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
965 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
966 : :
967 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
968 : : depth = 32;
969 : : next_hop_add = 100;
970 : :
971 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
972 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
973 : :
974 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
975 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
976 : :
977 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
978 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
979 : :
980 : 1 : rte_lpm6_delete_all(lpm);
981 : :
982 : : /* Add & lookup to hit valid extended TBL24 entry with valid TBL8
983 : : * entry
984 : : */
985 : : IPv6(ip_1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
986 : : depth_1 = 25;
987 : : next_hop_add_1 = 101;
988 : :
989 : : IPv6(ip_2, 128, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
990 : : depth_2 = 32;
991 : : next_hop_add_2 = 102;
992 : :
993 : 1 : next_hop_return = 0;
994 : :
995 : 1 : status = rte_lpm6_add(lpm, ip_1, depth_1, next_hop_add_1);
996 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
997 : :
998 : 1 : status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return);
999 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
1000 : :
1001 : 1 : status = rte_lpm6_add(lpm, ip_2, depth_2, next_hop_add_2);
1002 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1003 : :
1004 : 1 : status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return);
1005 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_2));
1006 : :
1007 : 1 : status = rte_lpm6_delete(lpm, ip_2, depth_2);
1008 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1009 : :
1010 : 1 : status = rte_lpm6_lookup(lpm, ip_2, &next_hop_return);
1011 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add_1));
1012 : :
1013 : 1 : status = rte_lpm6_delete(lpm, ip_1, depth_1);
1014 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1015 : :
1016 : 1 : status = rte_lpm6_lookup(lpm, ip_1, &next_hop_return);
1017 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1018 : :
1019 : 1 : rte_lpm6_free(lpm);
1020 : :
1021 : 1 : return PASS;
1022 : : }
1023 : :
1024 : : /*
1025 : : * - Add rule that covers a TBL24 range previously invalid & lookup (& delete &
1026 : : * lookup)
1027 : : * - Add rule that extends a TBL24 invalid entry & lookup (& delete & lookup)
1028 : : * - Add rule that extends a TBL24 valid entry & lookup for both rules (&
1029 : : * delete & lookup)
1030 : : * - Add rule that updates the next hop in TBL24 & lookup (& delete & lookup)
1031 : : * - Add rule that updates the next hop in TBL8 & lookup (& delete & lookup)
1032 : : * - Delete a rule that is not present in the TBL24 & lookup
1033 : : * - Delete a rule that is not present in the TBL8 & lookup
1034 : : */
1035 : : int32_t
1036 : 1 : test19(void)
1037 : : {
1038 : : struct rte_lpm6 *lpm = NULL;
1039 : : struct rte_lpm6_config config;
1040 : : uint8_t ip[16];
1041 : : uint8_t depth;
1042 : : uint32_t next_hop_add, next_hop_return;
1043 : : int32_t status = 0;
1044 : :
1045 : 1 : config.max_rules = MAX_RULES;
1046 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1047 : 1 : config.flags = 0;
1048 : :
1049 : : /* Add rule that covers a TBL24 range previously invalid & lookup
1050 : : * (& delete & lookup)
1051 : : */
1052 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1053 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1054 : :
1055 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1056 : : depth = 16;
1057 : : next_hop_add = 100;
1058 : :
1059 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1060 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1061 : :
1062 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1063 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1064 : :
1065 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1066 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1067 : :
1068 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1069 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1070 : :
1071 : 1 : rte_lpm6_delete_all(lpm);
1072 : :
1073 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1074 : : depth = 25;
1075 : : next_hop_add = 100;
1076 : :
1077 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1078 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1079 : :
1080 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1081 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1082 : :
1083 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1084 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1085 : :
1086 : 1 : rte_lpm6_delete_all(lpm);
1087 : :
1088 : : /*
1089 : : * Add rule that extends a TBL24 valid entry & lookup for both rules
1090 : : * (& delete & lookup)
1091 : : */
1092 : :
1093 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1094 : : depth = 24;
1095 : : next_hop_add = 100;
1096 : :
1097 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1098 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1099 : :
1100 : : IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1101 : : depth = 32;
1102 : : next_hop_add = 101;
1103 : :
1104 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1105 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1106 : :
1107 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1108 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1109 : :
1110 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1111 : : next_hop_add = 100;
1112 : :
1113 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1114 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1115 : :
1116 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1117 : : depth = 24;
1118 : :
1119 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1120 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1121 : :
1122 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1123 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1124 : :
1125 : : IPv6(ip, 128, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1126 : : depth = 32;
1127 : :
1128 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1129 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1130 : :
1131 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1132 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1133 : :
1134 : 1 : rte_lpm6_delete_all(lpm);
1135 : :
1136 : : /*
1137 : : * Add rule that updates the next hop in TBL24 & lookup
1138 : : * (& delete & lookup)
1139 : : */
1140 : :
1141 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1142 : : depth = 24;
1143 : : next_hop_add = 100;
1144 : :
1145 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1146 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1147 : :
1148 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1149 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1150 : :
1151 : : next_hop_add = 101;
1152 : :
1153 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1154 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1155 : :
1156 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1157 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1158 : :
1159 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1160 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1161 : :
1162 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1163 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1164 : :
1165 : 1 : rte_lpm6_delete_all(lpm);
1166 : :
1167 : : /*
1168 : : * Add rule that updates the next hop in TBL8 & lookup
1169 : : * (& delete & lookup)
1170 : : */
1171 : :
1172 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1173 : : depth = 32;
1174 : : next_hop_add = 100;
1175 : :
1176 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1177 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1178 : :
1179 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1180 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1181 : :
1182 : : next_hop_add = 101;
1183 : :
1184 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1185 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1186 : :
1187 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1188 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1189 : :
1190 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1191 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1192 : :
1193 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1194 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1195 : :
1196 : 1 : rte_lpm6_delete_all(lpm);
1197 : :
1198 : : /* Delete a rule that is not present in the TBL24 & lookup */
1199 : :
1200 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1201 : : depth = 24;
1202 : : next_hop_add = 100;
1203 : :
1204 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1205 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
1206 : :
1207 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1208 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1209 : :
1210 : 1 : rte_lpm6_delete_all(lpm);
1211 : :
1212 : : /* Delete a rule that is not present in the TBL8 & lookup */
1213 : :
1214 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1215 : : depth = 32;
1216 : : next_hop_add = 100;
1217 : :
1218 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1219 [ - + ]: 1 : TEST_LPM_ASSERT(status < 0);
1220 : :
1221 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1222 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1223 : :
1224 : 1 : rte_lpm6_free(lpm);
1225 : :
1226 : 1 : return PASS;
1227 : : }
1228 : :
1229 : : /*
1230 : : * Add two rules, lookup to hit the more specific one, lookup to hit the less
1231 : : * specific one delete the less specific rule and lookup previous values again;
1232 : : * add a more specific rule than the existing rule, lookup again
1233 : : */
1234 : : int32_t
1235 : 1 : test20(void)
1236 : : {
1237 : : struct rte_lpm6 *lpm = NULL;
1238 : : struct rte_lpm6_config config;
1239 : : uint8_t ip[16];
1240 : : uint8_t depth;
1241 : : uint32_t next_hop_add, next_hop_return;
1242 : : int32_t status = 0;
1243 : :
1244 : 1 : config.max_rules = MAX_RULES;
1245 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1246 : 1 : config.flags = 0;
1247 : :
1248 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1249 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1250 : :
1251 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1252 : : depth = 24;
1253 : : next_hop_add = 100;
1254 : :
1255 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1256 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1257 : :
1258 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10);
1259 : : depth = 128;
1260 : : next_hop_add = 101;
1261 : :
1262 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1263 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1264 : :
1265 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1266 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1267 : :
1268 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1269 : : next_hop_add = 100;
1270 : :
1271 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1272 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1273 : :
1274 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1275 : : depth = 24;
1276 : :
1277 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1278 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1279 : :
1280 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1281 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1282 : :
1283 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10);
1284 : : depth = 128;
1285 : :
1286 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1287 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1288 : :
1289 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1290 [ - + ]: 1 : TEST_LPM_ASSERT(status == -ENOENT);
1291 : :
1292 : 1 : rte_lpm6_free(lpm);
1293 : :
1294 : 1 : return PASS;
1295 : : }
1296 : :
1297 : : /*
1298 : : * Adds 3 rules and look them up through the lookup_bulk function.
1299 : : * Includes in the lookup a fourth IP address that won't match
1300 : : * and checks that the result is as expected.
1301 : : */
1302 : : int32_t
1303 : 1 : test21(void)
1304 : : {
1305 : : struct rte_lpm6 *lpm = NULL;
1306 : : struct rte_lpm6_config config;
1307 : : uint8_t ip_batch[4][16];
1308 : : uint8_t depth;
1309 : : uint32_t next_hop_add;
1310 : : int32_t next_hop_return[4];
1311 : : int32_t status = 0;
1312 : :
1313 : 1 : config.max_rules = MAX_RULES;
1314 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1315 : 1 : config.flags = 0;
1316 : :
1317 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1318 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1319 : :
1320 : : IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1321 : : depth = 48;
1322 : : next_hop_add = 100;
1323 : :
1324 : 1 : status = rte_lpm6_add(lpm, ip_batch[0], depth, next_hop_add);
1325 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1326 : :
1327 : : IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1328 : : depth = 48;
1329 : : next_hop_add = 101;
1330 : :
1331 : 1 : status = rte_lpm6_add(lpm, ip_batch[1], depth, next_hop_add);
1332 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1333 : :
1334 : : IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1335 : : depth = 48;
1336 : : next_hop_add = 102;
1337 : :
1338 : 1 : status = rte_lpm6_add(lpm, ip_batch[2], depth, next_hop_add);
1339 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1340 : :
1341 : : IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1342 : :
1343 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1344 : : next_hop_return, 4);
1345 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 100
+ - + - -
+ ]
1346 : : && next_hop_return[1] == 101 && next_hop_return[2] == 102
1347 : : && next_hop_return[3] == -1);
1348 : :
1349 : 1 : rte_lpm6_free(lpm);
1350 : :
1351 : 1 : return PASS;
1352 : : }
1353 : :
1354 : : /*
1355 : : * Adds 5 rules and look them up.
1356 : : * Use the delete_bulk function to delete two of them. Lookup again.
1357 : : * Use the delete_bulk function to delete one more. Lookup again.
1358 : : * Use the delete_bulk function to delete two more, one invalid. Lookup again.
1359 : : * Use the delete_bulk function to delete the remaining one. Lookup again.
1360 : : */
1361 : : int32_t
1362 : 1 : test22(void)
1363 : : {
1364 : : struct rte_lpm6 *lpm = NULL;
1365 : : struct rte_lpm6_config config;
1366 : : uint8_t ip_batch[5][16];
1367 : : uint8_t depth[5];
1368 : : uint32_t next_hop_add;
1369 : : int32_t next_hop_return[5];
1370 : : int32_t status = 0;
1371 : :
1372 : 1 : config.max_rules = MAX_RULES;
1373 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1374 : 1 : config.flags = 0;
1375 : :
1376 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1377 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1378 : :
1379 : : /* Adds 5 rules and look them up */
1380 : :
1381 : : IPv6(ip_batch[0], 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1382 : 1 : depth[0] = 48;
1383 : : next_hop_add = 101;
1384 : :
1385 : 1 : status = rte_lpm6_add(lpm, ip_batch[0], depth[0], next_hop_add);
1386 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1387 : :
1388 : : IPv6(ip_batch[1], 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1389 : 1 : depth[1] = 48;
1390 : : next_hop_add = 102;
1391 : :
1392 : 1 : status = rte_lpm6_add(lpm, ip_batch[1], depth[1], next_hop_add);
1393 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1394 : :
1395 : : IPv6(ip_batch[2], 128, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1396 : 1 : depth[2] = 48;
1397 : : next_hop_add = 103;
1398 : :
1399 : 1 : status = rte_lpm6_add(lpm, ip_batch[2], depth[2], next_hop_add);
1400 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1401 : :
1402 : : IPv6(ip_batch[3], 128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1403 : 1 : depth[3] = 48;
1404 : : next_hop_add = 104;
1405 : :
1406 : 1 : status = rte_lpm6_add(lpm, ip_batch[3], depth[3], next_hop_add);
1407 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1408 : :
1409 : : IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1410 : 1 : depth[4] = 48;
1411 : : next_hop_add = 105;
1412 : :
1413 : 1 : status = rte_lpm6_add(lpm, ip_batch[4], depth[4], next_hop_add);
1414 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1415 : :
1416 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1417 : : next_hop_return, 5);
1418 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == 101
+ - + - +
- - + ]
1419 : : && next_hop_return[1] == 102 && next_hop_return[2] == 103
1420 : : && next_hop_return[3] == 104 && next_hop_return[4] == 105);
1421 : :
1422 : : /* Use the delete_bulk function to delete two of them. Lookup again */
1423 : :
1424 : 1 : status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[0], depth, 2);
1425 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1426 : :
1427 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1428 : : next_hop_return, 5);
1429 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+ - + - +
- - + ]
1430 : : && next_hop_return[1] == -1 && next_hop_return[2] == 103
1431 : : && next_hop_return[3] == 104 && next_hop_return[4] == 105);
1432 : :
1433 : : /* Use the delete_bulk function to delete one more. Lookup again */
1434 : :
1435 : 1 : status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[2], depth, 1);
1436 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1437 : :
1438 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1439 : : next_hop_return, 5);
1440 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+ - + - +
- - + ]
1441 : : && next_hop_return[1] == -1 && next_hop_return[2] == -1
1442 : : && next_hop_return[3] == 104 && next_hop_return[4] == 105);
1443 : :
1444 : : /* Use the delete_bulk function to delete two, one invalid. Lookup again */
1445 : :
1446 : : IPv6(ip_batch[4], 128, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1447 : 1 : status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[3], depth, 2);
1448 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1449 : :
1450 : : IPv6(ip_batch[4], 128, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1451 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1452 : : next_hop_return, 5);
1453 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+ - + - +
- - + ]
1454 : : && next_hop_return[1] == -1 && next_hop_return[2] == -1
1455 : : && next_hop_return[3] == -1 && next_hop_return[4] == 105);
1456 : :
1457 : : /* Use the delete_bulk function to delete the remaining one. Lookup again */
1458 : :
1459 : 1 : status = rte_lpm6_delete_bulk_func(lpm, &ip_batch[4], depth, 1);
1460 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1461 : :
1462 : 1 : status = rte_lpm6_lookup_bulk_func(lpm, ip_batch,
1463 : : next_hop_return, 5);
1464 [ + - + - : 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return[0] == -1
+ - + - +
- - + ]
1465 : : && next_hop_return[1] == -1 && next_hop_return[2] == -1
1466 : : && next_hop_return[3] == -1 && next_hop_return[4] == -1);
1467 : :
1468 : 1 : rte_lpm6_free(lpm);
1469 : :
1470 : 1 : return PASS;
1471 : : }
1472 : :
1473 : : /*
1474 : : * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete,
1475 : : * lookup (miss) in a for loop of 30 times. This will check tbl8 extension
1476 : : * and contraction.
1477 : : */
1478 : : int32_t
1479 : 1 : test23(void)
1480 : : {
1481 : : struct rte_lpm6 *lpm = NULL;
1482 : : struct rte_lpm6_config config;
1483 : : uint32_t i;
1484 : : uint8_t ip[16];
1485 : : uint8_t depth;
1486 : : uint32_t next_hop_add, next_hop_return;
1487 : : int32_t status = 0;
1488 : :
1489 : 1 : config.max_rules = MAX_RULES;
1490 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1491 : 1 : config.flags = 0;
1492 : :
1493 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1494 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1495 : :
1496 : : IPv6(ip, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1497 : : depth = 128;
1498 : : next_hop_add = 100;
1499 : :
1500 [ + + ]: 31 : for (i = 0; i < 30; i++) {
1501 : 30 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1502 [ - + ]: 30 : TEST_LPM_ASSERT(status == 0);
1503 : :
1504 : 30 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1505 [ + - - + ]: 30 : TEST_LPM_ASSERT((status == 0) &&
1506 : : (next_hop_return == next_hop_add));
1507 : :
1508 : 30 : status = rte_lpm6_delete(lpm, ip, depth);
1509 [ - + ]: 30 : TEST_LPM_ASSERT(status == 0);
1510 : :
1511 : 30 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1512 [ - + ]: 30 : TEST_LPM_ASSERT(status == -ENOENT);
1513 : : }
1514 : :
1515 : 1 : rte_lpm6_free(lpm);
1516 : :
1517 : 1 : return PASS;
1518 : : }
1519 : :
1520 : : /*
1521 : : * Sequence of operations for find existing lpm table
1522 : : *
1523 : : * - create table
1524 : : * - find existing table: hit
1525 : : * - find non-existing table: miss
1526 : : */
1527 : : int32_t
1528 : 1 : test24(void)
1529 : : {
1530 : : struct rte_lpm6 *lpm = NULL, *result = NULL;
1531 : : struct rte_lpm6_config config;
1532 : :
1533 : 1 : config.max_rules = 256 * 32;
1534 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1535 : 1 : config.flags = 0;
1536 : :
1537 : : /* Create lpm */
1538 : 1 : lpm = rte_lpm6_create("lpm_find_existing", SOCKET_ID_ANY, &config);
1539 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1540 : :
1541 : : /* Try to find existing lpm */
1542 : 1 : result = rte_lpm6_find_existing("lpm_find_existing");
1543 [ - + ]: 1 : TEST_LPM_ASSERT(result == lpm);
1544 : :
1545 : : /* Try to find non-existing lpm */
1546 : 1 : result = rte_lpm6_find_existing("lpm_find_non_existing");
1547 [ - + ]: 1 : TEST_LPM_ASSERT(result == NULL);
1548 : :
1549 : : /* Cleanup. */
1550 : 1 : rte_lpm6_delete_all(lpm);
1551 : 1 : rte_lpm6_free(lpm);
1552 : :
1553 : 1 : return PASS;
1554 : : }
1555 : :
1556 : : /*
1557 : : * Add a set of random routes with random depths.
1558 : : * Lookup different IP addresses that match the routes previously added.
1559 : : * Checks that the next hop is the expected one.
1560 : : * The routes, IP addresses and expected result for every case have been
1561 : : * precalculated by using a python script and stored in a .h file.
1562 : : */
1563 : : int32_t
1564 : 1 : test25(void)
1565 : : {
1566 : : struct rte_lpm6 *lpm = NULL;
1567 : : struct rte_lpm6_config config;
1568 : : uint8_t ip[16];
1569 : : uint32_t i;
1570 : : uint8_t depth;
1571 : : uint32_t next_hop_add, next_hop_return, next_hop_expected;
1572 : : int32_t status = 0;
1573 : :
1574 : 1 : config.max_rules = MAX_RULES;
1575 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1576 : 1 : config.flags = 0;
1577 : :
1578 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1579 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1580 : :
1581 [ + + ]: 1001 : for (i = 0; i < 1000; i++) {
1582 : 1000 : memcpy(ip, large_route_table[i].ip, 16);
1583 : 1000 : depth = large_route_table[i].depth;
1584 : 1000 : next_hop_add = large_route_table[i].next_hop;
1585 : 1000 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1586 [ - + ]: 1000 : TEST_LPM_ASSERT(status == 0);
1587 : : }
1588 : :
1589 : : /* generate large IPS table and expected next_hops */
1590 : 1 : generate_large_ips_table(1);
1591 : :
1592 [ + + ]: 100001 : for (i = 0; i < 100000; i++) {
1593 : 100000 : memcpy(ip, large_ips_table[i].ip, 16);
1594 : 100000 : next_hop_expected = large_ips_table[i].next_hop;
1595 : :
1596 : 100000 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1597 [ + - - + ]: 100000 : TEST_LPM_ASSERT((status == 0) &&
1598 : : (next_hop_return == next_hop_expected));
1599 : : }
1600 : :
1601 : 1 : rte_lpm6_free(lpm);
1602 : :
1603 : 1 : return PASS;
1604 : : }
1605 : :
1606 : : /*
1607 : : * Test for overwriting of tbl8:
1608 : : * - add rule /32 and lookup
1609 : : * - add new rule /24 and lookup
1610 : : * - add third rule /25 and lookup
1611 : : * - lookup /32 and /24 rule to ensure the table has not been overwritten.
1612 : : */
1613 : : int32_t
1614 : 1 : test26(void)
1615 : : {
1616 : : struct rte_lpm6 *lpm = NULL;
1617 : : struct rte_lpm6_config config;
1618 : 1 : uint8_t ip_10_32[] = {10, 10, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1619 : 1 : uint8_t ip_10_24[] = {10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1620 : 1 : uint8_t ip_20_25[] = {10, 10, 20, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1621 : : uint8_t d_ip_10_32 = 32;
1622 : : uint8_t d_ip_10_24 = 24;
1623 : : uint8_t d_ip_20_25 = 25;
1624 : : uint32_t next_hop_ip_10_32 = 100;
1625 : : uint32_t next_hop_ip_10_24 = 105;
1626 : : uint32_t next_hop_ip_20_25 = 111;
1627 : 1 : uint32_t next_hop_return = 0;
1628 : : int32_t status = 0;
1629 : :
1630 : 1 : config.max_rules = MAX_RULES;
1631 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1632 : 1 : config.flags = 0;
1633 : :
1634 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1635 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1636 : :
1637 [ + - ]: 1 : if ((status = rte_lpm6_add(lpm, ip_10_32, d_ip_10_32,
1638 : : next_hop_ip_10_32)) < 0)
1639 : : return -1;
1640 : :
1641 : 1 : status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return);
1642 : 1 : uint32_t test_hop_10_32 = next_hop_return;
1643 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1644 [ - + ]: 1 : TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
1645 : :
1646 [ + - ]: 1 : if ((status = rte_lpm6_add(lpm, ip_10_24, d_ip_10_24,
1647 : : next_hop_ip_10_24)) < 0)
1648 : : return -1;
1649 : :
1650 : 1 : status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return);
1651 : 1 : uint32_t test_hop_10_24 = next_hop_return;
1652 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1653 [ - + ]: 1 : TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
1654 : :
1655 [ + - ]: 1 : if ((status = rte_lpm6_add(lpm, ip_20_25, d_ip_20_25,
1656 : : next_hop_ip_20_25)) < 0)
1657 : : return -1;
1658 : :
1659 : 1 : status = rte_lpm6_lookup(lpm, ip_20_25, &next_hop_return);
1660 : 1 : uint32_t test_hop_20_25 = next_hop_return;
1661 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1662 [ - + ]: 1 : TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25);
1663 : :
1664 : : if (test_hop_10_32 == test_hop_10_24) {
1665 : : printf("Next hop return equal\n");
1666 : : return -1;
1667 : : }
1668 : :
1669 : : if (test_hop_10_24 == test_hop_20_25){
1670 : : printf("Next hop return equal\n");
1671 : : return -1;
1672 : : }
1673 : :
1674 : 1 : status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return);
1675 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1676 [ - + ]: 1 : TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32);
1677 : :
1678 : 1 : status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return);
1679 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1680 [ - + ]: 1 : TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24);
1681 : :
1682 : 1 : rte_lpm6_free(lpm);
1683 : :
1684 : 1 : return PASS;
1685 : : }
1686 : :
1687 : : /*
1688 : : * Add a rule that reaches the end of the tree.
1689 : : * Add a rule that is more generic than the first one.
1690 : : * Check every possible combination that produces a match for the second rule.
1691 : : * This tests tbl expansion.
1692 : : */
1693 : : int32_t
1694 : 1 : test27(void)
1695 : : {
1696 : : struct rte_lpm6 *lpm = NULL;
1697 : : struct rte_lpm6_config config;
1698 : 1 : uint8_t ip[] = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,0};
1699 : : uint8_t depth = 128;
1700 : : uint32_t next_hop_add = 100, next_hop_return;
1701 : : int32_t status = 0;
1702 : : int i, j;
1703 : :
1704 : 1 : config.max_rules = MAX_RULES;
1705 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1706 : 1 : config.flags = 0;
1707 : :
1708 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1709 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1710 : :
1711 : : depth = 128;
1712 : : next_hop_add = 128;
1713 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1714 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1715 : :
1716 : : depth = 112;
1717 : : next_hop_add = 112;
1718 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1719 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1720 : :
1721 [ + + ]: 257 : for (i = 0; i < 256; i++) {
1722 : 256 : ip[14] = (uint8_t)i;
1723 [ + + ]: 65792 : for (j = 0; j < 256; j++) {
1724 : 65536 : ip[15] = (uint8_t)j;
1725 : 65536 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1726 [ + + ]: 65536 : if (i == 0 && j == 0)
1727 [ + - - + ]: 1 : TEST_LPM_ASSERT(status == 0 && next_hop_return == 128);
1728 : : else
1729 [ + - - + ]: 65535 : TEST_LPM_ASSERT(status == 0 && next_hop_return == 112);
1730 : : }
1731 : : }
1732 : :
1733 : 1 : rte_lpm6_free(lpm);
1734 : :
1735 : 1 : return PASS;
1736 : : }
1737 : :
1738 : : /*
1739 : : * Call add, lookup and delete for a single rule with maximum 21bit next_hop
1740 : : * size.
1741 : : * Check that next_hop returned from lookup is equal to provisioned value.
1742 : : * Delete the rule and check that the same test returns a miss.
1743 : : */
1744 : : int32_t
1745 : 1 : test28(void)
1746 : : {
1747 : : struct rte_lpm6 *lpm = NULL;
1748 : : struct rte_lpm6_config config;
1749 : 1 : uint8_t ip[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1750 : : uint8_t depth = 16;
1751 : 1 : uint32_t next_hop_add = 0x001FFFFF, next_hop_return = 0;
1752 : : int32_t status = 0;
1753 : :
1754 : 1 : config.max_rules = MAX_RULES;
1755 : 1 : config.number_tbl8s = NUMBER_TBL8S;
1756 : 1 : config.flags = 0;
1757 : :
1758 : 1 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
1759 [ - + ]: 1 : TEST_LPM_ASSERT(lpm != NULL);
1760 : :
1761 : 1 : status = rte_lpm6_add(lpm, ip, depth, next_hop_add);
1762 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1763 : :
1764 : 1 : status = rte_lpm6_lookup(lpm, ip, &next_hop_return);
1765 [ + - - + ]: 1 : TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add));
1766 : :
1767 : 1 : status = rte_lpm6_delete(lpm, ip, depth);
1768 [ - + ]: 1 : TEST_LPM_ASSERT(status == 0);
1769 : 1 : rte_lpm6_free(lpm);
1770 : :
1771 : 1 : return PASS;
1772 : : }
1773 : :
1774 : : /*
1775 : : * Do all unit tests.
1776 : : */
1777 : : static int
1778 : 1 : test_lpm6(void)
1779 : : {
1780 : : unsigned i;
1781 : : int status = -1, global_status = 0;
1782 : :
1783 [ + + ]: 30 : for (i = 0; i < RTE_DIM(tests6); i++) {
1784 : : printf("# test %02d\n", i);
1785 : 29 : status = tests6[i]();
1786 : :
1787 [ - + ]: 29 : if (status < 0) {
1788 : : printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests6[i]));
1789 : : global_status = status;
1790 : : }
1791 : : }
1792 : :
1793 : 1 : return global_status;
1794 : : }
1795 : :
1796 : 238 : REGISTER_FAST_TEST(lpm6_autotest, true, true, test_lpm6);
|