ethdev: move egress metadata to dynamic field
[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 <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);