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