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 "test.h"
7 : :
8 : : #include <stdio.h>
9 : : #include <stdint.h>
10 : : #include <stdlib.h>
11 : :
12 : : #include <rte_ip.h>
13 : : #include <rte_rib.h>
14 : :
15 : : typedef int32_t (*rte_rib_test)(void);
16 : :
17 : : static int32_t test_create_invalid(void);
18 : : static int32_t test_multiple_create(void);
19 : : static int32_t test_free_null(void);
20 : : static int32_t test_insert_invalid(void);
21 : : static int32_t test_get_fn(void);
22 : : static int32_t test_basic(void);
23 : : static int32_t test_tree_traversal(void);
24 : :
25 : : #define MAX_DEPTH 32
26 : : #define MAX_RULES (1 << 22)
27 : :
28 : : /*
29 : : * Check that rte_rib_create fails gracefully for incorrect user input
30 : : * arguments
31 : : */
32 : : int32_t
33 : 1 : test_create_invalid(void)
34 : : {
35 : : struct rte_rib *rib = NULL;
36 : : struct rte_rib_conf config;
37 : :
38 : 1 : config.max_nodes = MAX_RULES;
39 : 1 : config.ext_sz = 0;
40 : :
41 : : /* rte_rib_create: rib name == NULL */
42 : 1 : rib = rte_rib_create(NULL, SOCKET_ID_ANY, &config);
43 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
44 : : "Call succeeded with invalid parameters\n");
45 : :
46 : : /* rte_rib_create: config == NULL */
47 : 1 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, NULL);
48 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
49 : : "Call succeeded with invalid parameters\n");
50 : :
51 : : /* socket_id < -1 is invalid */
52 : 1 : rib = rte_rib_create(__func__, -2, &config);
53 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
54 : : "Call succeeded with invalid parameters\n");
55 : :
56 : : /* rte_rib_create: max_nodes = 0 */
57 : 1 : config.max_nodes = 0;
58 : 1 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
59 [ - + ]: 1 : RTE_TEST_ASSERT(rib == NULL,
60 : : "Call succeeded with invalid parameters\n");
61 : : config.max_nodes = MAX_RULES;
62 : :
63 : : return TEST_SUCCESS;
64 : : }
65 : :
66 : : /*
67 : : * Create rib table then delete rib table 10 times
68 : : * Use a slightly different rules size each time
69 : : */
70 : : int32_t
71 : 0 : test_multiple_create(void)
72 : : {
73 : : struct rte_rib *rib = NULL;
74 : : struct rte_rib_conf config;
75 : : int32_t i;
76 : :
77 : 0 : config.ext_sz = 0;
78 : :
79 [ # # ]: 0 : for (i = 0; i < 100; i++) {
80 : 0 : config.max_nodes = MAX_RULES - i;
81 : 0 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
82 [ # # ]: 0 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
83 : 0 : rte_rib_free(rib);
84 : : }
85 : : /* Can not test free so return success */
86 : : return TEST_SUCCESS;
87 : : }
88 : :
89 : : /*
90 : : * Call rte_rib_free for NULL pointer user input. Note: free has no return and
91 : : * therefore it is impossible to check for failure but this test is added to
92 : : * increase function coverage metrics and to validate that freeing null does
93 : : * not crash.
94 : : */
95 : : int32_t
96 : 1 : test_free_null(void)
97 : : {
98 : : struct rte_rib *rib = NULL;
99 : : struct rte_rib_conf config;
100 : :
101 : 1 : config.max_nodes = MAX_RULES;
102 : 1 : config.ext_sz = 0;
103 : :
104 : 1 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
105 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
106 : :
107 : 1 : rte_rib_free(rib);
108 : 1 : rte_rib_free(NULL);
109 : 1 : return TEST_SUCCESS;
110 : : }
111 : :
112 : : /*
113 : : * Check that rte_rib_insert fails gracefully for incorrect user input arguments
114 : : */
115 : : int32_t
116 : 1 : test_insert_invalid(void)
117 : : {
118 : : struct rte_rib *rib = NULL;
119 : : struct rte_rib_node *node, *node1;
120 : : struct rte_rib_conf config;
121 : : uint32_t ip = RTE_IPV4(0, 0, 0, 0);
122 : : uint8_t depth = 24;
123 : :
124 : 1 : config.max_nodes = MAX_RULES;
125 : 1 : config.ext_sz = 0;
126 : :
127 : : /* rte_rib_insert: rib == NULL */
128 : 1 : node = rte_rib_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_rib_create(__func__, SOCKET_ID_ANY, &config);
134 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
135 : :
136 : : /* rte_rib_insert: depth > MAX_DEPTH */
137 : 1 : node = rte_rib_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_rib_insert(rib, ip, depth);
143 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
144 : 1 : node1 = rte_rib_insert(rib, ip, depth);
145 [ - + ]: 1 : RTE_TEST_ASSERT(node1 == NULL,
146 : : "Call succeeded with invalid parameters\n");
147 : :
148 : 1 : rte_rib_free(rib);
149 : :
150 : 1 : return TEST_SUCCESS;
151 : : }
152 : :
153 : : /*
154 : : * Call rte_rib_node access functions with incorrect input.
155 : : * After call rte_rib_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_rib *rib = NULL;
162 : : struct rte_rib_node *node;
163 : : struct rte_rib_conf config;
164 : : void *ext;
165 : : uint32_t ip = RTE_IPV4(192, 0, 2, 0);
166 : : uint32_t 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_rib_create(__func__, SOCKET_ID_ANY, &config);
177 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
178 : :
179 : 1 : node = rte_rib_insert(rib, ip, depth);
180 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
181 : :
182 : : /* test rte_rib_get_ip() with incorrect args */
183 : 1 : ret = rte_rib_get_ip(NULL, &ip_ret);
184 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
185 : : "Call succeeded with invalid parameters\n");
186 : 1 : ret = rte_rib_get_ip(node, NULL);
187 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
188 : : "Call succeeded with invalid parameters\n");
189 : :
190 : : /* test rte_rib_get_depth() with incorrect args */
191 : 1 : ret = rte_rib_get_depth(NULL, &depth_ret);
192 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
193 : : "Call succeeded with invalid parameters\n");
194 : 1 : ret = rte_rib_get_depth(node, NULL);
195 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
196 : : "Call succeeded with invalid parameters\n");
197 : :
198 : : /* test rte_rib_set_nh() with incorrect args */
199 : 1 : ret = rte_rib_set_nh(NULL, nh_set);
200 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
201 : : "Call succeeded with invalid parameters\n");
202 : :
203 : : /* test rte_rib_get_nh() with incorrect args */
204 : 1 : ret = rte_rib_get_nh(NULL, &nh_ret);
205 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
206 : : "Call succeeded with invalid parameters\n");
207 : 1 : ret = rte_rib_get_nh(node, NULL);
208 [ - + ]: 1 : RTE_TEST_ASSERT(ret < 0,
209 : : "Call succeeded with invalid parameters\n");
210 : :
211 : : /* test rte_rib_get_ext() with incorrect args */
212 : 1 : ext = rte_rib_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_rib_get_ip(node, &ip_ret);
218 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (ip_ret == ip),
219 : : "Failed to get proper node ip\n");
220 : 1 : ret = rte_rib_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_rib_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_rib_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_rib_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_rib *rib = NULL;
242 : : struct rte_rib_node *node;
243 : : struct rte_rib_conf config;
244 : :
245 : : uint32_t ip = RTE_IPV4(192, 0, 2, 0);
246 : : uint64_t next_hop_add = 10;
247 : : uint64_t next_hop_return;
248 : : uint8_t depth = 24;
249 : : int ret;
250 : :
251 : 1 : config.max_nodes = MAX_RULES;
252 : 1 : config.ext_sz = 0;
253 : :
254 : 1 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
255 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
256 : :
257 : 1 : node = rte_rib_insert(rib, ip, depth);
258 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
259 : :
260 : 1 : ret = rte_rib_set_nh(node, next_hop_add);
261 [ - + ]: 1 : RTE_TEST_ASSERT(ret == 0,
262 : : "Failed to set rte_rib_node field\n");
263 : :
264 : 1 : node = rte_rib_lookup(rib, ip);
265 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to lookup\n");
266 : :
267 : 1 : ret = rte_rib_get_nh(node, &next_hop_return);
268 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (next_hop_add == next_hop_return),
269 : : "Failed to get proper nexthop\n");
270 : :
271 : 1 : node = rte_rib_lookup_exact(rib, ip, depth);
272 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL,
273 : : "Failed to lookup\n");
274 : :
275 : 1 : ret = rte_rib_get_nh(node, &next_hop_return);
276 [ + - - + ]: 1 : RTE_TEST_ASSERT((ret == 0) && (next_hop_add == next_hop_return),
277 : : "Failed to get proper nexthop\n");
278 : :
279 : 1 : rte_rib_remove(rib, ip, depth);
280 : :
281 : 1 : node = rte_rib_lookup(rib, ip);
282 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
283 : : "Lookup returns non existent rule\n");
284 : 1 : node = rte_rib_lookup_exact(rib, ip, depth);
285 [ - + ]: 1 : RTE_TEST_ASSERT(node == NULL,
286 : : "Lookup returns non existent rule\n");
287 : :
288 : 1 : rte_rib_free(rib);
289 : :
290 : 1 : return TEST_SUCCESS;
291 : : }
292 : :
293 : : int32_t
294 : 1 : test_tree_traversal(void)
295 : : {
296 : : struct rte_rib *rib = NULL;
297 : : struct rte_rib_node *node;
298 : : struct rte_rib_conf config;
299 : :
300 : : uint32_t ip1 = RTE_IPV4(10, 10, 10, 0);
301 : : uint32_t ip2 = RTE_IPV4(10, 10, 130, 80);
302 : : uint8_t depth = 30;
303 : :
304 : 1 : config.max_nodes = MAX_RULES;
305 : 1 : config.ext_sz = 0;
306 : :
307 : 1 : rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
308 [ - + ]: 1 : RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
309 : :
310 : 1 : node = rte_rib_insert(rib, ip1, depth);
311 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
312 : :
313 : 1 : node = rte_rib_insert(rib, ip2, depth);
314 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
315 : :
316 : : node = NULL;
317 : 1 : node = rte_rib_get_nxt(rib, RTE_IPV4(10, 10, 130, 0), 24, node,
318 : : RTE_RIB_GET_NXT_ALL);
319 [ - + ]: 1 : RTE_TEST_ASSERT(node != NULL, "Failed to get rib_node\n");
320 : :
321 : 1 : rte_rib_free(rib);
322 : :
323 : 1 : return TEST_SUCCESS;
324 : : }
325 : :
326 : : static struct unit_test_suite rib_tests = {
327 : : .suite_name = "rib autotest",
328 : : .setup = NULL,
329 : : .teardown = NULL,
330 : : .unit_test_cases = {
331 : : TEST_CASE(test_create_invalid),
332 : : TEST_CASE(test_free_null),
333 : : TEST_CASE(test_insert_invalid),
334 : : TEST_CASE(test_get_fn),
335 : : TEST_CASE(test_basic),
336 : : TEST_CASE(test_tree_traversal),
337 : : TEST_CASES_END()
338 : : }
339 : : };
340 : :
341 : : static struct unit_test_suite rib_slow_tests = {
342 : : .suite_name = "rib slow autotest",
343 : : .setup = NULL,
344 : : .teardown = NULL,
345 : : .unit_test_cases = {
346 : : TEST_CASE(test_multiple_create),
347 : : TEST_CASES_END()
348 : : }
349 : : };
350 : :
351 : : /*
352 : : * Do all unit tests.
353 : : */
354 : : static int
355 : 1 : test_rib(void)
356 : : {
357 : 1 : return unit_test_suite_runner(&rib_tests);
358 : : }
359 : :
360 : : static int
361 : 0 : test_slow_rib(void)
362 : : {
363 : 0 : return unit_test_suite_runner(&rib_slow_tests);
364 : : }
365 : :
366 : 251 : REGISTER_FAST_TEST(rib_autotest, true, true, test_rib);
367 : 251 : REGISTER_PERF_TEST(rib_slow_autotest, test_slow_rib);
|