1
2
3
4
5
6#include <stdio.h>
7#include <stdint.h>
8#include <stdlib.h>
9
10#include <rte_memory.h>
11#include <rte_log.h>
12
13#include "test.h"
14
15#ifdef RTE_EXEC_ENV_WINDOWS
16static int
17test_fib6(void)
18{
19 printf("fib not supported on Windows, skipping test\n");
20 return TEST_SKIPPED;
21}
22
23static int
24test_slow_fib6(void)
25{
26 printf("slow_fib not supported on Windows, skipping test\n");
27 return TEST_SKIPPED;
28}
29
30#else
31
32#include <rte_rib6.h>
33#include <rte_fib6.h>
34
35typedef int32_t (*rte_fib6_test)(void);
36
37static int32_t test_create_invalid(void);
38static int32_t test_multiple_create(void);
39static int32_t test_free_null(void);
40static int32_t test_add_del_invalid(void);
41static int32_t test_get_invalid(void);
42static int32_t test_lookup(void);
43
44#define MAX_ROUTES (1 << 16)
45
46#define MAX_TBL8 (1 << 15)
47
48
49
50
51
52int32_t
53test_create_invalid(void)
54{
55 struct rte_fib6 *fib = NULL;
56 struct rte_fib6_conf config;
57
58 config.max_routes = MAX_ROUTES;
59 config.rib_ext_sz = 0;
60 config.default_nh = 0;
61 config.type = RTE_FIB6_DUMMY;
62
63
64 fib = rte_fib6_create(NULL, SOCKET_ID_ANY, &config);
65 RTE_TEST_ASSERT(fib == NULL,
66 "Call succeeded with invalid parameters\n");
67
68
69 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, NULL);
70 RTE_TEST_ASSERT(fib == NULL,
71 "Call succeeded with invalid parameters\n");
72
73
74 fib = rte_fib6_create(__func__, -2, &config);
75 RTE_TEST_ASSERT(fib == NULL,
76 "Call succeeded with invalid parameters\n");
77
78
79 config.max_routes = 0;
80 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
81 RTE_TEST_ASSERT(fib == NULL,
82 "Call succeeded with invalid parameters\n");
83 config.max_routes = MAX_ROUTES;
84
85 config.type = RTE_FIB6_TRIE + 1;
86 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
87 RTE_TEST_ASSERT(fib == NULL,
88 "Call succeeded with invalid parameters\n");
89
90 config.type = RTE_FIB6_TRIE;
91 config.trie.num_tbl8 = MAX_TBL8;
92
93 config.trie.nh_sz = RTE_FIB6_TRIE_8B + 1;
94 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
95 RTE_TEST_ASSERT(fib == NULL,
96 "Call succeeded with invalid parameters\n");
97 config.trie.nh_sz = RTE_FIB6_TRIE_8B;
98
99 config.trie.num_tbl8 = 0;
100 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
101 RTE_TEST_ASSERT(fib == NULL,
102 "Call succeeded with invalid parameters\n");
103
104 return TEST_SUCCESS;
105}
106
107
108
109
110
111int32_t
112test_multiple_create(void)
113{
114 struct rte_fib6 *fib = NULL;
115 struct rte_fib6_conf config;
116 int32_t i;
117
118 config.rib_ext_sz = 0;
119 config.default_nh = 0;
120 config.type = RTE_FIB6_DUMMY;
121
122 for (i = 0; i < 100; i++) {
123 config.max_routes = MAX_ROUTES - i;
124 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
125 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
126 rte_fib6_free(fib);
127 }
128
129 return TEST_SUCCESS;
130}
131
132
133
134
135
136
137
138int32_t
139test_free_null(void)
140{
141 struct rte_fib6 *fib = NULL;
142 struct rte_fib6_conf config;
143
144 config.max_routes = MAX_ROUTES;
145 config.rib_ext_sz = 0;
146 config.default_nh = 0;
147 config.type = RTE_FIB6_DUMMY;
148
149 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
150 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
151
152 rte_fib6_free(fib);
153 rte_fib6_free(NULL);
154
155 return TEST_SUCCESS;
156}
157
158
159
160
161
162int32_t
163test_add_del_invalid(void)
164{
165 struct rte_fib6 *fib = NULL;
166 struct rte_fib6_conf config;
167 uint64_t nh = 100;
168 uint8_t ip[RTE_FIB6_IPV6_ADDR_SIZE] = {0};
169 int ret;
170 uint8_t depth = 24;
171
172 config.max_routes = MAX_ROUTES;
173 config.rib_ext_sz = 0;
174 config.default_nh = 0;
175 config.type = RTE_FIB6_DUMMY;
176
177
178 ret = rte_fib6_add(NULL, ip, depth, nh);
179 RTE_TEST_ASSERT(ret < 0,
180 "Call succeeded with invalid parameters\n");
181
182
183 ret = rte_fib6_delete(NULL, ip, depth);
184 RTE_TEST_ASSERT(ret < 0,
185 "Call succeeded with invalid parameters\n");
186
187
188 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
189 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
190
191
192 ret = rte_fib6_add(fib, ip, RTE_FIB6_MAXDEPTH + 1, nh);
193 RTE_TEST_ASSERT(ret < 0,
194 "Call succeeded with invalid parameters\n");
195
196
197 ret = rte_fib6_delete(fib, ip, RTE_FIB6_MAXDEPTH + 1);
198 RTE_TEST_ASSERT(ret < 0,
199 "Call succeeded with invalid parameters\n");
200
201 rte_fib6_free(fib);
202
203 return TEST_SUCCESS;
204}
205
206
207
208
209
210int32_t
211test_get_invalid(void)
212{
213 void *p;
214
215 p = rte_fib6_get_dp(NULL);
216 RTE_TEST_ASSERT(p == NULL,
217 "Call succeeded with invalid parameters\n");
218
219 p = rte_fib6_get_rib(NULL);
220 RTE_TEST_ASSERT(p == NULL,
221 "Call succeeded with invalid parameters\n");
222
223 return TEST_SUCCESS;
224}
225
226
227
228
229
230
231static int
232lookup_and_check_asc(struct rte_fib6 *fib,
233 uint8_t ip_arr[RTE_FIB6_MAXDEPTH][RTE_FIB6_IPV6_ADDR_SIZE],
234 uint8_t ip_missing[][RTE_FIB6_IPV6_ADDR_SIZE], uint64_t def_nh,
235 uint32_t n)
236{
237 uint64_t nh_arr[RTE_FIB6_MAXDEPTH];
238 int ret;
239 uint32_t i = 0;
240
241 ret = rte_fib6_lookup_bulk(fib, ip_arr, nh_arr, RTE_FIB6_MAXDEPTH);
242 RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n");
243
244 for (; i <= RTE_FIB6_MAXDEPTH - n; i++)
245 RTE_TEST_ASSERT(nh_arr[i] == n,
246 "Failed to get proper nexthop\n");
247
248 for (; i < RTE_FIB6_MAXDEPTH; i++)
249 RTE_TEST_ASSERT(nh_arr[i] == --n,
250 "Failed to get proper nexthop\n");
251
252 ret = rte_fib6_lookup_bulk(fib, ip_missing, nh_arr, 1);
253 RTE_TEST_ASSERT((ret == 0) && (nh_arr[0] == def_nh),
254 "Failed to get proper nexthop\n");
255
256 return TEST_SUCCESS;
257}
258
259static int
260lookup_and_check_desc(struct rte_fib6 *fib,
261 uint8_t ip_arr[RTE_FIB6_MAXDEPTH][RTE_FIB6_IPV6_ADDR_SIZE],
262 uint8_t ip_missing[][RTE_FIB6_IPV6_ADDR_SIZE], uint64_t def_nh,
263 uint32_t n)
264{
265 uint64_t nh_arr[RTE_FIB6_MAXDEPTH];
266 int ret;
267 uint32_t i = 0;
268
269 ret = rte_fib6_lookup_bulk(fib, ip_arr, nh_arr, RTE_FIB6_MAXDEPTH);
270 RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n");
271
272 for (; i < n; i++)
273 RTE_TEST_ASSERT(nh_arr[i] == RTE_FIB6_MAXDEPTH - i,
274 "Failed to get proper nexthop\n");
275
276 for (; i < RTE_FIB6_MAXDEPTH; i++)
277 RTE_TEST_ASSERT(nh_arr[i] == def_nh,
278 "Failed to get proper nexthop\n");
279
280 ret = rte_fib6_lookup_bulk(fib, ip_missing, nh_arr, 1);
281 RTE_TEST_ASSERT((ret == 0) && (nh_arr[0] == def_nh),
282 "Failed to get proper nexthop\n");
283
284 return TEST_SUCCESS;
285}
286
287static int
288check_fib(struct rte_fib6 *fib)
289{
290 uint64_t def_nh = 100;
291 uint8_t ip_arr[RTE_FIB6_MAXDEPTH][RTE_FIB6_IPV6_ADDR_SIZE];
292 uint8_t ip_add[RTE_FIB6_IPV6_ADDR_SIZE] = {0};
293 uint8_t ip_missing[1][RTE_FIB6_IPV6_ADDR_SIZE] = { {255} };
294 uint32_t i, j;
295 int ret;
296
297 ip_add[0] = 128;
298 ip_missing[0][0] = 127;
299 for (i = 0; i < RTE_FIB6_MAXDEPTH; i++) {
300 for (j = 0; j < RTE_FIB6_IPV6_ADDR_SIZE; j++) {
301 ip_arr[i][j] = ip_add[j] |
302 ~get_msk_part(RTE_FIB6_MAXDEPTH - i, j);
303 }
304 }
305
306 ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh, 0);
307 RTE_TEST_ASSERT(ret == TEST_SUCCESS, "Lookup and check fails\n");
308
309 for (i = 1; i <= RTE_FIB6_MAXDEPTH; i++) {
310 ret = rte_fib6_add(fib, ip_add, i, i);
311 RTE_TEST_ASSERT(ret == 0, "Failed to add a route\n");
312 ret = lookup_and_check_asc(fib, ip_arr, ip_missing, def_nh, i);
313 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
314 "Lookup and check fails\n");
315 }
316
317 for (i = RTE_FIB6_MAXDEPTH; i > 1; i--) {
318 ret = rte_fib6_delete(fib, ip_add, i);
319 RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n");
320 ret = lookup_and_check_asc(fib, ip_arr, ip_missing,
321 def_nh, i - 1);
322
323 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
324 "Lookup and check fails\n");
325 }
326 ret = rte_fib6_delete(fib, ip_add, i);
327 RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n");
328 ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh, 0);
329 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
330 "Lookup and check fails\n");
331
332 for (i = 0; i < RTE_FIB6_MAXDEPTH; i++) {
333 ret = rte_fib6_add(fib, ip_add, RTE_FIB6_MAXDEPTH - i,
334 RTE_FIB6_MAXDEPTH - i);
335 RTE_TEST_ASSERT(ret == 0, "Failed to add a route\n");
336 ret = lookup_and_check_desc(fib, ip_arr, ip_missing,
337 def_nh, i + 1);
338 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
339 "Lookup and check fails\n");
340 }
341
342 for (i = 1; i <= RTE_FIB6_MAXDEPTH; i++) {
343 ret = rte_fib6_delete(fib, ip_add, i);
344 RTE_TEST_ASSERT(ret == 0, "Failed to delete a route\n");
345 ret = lookup_and_check_desc(fib, ip_arr, ip_missing, def_nh,
346 RTE_FIB6_MAXDEPTH - i);
347 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
348 "Lookup and check fails\n");
349 }
350
351 return TEST_SUCCESS;
352}
353
354int32_t
355test_lookup(void)
356{
357 struct rte_fib6 *fib = NULL;
358 struct rte_fib6_conf config;
359 uint64_t def_nh = 100;
360 int ret;
361
362 config.max_routes = MAX_ROUTES;
363 config.rib_ext_sz = 0;
364 config.default_nh = def_nh;
365 config.type = RTE_FIB6_DUMMY;
366
367 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
368 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
369 ret = check_fib(fib);
370 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
371 "Check_fib fails for DUMMY type\n");
372 rte_fib6_free(fib);
373
374 config.type = RTE_FIB6_TRIE;
375
376 config.trie.nh_sz = RTE_FIB6_TRIE_2B;
377 config.trie.num_tbl8 = MAX_TBL8 - 1;
378 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
379 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
380 ret = check_fib(fib);
381 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
382 "Check_fib fails for TRIE_2B type\n");
383 rte_fib6_free(fib);
384
385 config.trie.nh_sz = RTE_FIB6_TRIE_4B;
386 config.trie.num_tbl8 = MAX_TBL8;
387 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
388 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
389 ret = check_fib(fib);
390 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
391 "Check_fib fails for TRIE_4B type\n");
392 rte_fib6_free(fib);
393
394 config.trie.nh_sz = RTE_FIB6_TRIE_8B;
395 config.trie.num_tbl8 = MAX_TBL8;
396 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &config);
397 RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
398 ret = check_fib(fib);
399 RTE_TEST_ASSERT(ret == TEST_SUCCESS,
400 "Check_fib fails for TRIE_8B type\n");
401 rte_fib6_free(fib);
402
403 return TEST_SUCCESS;
404}
405
406static struct unit_test_suite fib6_fast_tests = {
407 .suite_name = "fib6 autotest",
408 .setup = NULL,
409 .teardown = NULL,
410 .unit_test_cases = {
411 TEST_CASE(test_create_invalid),
412 TEST_CASE(test_free_null),
413 TEST_CASE(test_add_del_invalid),
414 TEST_CASE(test_get_invalid),
415 TEST_CASE(test_lookup),
416 TEST_CASES_END()
417 }
418};
419
420static struct unit_test_suite fib6_slow_tests = {
421 .suite_name = "fib6 slow autotest",
422 .setup = NULL,
423 .teardown = NULL,
424 .unit_test_cases = {
425 TEST_CASE(test_multiple_create),
426 TEST_CASES_END()
427 }
428};
429
430
431
432
433static int
434test_fib6(void)
435{
436 return unit_test_suite_runner(&fib6_fast_tests);
437}
438
439static int
440test_slow_fib6(void)
441{
442 return unit_test_suite_runner(&fib6_slow_tests);
443}
444
445#endif
446
447REGISTER_TEST_COMMAND(fib6_autotest, test_fib6);
448REGISTER_TEST_COMMAND(fib6_slow_autotest, test_slow_fib6);
449