1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com>
3 * Copyright(c) 2019 Intel Corporation
14 #ifdef RTE_EXEC_ENV_WINDOWS
18 printf("rib not supported on Windows, skipping test\n");
25 printf("slow_rib not supported on Windows, skipping test\n");
32 typedef int32_t (*rte_rib_test)(void);
34 static int32_t test_create_invalid(void);
35 static int32_t test_multiple_create(void);
36 static int32_t test_free_null(void);
37 static int32_t test_insert_invalid(void);
38 static int32_t test_get_fn(void);
39 static int32_t test_basic(void);
40 static int32_t test_tree_traversal(void);
43 #define MAX_RULES (1 << 22)
46 * Check that rte_rib_create fails gracefully for incorrect user input
50 test_create_invalid(void)
52 struct rte_rib *rib = NULL;
53 struct rte_rib_conf config;
55 config.max_nodes = MAX_RULES;
58 /* rte_rib_create: rib name == NULL */
59 rib = rte_rib_create(NULL, SOCKET_ID_ANY, &config);
60 RTE_TEST_ASSERT(rib == NULL,
61 "Call succeeded with invalid parameters\n");
63 /* rte_rib_create: config == NULL */
64 rib = rte_rib_create(__func__, SOCKET_ID_ANY, NULL);
65 RTE_TEST_ASSERT(rib == NULL,
66 "Call succeeded with invalid parameters\n");
68 /* socket_id < -1 is invalid */
69 rib = rte_rib_create(__func__, -2, &config);
70 RTE_TEST_ASSERT(rib == NULL,
71 "Call succeeded with invalid parameters\n");
73 /* rte_rib_create: max_nodes = 0 */
75 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
76 RTE_TEST_ASSERT(rib == NULL,
77 "Call succeeded with invalid parameters\n");
78 config.max_nodes = MAX_RULES;
84 * Create rib table then delete rib table 10 times
85 * Use a slightly different rules size each time
88 test_multiple_create(void)
90 struct rte_rib *rib = NULL;
91 struct rte_rib_conf config;
96 for (i = 0; i < 100; i++) {
97 config.max_nodes = MAX_RULES - i;
98 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
99 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
102 /* Can not test free so return success */
107 * Call rte_rib_free for NULL pointer user input. Note: free has no return and
108 * therefore it is impossible to check for failure but this test is added to
109 * increase function coverage metrics and to validate that freeing null does
115 struct rte_rib *rib = NULL;
116 struct rte_rib_conf config;
118 config.max_nodes = MAX_RULES;
121 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
122 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
130 * Check that rte_rib_insert fails gracefully for incorrect user input arguments
133 test_insert_invalid(void)
135 struct rte_rib *rib = NULL;
136 struct rte_rib_node *node, *node1;
137 struct rte_rib_conf config;
138 uint32_t ip = RTE_IPV4(0, 0, 0, 0);
141 config.max_nodes = MAX_RULES;
144 /* rte_rib_insert: rib == NULL */
145 node = rte_rib_insert(NULL, ip, depth);
146 RTE_TEST_ASSERT(node == NULL,
147 "Call succeeded with invalid parameters\n");
149 /*Create valid rib to use in rest of test. */
150 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
151 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
153 /* rte_rib_insert: depth > MAX_DEPTH */
154 node = rte_rib_insert(rib, ip, MAX_DEPTH + 1);
155 RTE_TEST_ASSERT(node == NULL,
156 "Call succeeded with invalid parameters\n");
158 /* insert the same ip/depth twice*/
159 node = rte_rib_insert(rib, ip, depth);
160 RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
161 node1 = rte_rib_insert(rib, ip, depth);
162 RTE_TEST_ASSERT(node1 == NULL,
163 "Call succeeded with invalid parameters\n");
171 * Call rte_rib_node access functions with incorrect input.
172 * After call rte_rib_node access functions with correct args
173 * and check the return values for correctness
178 struct rte_rib *rib = NULL;
179 struct rte_rib_node *node;
180 struct rte_rib_conf config;
182 uint32_t ip = RTE_IPV4(192, 0, 2, 0);
184 uint64_t nh_set = 10;
190 config.max_nodes = MAX_RULES;
193 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
194 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
196 node = rte_rib_insert(rib, ip, depth);
197 RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
199 /* test rte_rib_get_ip() with incorrect args */
200 ret = rte_rib_get_ip(NULL, &ip_ret);
201 RTE_TEST_ASSERT(ret < 0,
202 "Call succeeded with invalid parameters\n");
203 ret = rte_rib_get_ip(node, NULL);
204 RTE_TEST_ASSERT(ret < 0,
205 "Call succeeded with invalid parameters\n");
207 /* test rte_rib_get_depth() with incorrect args */
208 ret = rte_rib_get_depth(NULL, &depth_ret);
209 RTE_TEST_ASSERT(ret < 0,
210 "Call succeeded with invalid parameters\n");
211 ret = rte_rib_get_depth(node, NULL);
212 RTE_TEST_ASSERT(ret < 0,
213 "Call succeeded with invalid parameters\n");
215 /* test rte_rib_set_nh() with incorrect args */
216 ret = rte_rib_set_nh(NULL, nh_set);
217 RTE_TEST_ASSERT(ret < 0,
218 "Call succeeded with invalid parameters\n");
220 /* test rte_rib_get_nh() with incorrect args */
221 ret = rte_rib_get_nh(NULL, &nh_ret);
222 RTE_TEST_ASSERT(ret < 0,
223 "Call succeeded with invalid parameters\n");
224 ret = rte_rib_get_nh(node, NULL);
225 RTE_TEST_ASSERT(ret < 0,
226 "Call succeeded with invalid parameters\n");
228 /* test rte_rib_get_ext() with incorrect args */
229 ext = rte_rib_get_ext(NULL);
230 RTE_TEST_ASSERT(ext == NULL,
231 "Call succeeded with invalid parameters\n");
233 /* check the return values */
234 ret = rte_rib_get_ip(node, &ip_ret);
235 RTE_TEST_ASSERT((ret == 0) && (ip_ret == ip),
236 "Failed to get proper node ip\n");
237 ret = rte_rib_get_depth(node, &depth_ret);
238 RTE_TEST_ASSERT((ret == 0) && (depth_ret == depth),
239 "Failed to get proper node depth\n");
240 ret = rte_rib_set_nh(node, nh_set);
241 RTE_TEST_ASSERT(ret == 0,
242 "Failed to set rte_rib_node nexthop\n");
243 ret = rte_rib_get_nh(node, &nh_ret);
244 RTE_TEST_ASSERT((ret == 0) && (nh_ret == nh_set),
245 "Failed to get proper nexthop\n");
253 * Call insert, lookup/lookup_exact and delete for a single rule
258 struct rte_rib *rib = NULL;
259 struct rte_rib_node *node;
260 struct rte_rib_conf config;
262 uint32_t ip = RTE_IPV4(192, 0, 2, 0);
263 uint64_t next_hop_add = 10;
264 uint64_t next_hop_return;
268 config.max_nodes = MAX_RULES;
271 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
272 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
274 node = rte_rib_insert(rib, ip, depth);
275 RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
277 ret = rte_rib_set_nh(node, next_hop_add);
278 RTE_TEST_ASSERT(ret == 0,
279 "Failed to set rte_rib_node field\n");
281 node = rte_rib_lookup(rib, ip);
282 RTE_TEST_ASSERT(node != NULL, "Failed to lookup\n");
284 ret = rte_rib_get_nh(node, &next_hop_return);
285 RTE_TEST_ASSERT((ret == 0) && (next_hop_add == next_hop_return),
286 "Failed to get proper nexthop\n");
288 node = rte_rib_lookup_exact(rib, ip, depth);
289 RTE_TEST_ASSERT(node != NULL,
290 "Failed to lookup\n");
292 ret = rte_rib_get_nh(node, &next_hop_return);
293 RTE_TEST_ASSERT((ret == 0) && (next_hop_add == next_hop_return),
294 "Failed to get proper nexthop\n");
296 rte_rib_remove(rib, ip, depth);
298 node = rte_rib_lookup(rib, ip);
299 RTE_TEST_ASSERT(node == NULL,
300 "Lookup returns non existent rule\n");
301 node = rte_rib_lookup_exact(rib, ip, depth);
302 RTE_TEST_ASSERT(node == NULL,
303 "Lookup returns non existent rule\n");
311 test_tree_traversal(void)
313 struct rte_rib *rib = NULL;
314 struct rte_rib_node *node;
315 struct rte_rib_conf config;
317 uint32_t ip1 = RTE_IPV4(10, 10, 10, 0);
318 uint32_t ip2 = RTE_IPV4(10, 10, 130, 80);
321 config.max_nodes = MAX_RULES;
324 rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
325 RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
327 node = rte_rib_insert(rib, ip1, depth);
328 RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
330 node = rte_rib_insert(rib, ip2, depth);
331 RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
334 node = rte_rib_get_nxt(rib, RTE_IPV4(10, 10, 130, 0), 24, node,
335 RTE_RIB_GET_NXT_ALL);
336 RTE_TEST_ASSERT(node != NULL, "Failed to get rib_node\n");
343 static struct unit_test_suite rib_tests = {
344 .suite_name = "rib autotest",
348 TEST_CASE(test_create_invalid),
349 TEST_CASE(test_free_null),
350 TEST_CASE(test_insert_invalid),
351 TEST_CASE(test_get_fn),
352 TEST_CASE(test_basic),
353 TEST_CASE(test_tree_traversal),
358 static struct unit_test_suite rib_slow_tests = {
359 .suite_name = "rib slow autotest",
363 TEST_CASE(test_multiple_create),
374 return unit_test_suite_runner(&rib_tests);
380 return unit_test_suite_runner(&rib_slow_tests);
383 #endif /* !RTE_EXEC_ENV_WINDOWS */
385 REGISTER_TEST_COMMAND(rib_autotest, test_rib);
386 REGISTER_TEST_COMMAND(rib_slow_autotest, test_slow_rib);