test/crypto: add TTL and hop limit decrement cases
[dpdk.git] / app / test / test_ipsec_sad.c
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);