xref: /dpdk/app/test/test_ipsec_sad.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include <rte_ipsec_sad.h>
11 #include <rte_memory.h>
12 
13 #include "test.h"
14 #include "test_xmmt_ops.h"
15 
16 typedef int32_t (*rte_ipsec_sad_test)(void);
17 
18 static int32_t test_create_invalid(void);
19 static int32_t test_find_existing(void);
20 static int32_t test_multiple_create(void);
21 static int32_t test_add_invalid(void);
22 static int32_t test_delete_invalid(void);
23 static int32_t test_lookup_invalid(void);
24 static int32_t test_lookup_basic(void);
25 static int32_t test_lookup_adv(void);
26 static int32_t test_lookup_order(void);
27 
28 #define MAX_SA	100000
29 #define PASS 0
30 #define SPI	0xdead	/* spi to install */
31 #define DIP	0xbeef	/* dip to install */
32 #define SIP	0xf00d	/* sip to install */
33 #define BAD	0xbad	/* some random value not installed into the table */
34 
35 /*
36  * Check that rte_ipsec_sad_create fails gracefully for incorrect user input
37  * arguments
38  */
39 int32_t
40 test_create_invalid(void)
41 {
42 	struct rte_ipsec_sad *sad = NULL;
43 	struct rte_ipsec_sad_conf config;
44 
45 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
46 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
47 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
48 	config.socket_id = SOCKET_ID_ANY;
49 	config.flags = 0;
50 
51 	/* name == NULL */
52 	sad = rte_ipsec_sad_create(NULL, &config);
53 	RTE_TEST_ASSERT(sad == NULL,
54 		"Call succeeded with invalid parameters\n");
55 
56 	/* max_sa for every type = 0 */
57 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = 0;
58 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0;
59 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0;
60 	sad = rte_ipsec_sad_create(__func__, &config);
61 	RTE_TEST_ASSERT(sad == NULL,
62 		"Call succeeded with invalid parameters\n");
63 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
64 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
65 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
66 
67 	/* socket_id < -1 is invalid */
68 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
69 	config.socket_id = -2;
70 	sad = rte_ipsec_sad_create(__func__, &config);
71 	RTE_TEST_ASSERT(sad == NULL,
72 		"Call succeeded with invalid parameters\n");
73 	config.socket_id = SOCKET_ID_ANY;
74 
75 	return TEST_SUCCESS;
76 }
77 
78 /*
79  * Test rte_ipsec_sad_find_existing()
80  * Create SAD and try to find it by it's name
81  */
82 int32_t
83 test_find_existing(void)
84 {
85 	const char *name1 = "sad_one";
86 	const char *name2 = "sad_two";
87 	struct rte_ipsec_sad *one, *two, *tmp;
88 	struct rte_ipsec_sad_conf config;
89 
90 	config.socket_id = SOCKET_ID_ANY;
91 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
92 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0;
93 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0;
94 	one = rte_ipsec_sad_create(name1, &config);
95 	RTE_TEST_ASSERT_NOT_NULL(one, "Failed to create SAD\n");
96 	two = rte_ipsec_sad_create(name2, &config);
97 	RTE_TEST_ASSERT_NOT_NULL(two, "Failed to create SAD\n");
98 
99 	/* Find non existing */
100 	tmp = rte_ipsec_sad_find_existing("sad_three");
101 	RTE_TEST_ASSERT(tmp == NULL,
102 		"rte_ipsec_sad_find_existing returns invalid SAD\n");
103 
104 	tmp = rte_ipsec_sad_find_existing(name1);
105 	RTE_TEST_ASSERT(tmp == one,
106 		"rte_ipsec_sad_find_existing returns invalid SAD\n");
107 
108 	tmp = rte_ipsec_sad_find_existing(name2);
109 	RTE_TEST_ASSERT(tmp == two,
110 		"rte_ipsec_sad_find_existing returns invalid SAD\n");
111 
112 	rte_ipsec_sad_destroy(one);
113 	rte_ipsec_sad_destroy(two);
114 	return TEST_SUCCESS;
115 }
116 
117 /*
118  * Create ipsec sad then delete it 10 times
119  * Use a slightly different max_sa each time
120  */
121 int32_t
122 test_multiple_create(void)
123 {
124 	int i;
125 	struct rte_ipsec_sad *sad = NULL;
126 	struct rte_ipsec_sad_conf config;
127 
128 	config.socket_id = SOCKET_ID_ANY;
129 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
130 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
131 
132 	for (i = 0; i < 10; i++) {
133 		config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA - i;
134 		sad = rte_ipsec_sad_create(__func__, &config);
135 		RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
136 		rte_ipsec_sad_destroy(sad);
137 	}
138 	return TEST_SUCCESS;
139 }
140 
141 static int32_t
142 __test_add_invalid(int ipv6, union rte_ipsec_sad_key *tuple)
143 {
144 	int status;
145 	struct rte_ipsec_sad *sad = NULL;
146 	struct rte_ipsec_sad_conf config;
147 	uint64_t tmp;
148 	void *sa = &tmp;
149 
150 	/* sad == NULL*/
151 	status = rte_ipsec_sad_add(NULL, tuple,
152 			RTE_IPSEC_SAD_SPI_DIP_SIP, sa);
153 	RTE_TEST_ASSERT(status < 0,
154 		"Call succeeded with invalid parameters\n");
155 
156 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
157 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
158 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
159 	config.socket_id = SOCKET_ID_ANY;
160 	config.flags = 0;
161 	if (ipv6)
162 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
163 
164 	sad = rte_ipsec_sad_create(__func__, &config);
165 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
166 
167 	/* key == NULL*/
168 	status = rte_ipsec_sad_add(sad, NULL, RTE_IPSEC_SAD_SPI_DIP_SIP, sa);
169 	RTE_TEST_ASSERT(status < 0,
170 		"Call succeeded with invalid parameters\n");
171 
172 	/* len is incorrect*/
173 	status = rte_ipsec_sad_add(sad, tuple,
174 		RTE_IPSEC_SAD_SPI_DIP_SIP + 1, sa);
175 	RTE_TEST_ASSERT(status < 0,
176 		"Call succeeded with invalid parameters\n");
177 
178 	/* sa == NULL*/
179 	status = rte_ipsec_sad_add(sad, tuple,
180 		RTE_IPSEC_SAD_SPI_DIP_SIP, NULL);
181 	RTE_TEST_ASSERT(status < 0,
182 		"Call succeeded with invalid parameters\n");
183 
184 	/* sa is not aligned*/
185 	status = rte_ipsec_sad_add(sad, tuple,
186 	RTE_IPSEC_SAD_SPI_DIP_SIP, (void *)((uint8_t *)sa + 1));
187 	RTE_TEST_ASSERT(status < 0,
188 		"Call succeeded with invalid parameters\n");
189 
190 	rte_ipsec_sad_destroy(sad);
191 
192 	return TEST_SUCCESS;
193 }
194 
195 /*
196  * Check that rte_ipsec_sad_add fails gracefully
197  * for incorrect user input arguments
198  */
199 int32_t
200 test_add_invalid(void)
201 {
202 	int status;
203 	struct rte_ipsec_sadv4_key tuple_v4 = {10, 20, 30};
204 	struct rte_ipsec_sadv6_key tuple_v6 = {10, {20, }, {30, } };
205 
206 	status = __test_add_invalid(0, (union rte_ipsec_sad_key *)&tuple_v4);
207 	if (status != TEST_SUCCESS)
208 		return status;
209 
210 	status = __test_add_invalid(1, (union rte_ipsec_sad_key *)&tuple_v6);
211 
212 	return status;
213 
214 }
215 
216 static int32_t
217 __test_delete_invalid(int ipv6, union rte_ipsec_sad_key *tuple)
218 {
219 	int status;
220 	struct rte_ipsec_sad *sad = NULL;
221 	struct rte_ipsec_sad_conf config;
222 
223 	/* sad == NULL*/
224 	status = rte_ipsec_sad_del(NULL, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
225 	RTE_TEST_ASSERT(status < 0,
226 		"Call succeeded with invalid parameters\n");
227 
228 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
229 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
230 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
231 	config.socket_id = SOCKET_ID_ANY;
232 	config.flags = 0;
233 	if (ipv6)
234 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
235 
236 	sad = rte_ipsec_sad_create(__func__, &config);
237 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
238 
239 	/* key == NULL*/
240 	status = rte_ipsec_sad_del(sad, NULL, RTE_IPSEC_SAD_SPI_DIP_SIP);
241 	RTE_TEST_ASSERT(status < 0,
242 		"Call succeeded with invalid parameters\n");
243 
244 	/* len is incorrect */
245 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP + 1);
246 	RTE_TEST_ASSERT(status < 0,
247 		"Call succeeded with invalid parameters\n");
248 
249 	rte_ipsec_sad_destroy(sad);
250 
251 	return TEST_SUCCESS;
252 }
253 
254 /*
255  * Check that rte_ipsec_sad_delete fails gracefully for incorrect user input
256  * arguments
257  */
258 int32_t
259 test_delete_invalid(void)
260 {
261 	int status;
262 	struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP};
263 	struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, },
264 			{0xf0, 0x0d, } };
265 
266 	status = __test_delete_invalid(0, (union rte_ipsec_sad_key *)&tuple_v4);
267 	if (status != TEST_SUCCESS)
268 		return status;
269 
270 	status = __test_delete_invalid(1, (union rte_ipsec_sad_key *)&tuple_v6);
271 
272 	return status;
273 }
274 
275 static int32_t
276 __test_lookup_invalid(int ipv6, union rte_ipsec_sad_key *tuple)
277 {
278 	int status;
279 	struct rte_ipsec_sad *sad = NULL;
280 	struct rte_ipsec_sad_conf config;
281 	const union rte_ipsec_sad_key *key_arr[] = {tuple};
282 	void *sa[1];
283 
284 	status = rte_ipsec_sad_lookup(NULL, key_arr, sa, 1);
285 	RTE_TEST_ASSERT(status < 0,
286 		"Call succeeded with invalid parameters\n");
287 
288 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
289 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
290 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
291 	config.socket_id = SOCKET_ID_ANY;
292 	config.flags = 0;
293 	if (ipv6)
294 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
295 
296 	sad = rte_ipsec_sad_create(__func__, &config);
297 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
298 
299 	status = rte_ipsec_sad_lookup(sad, NULL, sa, 1);
300 	RTE_TEST_ASSERT(status < 0,
301 		"Call succeeded with invalid parameters\n");
302 
303 	status = rte_ipsec_sad_lookup(sad, key_arr, NULL, 1);
304 	RTE_TEST_ASSERT(status < 0,
305 		"Call succeeded with invalid parameters\n");
306 
307 	rte_ipsec_sad_destroy(sad);
308 
309 	return TEST_SUCCESS;
310 }
311 
312 /*
313  * Check that rte_ipsec_sad_lookup fails gracefully for incorrect user input
314  * arguments
315  */
316 int32_t
317 test_lookup_invalid(void)
318 {
319 	int status;
320 	struct rte_ipsec_sadv4_key tuple_v4 = {10, 20, 30};
321 	struct rte_ipsec_sadv6_key tuple_v6 = {10, {20, }, {30, } };
322 
323 	status = __test_lookup_invalid(0,
324 			(union rte_ipsec_sad_key *)&tuple_v4);
325 	if (status != TEST_SUCCESS)
326 		return status;
327 
328 	status = __test_lookup_invalid(1,
329 			(union rte_ipsec_sad_key *)&tuple_v6);
330 
331 	return status;
332 }
333 
334 static int32_t
335 __test_lookup_basic(int ipv6, union rte_ipsec_sad_key *tuple,
336 	union rte_ipsec_sad_key *tuple_1)
337 {
338 	int status;
339 	struct rte_ipsec_sad *sad = NULL;
340 	struct rte_ipsec_sad_conf config;
341 	const union rte_ipsec_sad_key *key_arr[] = {tuple};
342 
343 	uint64_t tmp;
344 	void *sa[1];
345 
346 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
347 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
348 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
349 	config.socket_id = SOCKET_ID_ANY;
350 	config.flags = 0;
351 	if (ipv6)
352 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
353 
354 	sad = rte_ipsec_sad_create(__func__, &config);
355 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
356 
357 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 1);
358 	RTE_TEST_ASSERT((status == 0) && (sa[0] == NULL),
359 		"Lookup returns an unexpected result\n");
360 
361 	sa[0] = &tmp;
362 	status = rte_ipsec_sad_add(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY, sa[0]);
363 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
364 
365 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 1);
366 	RTE_TEST_ASSERT((status == 1) && (sa[0] == &tmp),
367 		"Lookup returns an unexpected result\n");
368 
369 	key_arr[0] = tuple_1;
370 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 1);
371 	RTE_TEST_ASSERT((status == 1) && (sa[0] == &tmp),
372 		"Lookup returns an unexpected result\n");
373 	key_arr[0] = tuple;
374 
375 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
376 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
377 
378 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 1);
379 	RTE_TEST_ASSERT((status == 0) && (sa[0] == NULL),
380 		"Lookup returns an unexpected result\n");
381 
382 	rte_ipsec_sad_destroy(sad);
383 
384 	return TEST_SUCCESS;
385 }
386 
387 /*
388  * Lookup missing key, then add it as RTE_IPSEC_SAD_SPI_ONLY, lookup it again,
389  * lookup different key with the same SPI, then delete it and repeat lookup
390  */
391 int32_t
392 test_lookup_basic(void)
393 {
394 	int status;
395 	struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP};
396 	struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, BAD, BAD};
397 	struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, },
398 			{0xf0, 0x0d, } };
399 	struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0x0b, 0xad, },
400 			{0x0b, 0xad, } };
401 
402 	status = __test_lookup_basic(0, (union rte_ipsec_sad_key *)&tuple_v4,
403 			(union rte_ipsec_sad_key *)&tuple_v4_1);
404 	if (status != TEST_SUCCESS)
405 		return status;
406 
407 	status = __test_lookup_basic(1, (union rte_ipsec_sad_key *)&tuple_v6,
408 			(union rte_ipsec_sad_key *)&tuple_v6_1);
409 
410 	return status;
411 }
412 
413 static int32_t
414 __test_lookup_adv(int ipv6, union rte_ipsec_sad_key *tuple,
415 	const union rte_ipsec_sad_key **key_arr)
416 {
417 	int status;
418 	struct rte_ipsec_sad *sad = NULL;
419 	struct rte_ipsec_sad_conf config;
420 	uint64_t tmp1, tmp2, tmp3;
421 	void *install_sa;
422 	void *sa[4];
423 
424 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
425 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
426 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
427 	config.socket_id = SOCKET_ID_ANY;
428 	config.flags = 0;
429 	if (ipv6)
430 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
431 	sad = rte_ipsec_sad_create(__func__, &config);
432 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
433 
434 	/* lookup with empty table */
435 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
436 	RTE_TEST_ASSERT(status == 0, "Lookup returns an unexpected result\n");
437 	RTE_TEST_ASSERT(sa[0] == NULL,
438 		"Lookup returns an unexpected result\n");
439 	RTE_TEST_ASSERT(sa[1] == NULL,
440 		"Lookup returns an unexpected result\n");
441 	RTE_TEST_ASSERT(sa[2] == NULL,
442 		"Lookup returns an unexpected result\n");
443 	RTE_TEST_ASSERT(sa[3] == NULL,
444 		"Lookup returns an unexpected result\n");
445 
446 	/* lookup with one RTE_IPSEC_SAD_SPI_ONLY rule */
447 	install_sa = &tmp1;
448 	status = rte_ipsec_sad_add(sad, tuple,
449 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
450 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
451 
452 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
453 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
454 	RTE_TEST_ASSERT(sa[0] == &tmp1,
455 		"Lookup returns an unexpected result\n");
456 	RTE_TEST_ASSERT(sa[1] == &tmp1,
457 		"Lookup returns an unexpected result\n");
458 	RTE_TEST_ASSERT(sa[2] == &tmp1,
459 		"Lookup returns an unexpected result\n");
460 	RTE_TEST_ASSERT(sa[3] == NULL,
461 		"Lookup returns an unexpected result\n");
462 
463 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
464 	RTE_TEST_ASSERT(status == 0, "Failde to delete a rule\n");
465 
466 	/* lookup with one RTE_IPSEC_SAD_SPI_DIP rule */
467 	install_sa = &tmp2;
468 	status = rte_ipsec_sad_add(sad, tuple,
469 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
470 	RTE_TEST_ASSERT(status == 0, "failed to add a rule\n");
471 
472 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
473 	RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n");
474 	RTE_TEST_ASSERT(sa[0] == &tmp2,
475 		"Lookup returns an unexpected result\n");
476 	RTE_TEST_ASSERT(sa[1] == &tmp2,
477 		"Lookup returns an unexpected result\n");
478 	RTE_TEST_ASSERT(sa[2] == NULL,
479 		"Lookup returns an unexpected result\n");
480 	RTE_TEST_ASSERT(sa[3] == NULL,
481 		"Lookup returns an unexpected result\n");
482 
483 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP);
484 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
485 
486 	/* lookup with one RTE_IPSEC_SAD_SPI_DIP_SIP rule */
487 	install_sa = &tmp3;
488 	status = rte_ipsec_sad_add(sad, tuple,
489 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
490 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
491 
492 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
493 	RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n");
494 	RTE_TEST_ASSERT(sa[0] == &tmp3,
495 		"Lookup returns an unexpected result\n");
496 	RTE_TEST_ASSERT(sa[1] == NULL,
497 		"Lookup returns an unexpected result\n");
498 	RTE_TEST_ASSERT(sa[2] == NULL,
499 		"Lookup returns an unexpected result\n");
500 	RTE_TEST_ASSERT(sa[3] == NULL,
501 		"Lookup returns an unexpected result\n");
502 
503 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
504 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
505 
506 	/* lookup with two RTE_IPSEC_SAD_ONLY and RTE_IPSEC_SAD_DIP rules */
507 	install_sa = &tmp1;
508 	status = rte_ipsec_sad_add(sad, tuple,
509 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
510 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
511 	install_sa = &tmp2;
512 	status = rte_ipsec_sad_add(sad, tuple,
513 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
514 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
515 
516 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
517 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
518 	RTE_TEST_ASSERT(sa[0] == &tmp2,
519 		"Lookup returns an unexpected result\n");
520 	RTE_TEST_ASSERT(sa[1] == &tmp2,
521 		"Lookup returns an unexpected result\n");
522 	RTE_TEST_ASSERT(sa[2] == &tmp1,
523 		"Lookup returns an unexpected result\n");
524 	RTE_TEST_ASSERT(sa[3] == NULL,
525 		"Lookup returns an unexpected result\n");
526 
527 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
528 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
529 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP);
530 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
531 
532 	/* lookup with two RTE_IPSEC_SAD_ONLY and RTE_IPSEC_SAD_DIP_SIP rules */
533 	install_sa = &tmp1;
534 	status = rte_ipsec_sad_add(sad, tuple,
535 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
536 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
537 	install_sa = &tmp3;
538 	status = rte_ipsec_sad_add(sad, tuple,
539 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
540 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
541 
542 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
543 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
544 	RTE_TEST_ASSERT(sa[0] == &tmp3,
545 		"Lookup returns an unexpected result\n");
546 	RTE_TEST_ASSERT(sa[1] == &tmp1,
547 		"Lookup returns an unexpected result\n");
548 	RTE_TEST_ASSERT(sa[2] == &tmp1,
549 		"Lookup returns an unexpected result\n");
550 	RTE_TEST_ASSERT(sa[3] == NULL,
551 		"Lookup returns an unexpected result\n");
552 
553 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
554 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
555 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
556 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
557 
558 	/* lookup with two RTE_IPSEC_SAD_DIP and RTE_IPSEC_SAD_DIP_SIP rules */
559 	install_sa = &tmp2;
560 	status = rte_ipsec_sad_add(sad, tuple,
561 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
562 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
563 	install_sa = &tmp3;
564 	status = rte_ipsec_sad_add(sad, tuple,
565 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
566 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
567 
568 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
569 	RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n");
570 	RTE_TEST_ASSERT(sa[0] == &tmp3,
571 		"Lookup returns an unexpected result\n");
572 	RTE_TEST_ASSERT(sa[1] == &tmp2,
573 		"Lookup returns an unexpected result\n");
574 	RTE_TEST_ASSERT(sa[2] == NULL,
575 		"Lookup returns an unexpected result\n");
576 	RTE_TEST_ASSERT(sa[3] == NULL,
577 		"Lookup returns an unexpected result\n");
578 
579 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP);
580 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
581 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
582 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
583 
584 	/*
585 	 * lookup with three RTE_IPSEC_SAD_DIP, RTE_IPSEC_SAD_DIP and
586 	 * RTE_IPSEC_SAD_DIP_SIP rules
587 	 */
588 	install_sa = &tmp1;
589 	status = rte_ipsec_sad_add(sad, tuple,
590 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
591 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
592 	install_sa = &tmp2;
593 	status = rte_ipsec_sad_add(sad, tuple,
594 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
595 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
596 	install_sa = &tmp3;
597 	status = rte_ipsec_sad_add(sad, tuple,
598 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
599 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
600 
601 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 4);
602 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
603 	RTE_TEST_ASSERT(sa[0] == &tmp3,
604 		"Lookup returns an unexpected result\n");
605 	RTE_TEST_ASSERT(sa[1] == &tmp2,
606 		"Lookup returns an unexpected result\n");
607 	RTE_TEST_ASSERT(sa[2] == &tmp1,
608 		"Lookup returns an unexpected result\n");
609 	RTE_TEST_ASSERT(sa[3] == NULL,
610 		"Lookup returns an unexpected result\n");
611 
612 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
613 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
614 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP);
615 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
616 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
617 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
618 
619 	rte_ipsec_sad_destroy(sad);
620 
621 	return TEST_SUCCESS;
622 }
623 
624 /*
625  * Lookup different keys in a table with:
626  *  - RTE_IPSEC_SAD_SPI_ONLY
627  *  - RTE_IPSEC_SAD_SPI_DIP
628  *  - RTE_IPSEC_SAD_SPI_SIP
629  *  - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP
630  *  - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP_SIP
631  *  - RTE_IPSEC_SAD_SPI_DIP/RTE_IPSEC_SAD_SPI_DIP_SIP
632  *  - RTE_IPSEC_SAD_SPI_ONLY/RTE_IPSEC_SAD_SPI_DIP/RTE_IPSEC_SAD_SPI_DIP_SIP
633  * length of rule installed.
634  */
635 int32_t
636 test_lookup_adv(void)
637 {
638 	int status;
639 	/* key to install*/
640 	struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP};
641 	struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, DIP, BAD};
642 	struct rte_ipsec_sadv4_key tuple_v4_2 = {SPI, BAD, SIP};
643 	struct rte_ipsec_sadv4_key tuple_v4_3 = {BAD, DIP, SIP};
644 
645 	/* key to install*/
646 	struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, },
647 			{0xf0, 0x0d, } };
648 	struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0xbe, 0xef, },
649 			{0x0b, 0xad, } };
650 	struct rte_ipsec_sadv6_key tuple_v6_2 = {SPI, {0x0b, 0xad, },
651 			{0xf0, 0x0d, } };
652 	struct rte_ipsec_sadv6_key tuple_v6_3 = {BAD, {0xbe, 0xef, },
653 			{0xf0, 0x0d, } };
654 
655 	const union rte_ipsec_sad_key *key_arr[] = {
656 				(union rte_ipsec_sad_key *)&tuple_v4,
657 				(union rte_ipsec_sad_key *)&tuple_v4_1,
658 				(union rte_ipsec_sad_key *)&tuple_v4_2,
659 				(union rte_ipsec_sad_key *)&tuple_v4_3
660 					};
661 
662 	status = __test_lookup_adv(0, (union rte_ipsec_sad_key *)&tuple_v4,
663 			key_arr);
664 	if (status != TEST_SUCCESS)
665 		return status;
666 	key_arr[0] = (union rte_ipsec_sad_key *)&tuple_v6;
667 	key_arr[1] = (union rte_ipsec_sad_key *)&tuple_v6_1;
668 	key_arr[2] = (union rte_ipsec_sad_key *)&tuple_v6_2;
669 	key_arr[3] = (union rte_ipsec_sad_key *)&tuple_v6_3;
670 	status = __test_lookup_adv(1, (union rte_ipsec_sad_key *)&tuple_v6,
671 			key_arr);
672 
673 	return status;
674 }
675 
676 
677 static int32_t
678 __test_lookup_order(int ipv6, union rte_ipsec_sad_key *tuple,
679 	union rte_ipsec_sad_key *tuple_1, union rte_ipsec_sad_key *tuple_2)
680 {
681 	int status;
682 	struct rte_ipsec_sad *sad = NULL;
683 	struct rte_ipsec_sad_conf config;
684 	const union rte_ipsec_sad_key *key_arr[] = {tuple, tuple_1, tuple_2,};
685 	uint64_t tmp1, tmp2, tmp3;
686 	void *install_sa;
687 	void *sa[3];
688 
689 	config.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = MAX_SA;
690 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP] = MAX_SA;
691 	config.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = MAX_SA;
692 	config.socket_id = SOCKET_ID_ANY;
693 	config.flags = 0;
694 	if (ipv6)
695 		config.flags = RTE_IPSEC_SAD_FLAG_IPV6;
696 	sad = rte_ipsec_sad_create(__func__, &config);
697 	RTE_TEST_ASSERT_NOT_NULL(sad, "Failed to create SAD\n");
698 
699 	/* install RTE_IPSEC_SAD_SPI_ONLY */
700 	install_sa = &tmp1;
701 	status = rte_ipsec_sad_add(sad, tuple,
702 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
703 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
704 
705 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
706 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
707 	RTE_TEST_ASSERT(sa[0] == &tmp1,
708 		"Lookup returns an unexpected result\n");
709 	RTE_TEST_ASSERT(sa[1] == &tmp1,
710 		"Lookup returns an unexpected result\n");
711 	RTE_TEST_ASSERT(sa[2] == &tmp1,
712 		"Lookup returns an unexpected result\n");
713 
714 	/* add RTE_IPSEC_SAD_SPI_DIP */
715 	install_sa = &tmp2;
716 	status = rte_ipsec_sad_add(sad, tuple,
717 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
718 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
719 
720 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
721 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
722 	RTE_TEST_ASSERT(sa[0] == &tmp2,
723 		"Lookup returns an unexpected result\n");
724 	RTE_TEST_ASSERT(sa[1] == &tmp2,
725 		"Lookup returns an unexpected result\n");
726 	RTE_TEST_ASSERT(sa[2] == &tmp1,
727 		"Lookup returns an unexpected result\n");
728 
729 	/* add RTE_IPSEC_SAD_SPI_DIP_SIP */
730 	install_sa = &tmp3;
731 	status = rte_ipsec_sad_add(sad, tuple,
732 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
733 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
734 
735 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
736 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
737 	RTE_TEST_ASSERT(sa[0] == &tmp3,
738 		"Lookup returns an unexpected result\n");
739 	RTE_TEST_ASSERT(sa[1] == &tmp2,
740 		"Lookup returns an unexpected result\n");
741 	RTE_TEST_ASSERT(sa[2] == &tmp1,
742 		"Lookup returns an unexpected result\n");
743 
744 	/* delete RTE_IPSEC_SAD_SPI_ONLY */
745 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_ONLY);
746 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
747 
748 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
749 	RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n");
750 	RTE_TEST_ASSERT(sa[0] == &tmp3,
751 		"Lookup returns an unexpected result\n");
752 	RTE_TEST_ASSERT(sa[1] == &tmp2,
753 		"Lookup returns an unexpected result\n");
754 	RTE_TEST_ASSERT(sa[2] == NULL,
755 		"Lookup returns an unexpected result\n");
756 
757 	/* delete RTE_IPSEC_SAD_SPI_DIP */
758 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP);
759 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
760 
761 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
762 	RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n");
763 	RTE_TEST_ASSERT(sa[0] == &tmp3,
764 		"Lookup returns an unexpected result\n");
765 	RTE_TEST_ASSERT(sa[1] == NULL,
766 		"Lookup returns an unexpected result\n");
767 	RTE_TEST_ASSERT(sa[2] == NULL,
768 		"Lookup returns an unexpected result\n");
769 
770 	/* delete RTE_IPSEC_SAD_SPI_DIP_SIP */
771 	status = rte_ipsec_sad_del(sad, tuple, RTE_IPSEC_SAD_SPI_DIP_SIP);
772 	RTE_TEST_ASSERT(status == 0, "Failed to delete a rule\n");
773 
774 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
775 	RTE_TEST_ASSERT(status == 0, "Lookup returns an unexpected result\n");
776 	RTE_TEST_ASSERT(sa[0] == NULL,
777 		"Lookup returns an unexpected result\n");
778 	RTE_TEST_ASSERT(sa[1] == NULL,
779 		"Lookup returns an unexpected result\n");
780 	RTE_TEST_ASSERT(sa[2] == NULL,
781 		"Lookup returns an unexpected result\n");
782 
783 	/* add RTE_IPSEC_SAD_SPI_DIP_SIP */
784 	install_sa = &tmp3;
785 	status = rte_ipsec_sad_add(sad, tuple,
786 			RTE_IPSEC_SAD_SPI_DIP_SIP, install_sa);
787 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
788 
789 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
790 	RTE_TEST_ASSERT(status == 1, "Lookup returns an unexpected result\n");
791 	RTE_TEST_ASSERT(sa[0] == &tmp3,
792 		"Lookup returns an unexpected result\n");
793 	RTE_TEST_ASSERT(sa[1] == NULL,
794 		"Lookup returns an unexpected result\n");
795 	RTE_TEST_ASSERT(sa[2] == NULL,
796 		"Lookup returns an unexpected result\n");
797 
798 	/* add RTE_IPSEC_SAD_SPI_DIP */
799 	install_sa = &tmp2;
800 	status = rte_ipsec_sad_add(sad, tuple,
801 			RTE_IPSEC_SAD_SPI_DIP, install_sa);
802 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
803 
804 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
805 	RTE_TEST_ASSERT(status == 2, "Lookup returns an unexpected result\n");
806 	RTE_TEST_ASSERT(sa[0] == &tmp3,
807 		"Lookup returns an unexpected result\n");
808 	RTE_TEST_ASSERT(sa[1] == &tmp2,
809 		"Lookup returns an unexpected result\n");
810 	RTE_TEST_ASSERT(sa[2] == NULL,
811 		"Lookup returns an unexpected result\n");
812 
813 	/* add RTE_IPSEC_SAD_SPI_ONLY */
814 	install_sa = &tmp1;
815 	status = rte_ipsec_sad_add(sad, tuple,
816 			RTE_IPSEC_SAD_SPI_ONLY, install_sa);
817 	RTE_TEST_ASSERT(status == 0, "Failed to add a rule\n");
818 
819 	status = rte_ipsec_sad_lookup(sad, key_arr, sa, 3);
820 	RTE_TEST_ASSERT(status == 3, "Lookup returns an unexpected result\n");
821 	RTE_TEST_ASSERT(sa[0] == &tmp3,
822 		"Lookup returns an unexpected result\n");
823 	RTE_TEST_ASSERT(sa[1] == &tmp2,
824 		"Lookup returns an unexpected result\n");
825 	RTE_TEST_ASSERT(sa[2] == &tmp1,
826 		"Lookup returns an unexpected result\n");
827 
828 	rte_ipsec_sad_destroy(sad);
829 	return TEST_SUCCESS;
830 }
831 
832 /*
833  * Check an order of add and delete
834  */
835 int32_t
836 test_lookup_order(void)
837 {
838 	int status;
839 	/* key to install*/
840 	struct rte_ipsec_sadv4_key tuple_v4 = {SPI, DIP, SIP};
841 	struct rte_ipsec_sadv4_key tuple_v4_1 = {SPI, DIP, BAD};
842 	struct rte_ipsec_sadv4_key tuple_v4_2 = {SPI, BAD, SIP};
843 	/* key to install*/
844 	struct rte_ipsec_sadv6_key tuple_v6 = {SPI, {0xbe, 0xef, },
845 			{0xf0, 0x0d, } };
846 	struct rte_ipsec_sadv6_key tuple_v6_1 = {SPI, {0xbe, 0xef, },
847 			{0x0b, 0xad, } };
848 	struct rte_ipsec_sadv6_key tuple_v6_2 = {SPI, {0x0b, 0xad, },
849 			{0xf0, 0x0d, } };
850 
851 	status = __test_lookup_order(0, (union rte_ipsec_sad_key *)&tuple_v4,
852 			(union rte_ipsec_sad_key *)&tuple_v4_1,
853 			(union rte_ipsec_sad_key *)&tuple_v4_2);
854 	if (status != TEST_SUCCESS)
855 		return status;
856 
857 	status = __test_lookup_order(1, (union rte_ipsec_sad_key *)&tuple_v6,
858 			(union rte_ipsec_sad_key *)&tuple_v6_1,
859 			(union rte_ipsec_sad_key *)&tuple_v6_2);
860 	return status;
861 }
862 
863 static struct unit_test_suite ipsec_sad_tests = {
864 	.suite_name = "ipsec sad autotest",
865 	.setup = NULL,
866 	.teardown = NULL,
867 	.unit_test_cases = {
868 		TEST_CASE(test_create_invalid),
869 		TEST_CASE(test_find_existing),
870 		TEST_CASE(test_multiple_create),
871 		TEST_CASE(test_add_invalid),
872 		TEST_CASE(test_delete_invalid),
873 		TEST_CASE(test_lookup_invalid),
874 		TEST_CASE(test_lookup_basic),
875 		TEST_CASE(test_lookup_adv),
876 		TEST_CASE(test_lookup_order),
877 		TEST_CASES_END()
878 	}
879 };
880 
881 static int
882 test_ipsec_sad(void)
883 {
884 	return unit_test_suite_runner(&ipsec_sad_tests);
885 }
886 
887 REGISTER_TEST_COMMAND(ipsec_sad_autotest, test_ipsec_sad);
888