Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com>
3 : : * Copyright(c) 2019 Intel Corporation
4 : : */
5 : :
6 : : #include <stdio.h>
7 : : #include <stdint.h>
8 : : #include <stdlib.h>
9 : : #include <rte_ip6.h>
10 : : #include <rte_rib6.h>
11 : :
12 : : #include "test.h"
13 : :
14 : : typedef int32_t (*rte_rib6_test)(void);
15 : :
16 : : static int32_t test_create_invalid(void);
17 : : static int32_t test_multiple_create(void);
18 : : static int32_t test_free_null(void);
19 : : static int32_t test_insert_invalid(void);
20 : : static int32_t test_get_fn(void);
21 : : static int32_t test_basic(void);
22 : : static int32_t test_tree_traversal(void);
23 : :
24 : : #define MAX_DEPTH 128
25 : : #define MAX_RULES (1 << 22)
26 : :
27 : : /*
28 : : * Check that rte_rib6_create fails gracefully for incorrect user input
29 : : * arguments
30 : : */
31 : : int32_t
32 : 1 : test_create_invalid(void)
33 : : {
34 : : struct rte_rib6 *rib = NULL;
35 : : struct rte_rib6_conf config;
36 : :
37 : 1 : config.max_nodes = MAX_RULES;
38 : 1 : config.ext_sz = 0;
39 : :
40 : : /* rte_rib6_create: rib name == NULL */
41 : 1 : rib = rte_rib6_create(NULL, SOCKET_ID_ANY, &config);
42 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
43 : : "Call succeeded with invalid parameters\n");
44 : :
45 : : /* rte_rib6_create: config == NULL */
46 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, NULL);
47 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
48 : : "Call succeeded with invalid parameters\n");
49 : :
50 : : /* socket_id < -1 is invalid */
51 : 1 : rib = rte_rib6_create(__func__, -2, &config);
52 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
53 : : "Call succeeded with invalid parameters\n");
54 : :
55 : : /* rte_rib6_create: max_nodes = 0 */
56 : 1 : config.max_nodes = 0;
57 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
58 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
59 : : "Call succeeded with invalid parameters\n");
60 : : config.max_nodes = MAX_RULES;
61 : :
62 : : return TEST_SUCCESS;
63 : : }
64 : :
65 : : /*
66 : : * Create rib table then delete rib table 10 times
67 : : * Use a slightly different rules size each time
68 : : */
69 : : int32_t
70 : 0 : test_multiple_create(void)
71 : : {
72 : : struct rte_rib6 *rib = NULL;
73 : : struct rte_rib6_conf config;
74 : : int32_t i;
75 : :
76 : 0 : config.ext_sz = 0;
77 : :
78 [ # # ]: 0 : for (i = 0; i < 100; i++) {
79 : 0 : config.max_nodes = MAX_RULES - i;
80 : 0 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
81 [ # # ]: 0 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
82 : 0 : rte_rib6_free(rib);
83 : : }
84 : : /* Can not test free so return success */
85 : : return TEST_SUCCESS;
86 : : }
87 : :
88 : : /*
89 : : * Call rte_rib6_free for NULL pointer user input. Note: free has no return and
90 : : * therefore it is impossible to check for failure but this test is added to
91 : : * increase function coverage metrics and to validate that freeing null does
92 : : * not crash.
93 : : */
94 : : int32_t
95 : 1 : test_free_null(void)
96 : : {
97 : : struct rte_rib6 *rib = NULL;
98 : : struct rte_rib6_conf config;
99 : :
100 : 1 : config.max_nodes = MAX_RULES;
101 : 1 : config.ext_sz = 0;
102 : :
103 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
104 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
105 : :
106 : 1 : rte_rib6_free(rib);
107 : 1 : rte_rib6_free(NULL);
108 : 1 : return TEST_SUCCESS;
109 : : }
110 : :
111 : : /*
112 : : * Check that rte_rib6_insert fails gracefully
113 : : * for incorrect user input arguments
114 : : */
115 : : int32_t
116 : 1 : test_insert_invalid(void)
117 : : {
118 : : struct rte_rib6 *rib = NULL;
119 : : struct rte_rib6_node *node, *node1;
120 : : struct rte_rib6_conf config;
121 : 1 : struct rte_ipv6_addr ip = {0};
122 : : uint8_t depth = 24;
123 : :
124 : 1 : config.max_nodes = MAX_RULES;
125 : 1 : config.ext_sz = 0;
126 : :
127 : : /* rte_rib6_insert: rib == NULL */
128 : 1 : node = rte_rib6_insert(NULL, &ip, depth);
129 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
130 : : "Call succeeded with invalid parameters\n");
131 : :
132 : : /*Create valid rib to use in rest of test. */
133 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
134 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
135 : :
136 : : /* rte_rib6_insert: depth > MAX_DEPTH */
137 : 1 : node = rte_rib6_insert(rib, &ip, MAX_DEPTH + 1);
138 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
139 : : "Call succeeded with invalid parameters\n");
140 : :
141 : : /* insert the same ip/depth twice*/
142 : 1 : node = rte_rib6_insert(rib, &ip, depth);
143 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
144 : 1 : node1 = rte_rib6_insert(rib, &ip, depth);
145 [ - + ]: 1 : RTE_TEST_ASSERT(node1 == NULL,
146 : : "Call succeeded with invalid parameters\n");
147 : :
148 : 1 : rte_rib6_free(rib);
149 : :
150 : 1 : return TEST_SUCCESS;
151 : : }
152 : :
153 : : /*
154 : : * Call rte_rib6_node access functions with incorrect input.
155 : : * After call rte_rib6_node access functions with correct args
156 : : * and check the return values for correctness
157 : : */
158 : : int32_t
159 : 1 : test_get_fn(void)
160 : : {
161 : : struct rte_rib6 *rib = NULL;
162 : : struct rte_rib6_node *node;
163 : : struct rte_rib6_conf config;
164 : : void *ext;
165 : 1 : struct rte_ipv6_addr ip = RTE_IPV6(0xc000, 0x0200, 0, 0, 0, 0, 0, 0);
166 : : struct rte_ipv6_addr ip_ret;
167 : : uint64_t nh_set = 10;
168 : : uint64_t nh_ret;
169 : : uint8_t depth = 24;
170 : : uint8_t depth_ret;
171 : : int ret;
172 : :
173 : 1 : config.max_nodes = MAX_RULES;
174 : 1 : config.ext_sz = 0;
175 : :
176 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
177 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
178 : :
179 : 1 : node = rte_rib6_insert(rib, &ip, depth);
180 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
181 : :
182 : : /* test rte_rib6_get_ip() with incorrect args */
183 : 1 : ret = rte_rib6_get_ip(NULL, &ip_ret);
184 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
185 : : "Call succeeded with invalid parameters\n");
186 : 1 : ret = rte_rib6_get_ip(node, NULL);
187 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
188 : : "Call succeeded with invalid parameters\n");
189 : :
190 : : /* test rte_rib6_get_depth() with incorrect args */
191 : 1 : ret = rte_rib6_get_depth(NULL, &depth_ret);
192 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
193 : : "Call succeeded with invalid parameters\n");
194 : 1 : ret = rte_rib6_get_depth(node, NULL);
195 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
196 : : "Call succeeded with invalid parameters\n");
197 : :
198 : : /* test rte_rib6_set_nh() with incorrect args */
199 : 1 : ret = rte_rib6_set_nh(NULL, nh_set);
200 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
201 : : "Call succeeded with invalid parameters\n");
202 : :
203 : : /* test rte_rib6_get_nh() with incorrect args */
204 : 1 : ret = rte_rib6_get_nh(NULL, &nh_ret);
205 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
206 : : "Call succeeded with invalid parameters\n");
207 : 1 : ret = rte_rib6_get_nh(node, NULL);
208 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
209 : : "Call succeeded with invalid parameters\n");
210 : :
211 : : /* test rte_rib6_get_ext() with incorrect args */
212 : 1 : ext = rte_rib6_get_ext(NULL);
213 [ - + ]: 1 : RTE_TEST_ASSERT(ext == NULL,
214 : : "Call succeeded with invalid parameters\n");
215 : :
216 : : /* check the return values */
217 : 1 : ret = rte_rib6_get_ip(node, &ip_ret);
218 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (rte_ipv6_addr_eq(&ip_ret, &ip)),
219 : : "Failed to get proper node ip\n");
220 : 1 : ret = rte_rib6_get_depth(node, &depth_ret);
221 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (depth_ret == depth),
222 : : "Failed to get proper node depth\n");
223 : 1 : ret = rte_rib6_set_nh(node, nh_set);
224 [ - + ]: 1 : RTE_TEST_ASSERT(ret == 0,
225 : : "Failed to set rte_rib_node nexthop\n");
226 : 1 : ret = rte_rib6_get_nh(node, &nh_ret);
227 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (nh_ret == nh_set),
228 : : "Failed to get proper nexthop\n");
229 : :
230 : 1 : rte_rib6_free(rib);
231 : :
232 : 1 : return TEST_SUCCESS;
233 : : }
234 : :
235 : : /*
236 : : * Call insert, lookup/lookup_exact and delete for a single rule
237 : : */
238 : : int32_t
239 : 1 : test_basic(void)
240 : : {
241 : : struct rte_rib6 *rib = NULL;
242 : : struct rte_rib6_node *node;
243 : : struct rte_rib6_conf config;
244 : :
245 : 1 : struct rte_ipv6_addr ip = RTE_IPV6(0xc000, 0x0200, 0, 0, 0, 0, 0, 0);
246 : : uint64_t next_hop_add = 10;
247 : : uint64_t next_hop_return;
248 : : uint8_t depth = 24;
249 : : uint32_t status = 0;
250 : :
251 : 1 : config.max_nodes = MAX_RULES;
252 : 1 : config.ext_sz = 0;
253 : :
254 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
255 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
256 : :
257 : 1 : node = rte_rib6_insert(rib, &ip, depth);
258 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
259 : :
260 : 1 : status = rte_rib6_set_nh(node, next_hop_add);
261 [ - + ]: 1 : RTE_TEST_ASSERT(status == 0,
262 : : "Failed to set rte_rib_node field\n");
263 : :
264 : 1 : node = rte_rib6_lookup(rib, &ip);
265 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to lookup\n");
266 : :
267 : 1 : status = rte_rib6_get_nh(node, &next_hop_return);
268 [ + - - + ]: 1 : RTE_TEST_ASSERT((status == 0) && (next_hop_add == next_hop_return),
269 : : "Failed to get proper nexthop\n");
270 : :
271 : 1 : node = rte_rib6_lookup_exact(rib, &ip, depth);
272 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL,
273 : : "Failed to lookup\n");
274 : :
275 : 1 : status = rte_rib6_get_nh(node, &next_hop_return);
276 [ + - - + ]: 1 : RTE_TEST_ASSERT((status == 0) && (next_hop_add == next_hop_return),
277 : : "Failed to get proper nexthop\n");
278 : :
279 : 1 : rte_rib6_remove(rib, &ip, depth);
280 : :
281 : 1 : node = rte_rib6_lookup(rib, &ip);
282 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
283 : : "Lookup returns non existent rule\n");
284 : 1 : node = rte_rib6_lookup_exact(rib, &ip, depth);
285 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
286 : : "Lookup returns non existent rule\n");
287 : :
288 : 1 : rte_rib6_free(rib);
289 : :
290 : 1 : return TEST_SUCCESS;
291 : : }
292 : :
293 : : int32_t
294 : 1 : test_tree_traversal(void)
295 : : {
296 : : struct rte_rib6 *rib = NULL;
297 : : struct rte_rib6_node *node;
298 : : struct rte_rib6_conf config;
299 : :
300 : 1 : struct rte_ipv6_addr ip = RTE_IPV6(0x0a00, 0x0282, 0, 0, 0, 0, 0, 0);
301 : 1 : struct rte_ipv6_addr ip1 = RTE_IPV6(0x0a00, 0x0200, 0, 0, 0, 0, 0, 0);
302 : 1 : struct rte_ipv6_addr ip2 = RTE_IPV6(0x0a00, 0x0282, 0, 0, 0, 0, 0, 0x0050);
303 : : uint8_t depth = 126;
304 : :
305 : 1 : config.max_nodes = MAX_RULES;
306 : 1 : config.ext_sz = 0;
307 : :
308 : 1 : rib = rte_rib6_create(__func__, SOCKET_ID_ANY, &config);
309 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
310 : :
311 : 1 : node = rte_rib6_insert(rib, &ip1, depth);
312 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
313 : 1 : node = rte_rib6_insert(rib, &ip2, depth);
314 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
315 : :
316 : : node = NULL;
317 : 1 : node = rte_rib6_get_nxt(rib, &ip, 32, node, RTE_RIB6_GET_NXT_ALL);
318 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to get rib_node\n");
319 : :
320 : 1 : rte_rib6_free(rib);
321 : :
322 : 1 : return TEST_SUCCESS;
323 : : }
324 : :
325 : : static struct unit_test_suite rib6_tests = {
326 : : .suite_name = "rib6 autotest",
327 : : .setup = NULL,
328 : : .teardown = NULL,
329 : : .unit_test_cases = {
330 : : TEST_CASE(test_create_invalid),
331 : : TEST_CASE(test_free_null),
332 : : TEST_CASE(test_insert_invalid),
333 : : TEST_CASE(test_get_fn),
334 : : TEST_CASE(test_basic),
335 : : TEST_CASE(test_tree_traversal),
336 : : TEST_CASES_END()
337 : : }
338 : : };
339 : :
340 : : static struct unit_test_suite rib6_slow_tests = {
341 : : .suite_name = "rib6 slow autotest",
342 : : .setup = NULL,
343 : : .teardown = NULL,
344 : : .unit_test_cases = {
345 : : TEST_CASE(test_multiple_create),
346 : : TEST_CASES_END()
347 : : }
348 : : };
349 : :
350 : : /*
351 : : * Do all unit tests.
352 : : */
353 : : static int
354 : 1 : test_rib6(void)
355 : : {
356 : 1 : return unit_test_suite_runner(&rib6_tests);
357 : : }
358 : :
359 : : static int
360 : 0 : test_slow_rib6(void)
361 : : {
362 : 0 : return unit_test_suite_runner(&rib6_slow_tests);
363 : : }
364 : :
365 : 251 : REGISTER_FAST_TEST(rib6_autotest, true, true, test_rib6);
366 : 251 : REGISTER_PERF_TEST(rib6_slow_autotest, test_slow_rib6);
|