d18220a885240f1ca362655856434afe73854148
[dpdk.git] / app / test / test_ipsec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #include <time.h>
6
7 #include <rte_common.h>
8 #include <rte_hexdump.h>
9 #include <rte_mbuf.h>
10 #include <rte_malloc.h>
11 #include <rte_memcpy.h>
12 #include <rte_cycles.h>
13 #include <rte_bus_vdev.h>
14 #include <rte_ip.h>
15
16 #include <rte_crypto.h>
17 #include <rte_cryptodev.h>
18 #include <rte_cryptodev_pmd.h>
19 #include <rte_lcore.h>
20 #include <rte_ipsec.h>
21 #include <rte_random.h>
22 #include <rte_esp.h>
23 #include <rte_security_driver.h>
24
25 #include "test.h"
26 #include "test_cryptodev.h"
27
28 #define VDEV_ARGS_SIZE  100
29 #define MAX_NB_SESSIONS 200
30 #define MAX_NB_SAS              2
31 #define REPLAY_WIN_0    0
32 #define REPLAY_WIN_32   32
33 #define REPLAY_WIN_64   64
34 #define REPLAY_WIN_128  128
35 #define REPLAY_WIN_256  256
36 #define DATA_64_BYTES   64
37 #define DATA_80_BYTES   80
38 #define DATA_100_BYTES  100
39 #define ESN_ENABLED             1
40 #define ESN_DISABLED    0
41 #define INBOUND_SPI             7
42 #define OUTBOUND_SPI    17
43 #define BURST_SIZE              32
44 #define REORDER_PKTS    1
45 #define DEQUEUE_COUNT   1000
46
47 struct user_params {
48         enum rte_crypto_sym_xform_type auth;
49         enum rte_crypto_sym_xform_type cipher;
50         enum rte_crypto_sym_xform_type aead;
51
52         char auth_algo[128];
53         char cipher_algo[128];
54         char aead_algo[128];
55 };
56
57 struct ipsec_testsuite_params {
58         struct rte_mempool *mbuf_pool;
59         struct rte_mempool *cop_mpool;
60         struct rte_cryptodev_config conf;
61         struct rte_cryptodev_qp_conf qp_conf;
62
63         uint8_t valid_dev;
64         uint8_t valid_dev_found;
65 };
66
67 struct ipsec_unitest_params {
68         struct rte_crypto_sym_xform cipher_xform;
69         struct rte_crypto_sym_xform auth_xform;
70         struct rte_crypto_sym_xform aead_xform;
71         struct rte_crypto_sym_xform *crypto_xforms;
72
73         struct rte_security_ipsec_xform ipsec_xform;
74
75         struct rte_ipsec_sa_prm sa_prm;
76         struct rte_ipsec_session ss[MAX_NB_SAS];
77
78         struct rte_crypto_op *cop[BURST_SIZE];
79
80         struct rte_mbuf *obuf[BURST_SIZE], *ibuf[BURST_SIZE],
81                 *testbuf[BURST_SIZE];
82
83         uint16_t pkt_index;
84 };
85
86 struct ipsec_test_cfg {
87         uint32_t replay_win_sz;
88         uint32_t esn;
89         uint64_t flags;
90         size_t pkt_sz;
91         uint16_t num_pkts;
92         uint32_t reorder_pkts;
93 };
94
95 static const struct ipsec_test_cfg test_cfg[] = {
96         {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, 1, 0},
97         {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, BURST_SIZE, 0},
98         {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_80_BYTES, BURST_SIZE,
99                 REORDER_PKTS},
100         {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, 1, 0},
101         {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, BURST_SIZE,
102                 REORDER_PKTS},
103         {REPLAY_WIN_64, ESN_ENABLED, 0, DATA_64_BYTES, 1, 0},
104         {REPLAY_WIN_128, ESN_ENABLED, RTE_IPSEC_SAFLAG_SQN_ATOM,
105                 DATA_80_BYTES, 1, 0},
106         {REPLAY_WIN_256, ESN_DISABLED, 0, DATA_100_BYTES, 1, 0},
107 };
108
109 static const int num_cfg = RTE_DIM(test_cfg);
110 static struct ipsec_testsuite_params testsuite_params = { NULL };
111 static struct ipsec_unitest_params unittest_params;
112 static struct user_params uparams;
113
114 struct supported_cipher_algo {
115         const char *keyword;
116         enum rte_crypto_cipher_algorithm algo;
117         uint16_t iv_len;
118         uint16_t block_size;
119         uint16_t key_len;
120 };
121
122 struct supported_auth_algo {
123         const char *keyword;
124         enum rte_crypto_auth_algorithm algo;
125         uint16_t digest_len;
126         uint16_t key_len;
127         uint8_t key_not_req;
128 };
129
130 const struct supported_cipher_algo cipher_algos[] = {
131         {
132                 .keyword = "null",
133                 .algo = RTE_CRYPTO_CIPHER_NULL,
134                 .iv_len = 0,
135                 .block_size = 4,
136                 .key_len = 0
137         },
138 };
139
140 const struct supported_auth_algo auth_algos[] = {
141         {
142                 .keyword = "null",
143                 .algo = RTE_CRYPTO_AUTH_NULL,
144                 .digest_len = 0,
145                 .key_len = 0,
146                 .key_not_req = 1
147         },
148 };
149
150 static int
151 dummy_sec_create(void *device, struct rte_security_session_conf *conf,
152         struct rte_security_session *sess, struct rte_mempool *mp)
153 {
154         RTE_SET_USED(device);
155         RTE_SET_USED(conf);
156         RTE_SET_USED(mp);
157
158         sess->sess_private_data = NULL;
159         return 0;
160 }
161
162 static int
163 dummy_sec_destroy(void *device, struct rte_security_session *sess)
164 {
165         RTE_SET_USED(device);
166         RTE_SET_USED(sess);
167         return 0;
168 }
169
170 static const struct rte_security_ops dummy_sec_ops = {
171         .session_create = dummy_sec_create,
172         .session_destroy = dummy_sec_destroy,
173 };
174
175 static struct rte_security_ctx dummy_sec_ctx = {
176         .ops = &dummy_sec_ops,
177 };
178
179 static const struct supported_cipher_algo *
180 find_match_cipher_algo(const char *cipher_keyword)
181 {
182         size_t i;
183
184         for (i = 0; i < RTE_DIM(cipher_algos); i++) {
185                 const struct supported_cipher_algo *algo =
186                         &cipher_algos[i];
187
188                 if (strcmp(cipher_keyword, algo->keyword) == 0)
189                         return algo;
190         }
191
192         return NULL;
193 }
194
195 static const struct supported_auth_algo *
196 find_match_auth_algo(const char *auth_keyword)
197 {
198         size_t i;
199
200         for (i = 0; i < RTE_DIM(auth_algos); i++) {
201                 const struct supported_auth_algo *algo =
202                         &auth_algos[i];
203
204                 if (strcmp(auth_keyword, algo->keyword) == 0)
205                         return algo;
206         }
207
208         return NULL;
209 }
210
211 static void
212 fill_crypto_xform(struct ipsec_unitest_params *ut_params,
213         const struct supported_auth_algo *auth_algo,
214         const struct supported_cipher_algo *cipher_algo)
215 {
216         ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
217         ut_params->cipher_xform.cipher.algo = cipher_algo->algo;
218         ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
219         ut_params->auth_xform.auth.algo = auth_algo->algo;
220
221         if (ut_params->ipsec_xform.direction ==
222                         RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
223                 ut_params->cipher_xform.cipher.op =
224                         RTE_CRYPTO_CIPHER_OP_DECRYPT;
225                 ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
226                 ut_params->cipher_xform.next = NULL;
227                 ut_params->auth_xform.next = &ut_params->cipher_xform;
228                 ut_params->crypto_xforms = &ut_params->auth_xform;
229         } else {
230                 ut_params->cipher_xform.cipher.op =
231                         RTE_CRYPTO_CIPHER_OP_ENCRYPT;
232                 ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
233                 ut_params->auth_xform.next = NULL;
234                 ut_params->cipher_xform.next = &ut_params->auth_xform;
235                 ut_params->crypto_xforms = &ut_params->cipher_xform;
236         }
237 }
238
239 static int
240 check_cryptodev_capability(const struct ipsec_unitest_params *ut,
241                 uint8_t dev_id)
242 {
243         struct rte_cryptodev_sym_capability_idx cap_idx;
244         const struct rte_cryptodev_symmetric_capability *cap;
245         int rc = -1;
246
247         cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
248         cap_idx.algo.auth = ut->auth_xform.auth.algo;
249         cap = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
250
251         if (cap != NULL) {
252                 rc = rte_cryptodev_sym_capability_check_auth(cap,
253                                 ut->auth_xform.auth.key.length,
254                                 ut->auth_xform.auth.digest_length, 0);
255                 if (rc == 0) {
256                         cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
257                         cap_idx.algo.cipher = ut->cipher_xform.cipher.algo;
258                         cap = rte_cryptodev_sym_capability_get(
259                                         dev_id, &cap_idx);
260                         if (cap != NULL)
261                                 rc = rte_cryptodev_sym_capability_check_cipher(
262                                         cap,
263                                         ut->cipher_xform.cipher.key.length,
264                                         ut->cipher_xform.cipher.iv.length);
265                 }
266         }
267
268         return rc;
269 }
270
271 static int
272 testsuite_setup(void)
273 {
274         struct ipsec_testsuite_params *ts_params = &testsuite_params;
275         struct ipsec_unitest_params *ut_params = &unittest_params;
276         const struct supported_auth_algo *auth_algo;
277         const struct supported_cipher_algo *cipher_algo;
278         struct rte_cryptodev_info info;
279         uint32_t i, nb_devs, dev_id;
280         size_t sess_sz;
281         int rc;
282
283         memset(ts_params, 0, sizeof(*ts_params));
284         memset(ut_params, 0, sizeof(*ut_params));
285         memset(&uparams, 0, sizeof(struct user_params));
286
287         uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
288         uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
289         uparams.aead = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED;
290         strcpy(uparams.auth_algo, "null");
291         strcpy(uparams.cipher_algo, "null");
292
293         auth_algo = find_match_auth_algo(uparams.auth_algo);
294         cipher_algo = find_match_cipher_algo(uparams.cipher_algo);
295         fill_crypto_xform(ut_params, auth_algo, cipher_algo);
296
297         nb_devs = rte_cryptodev_count();
298         if (nb_devs < 1) {
299                 RTE_LOG(WARNING, USER1, "No crypto devices found?\n");
300                 return TEST_SKIPPED;
301         }
302
303         /* Find first valid crypto device */
304         for (i = 0; i < nb_devs; i++) {
305                 rc = check_cryptodev_capability(ut_params, i);
306                 if (rc == 0) {
307                         ts_params->valid_dev = i;
308                         ts_params->valid_dev_found = 1;
309                         break;
310                 }
311         }
312
313         if (ts_params->valid_dev_found == 0)
314                 return TEST_FAILED;
315
316         ts_params->mbuf_pool = rte_pktmbuf_pool_create(
317                         "CRYPTO_MBUFPOOL",
318                         NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
319                         rte_socket_id());
320         if (ts_params->mbuf_pool == NULL) {
321                 RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n");
322                 return TEST_FAILED;
323         }
324
325         ts_params->cop_mpool = rte_crypto_op_pool_create(
326                         "MBUF_CRYPTO_SYM_OP_POOL",
327                         RTE_CRYPTO_OP_TYPE_SYMMETRIC,
328                         NUM_MBUFS, MBUF_CACHE_SIZE,
329                         DEFAULT_NUM_XFORMS *
330                         sizeof(struct rte_crypto_sym_xform) +
331                         MAXIMUM_IV_LENGTH,
332                         rte_socket_id());
333         if (ts_params->cop_mpool == NULL) {
334                 RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
335                 return TEST_FAILED;
336         }
337
338         /* Set up all the qps on the first of the valid devices found */
339         dev_id = ts_params->valid_dev;
340
341         rte_cryptodev_info_get(dev_id, &info);
342
343         ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
344         ts_params->conf.socket_id = SOCKET_ID_ANY;
345         ts_params->conf.ff_disable = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO;
346
347         sess_sz = rte_cryptodev_sym_get_private_session_size(dev_id);
348         sess_sz = RTE_MAX(sess_sz, sizeof(struct rte_security_session));
349
350         /*
351          * Create mempools for sessions
352          */
353         if (info.sym.max_nb_sessions != 0 &&
354                         info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
355                 RTE_LOG(ERR, USER1, "Device does not support "
356                                 "at least %u sessions\n",
357                                 MAX_NB_SESSIONS);
358                 return TEST_FAILED;
359         }
360
361         ts_params->qp_conf.mp_session_private = rte_mempool_create(
362                                 "test_priv_sess_mp",
363                                 MAX_NB_SESSIONS,
364                                 sess_sz,
365                                 0, 0, NULL, NULL, NULL,
366                                 NULL, SOCKET_ID_ANY,
367                                 0);
368
369         TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session_private,
370                         "private session mempool allocation failed");
371
372         ts_params->qp_conf.mp_session =
373                 rte_cryptodev_sym_session_pool_create("test_sess_mp",
374                         MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY);
375
376         TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session,
377                         "session mempool allocation failed");
378
379         TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
380                         &ts_params->conf),
381                         "Failed to configure cryptodev %u with %u qps",
382                         dev_id, ts_params->conf.nb_queue_pairs);
383
384         ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
385
386         TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
387                 dev_id, 0, &ts_params->qp_conf,
388                 rte_cryptodev_socket_id(dev_id)),
389                 "Failed to setup queue pair %u on cryptodev %u",
390                 0, dev_id);
391
392         return TEST_SUCCESS;
393 }
394
395 static void
396 testsuite_teardown(void)
397 {
398         struct ipsec_testsuite_params *ts_params = &testsuite_params;
399
400         if (ts_params->mbuf_pool != NULL) {
401                 RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
402                 rte_mempool_avail_count(ts_params->mbuf_pool));
403                 rte_mempool_free(ts_params->mbuf_pool);
404                 ts_params->mbuf_pool = NULL;
405         }
406
407         if (ts_params->cop_mpool != NULL) {
408                 RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
409                 rte_mempool_avail_count(ts_params->cop_mpool));
410                 rte_mempool_free(ts_params->cop_mpool);
411                 ts_params->cop_mpool = NULL;
412         }
413
414         /* Free session mempools */
415         if (ts_params->qp_conf.mp_session != NULL) {
416                 rte_mempool_free(ts_params->qp_conf.mp_session);
417                 ts_params->qp_conf.mp_session = NULL;
418         }
419
420         if (ts_params->qp_conf.mp_session_private != NULL) {
421                 rte_mempool_free(ts_params->qp_conf.mp_session_private);
422                 ts_params->qp_conf.mp_session_private = NULL;
423         }
424 }
425
426 static int
427 ut_setup(void)
428 {
429         struct ipsec_testsuite_params *ts_params = &testsuite_params;
430         struct ipsec_unitest_params *ut_params = &unittest_params;
431
432         /* Clear unit test parameters before running test */
433         memset(ut_params, 0, sizeof(*ut_params));
434
435         /* Reconfigure device to default parameters */
436         ts_params->conf.socket_id = SOCKET_ID_ANY;
437
438         /* Start the device */
439         TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_dev),
440                         "Failed to start cryptodev %u",
441                         ts_params->valid_dev);
442
443         return TEST_SUCCESS;
444 }
445
446 static void
447 ut_teardown(void)
448 {
449         struct ipsec_testsuite_params *ts_params = &testsuite_params;
450         struct ipsec_unitest_params *ut_params = &unittest_params;
451         int i;
452
453         for (i = 0; i < BURST_SIZE; i++) {
454                 /* free crypto operation structure */
455                 if (ut_params->cop[i]) {
456                         rte_crypto_op_free(ut_params->cop[i]);
457                         ut_params->cop[i] = NULL;
458                 }
459
460                 /*
461                  * free mbuf - both obuf and ibuf are usually the same,
462                  * so check if they point at the same address is necessary,
463                  * to avoid freeing the mbuf twice.
464                  */
465                 if (ut_params->obuf[i]) {
466                         rte_pktmbuf_free(ut_params->obuf[i]);
467                         if (ut_params->ibuf[i] == ut_params->obuf[i])
468                                 ut_params->ibuf[i] = NULL;
469                         ut_params->obuf[i] = NULL;
470                 }
471                 if (ut_params->ibuf[i]) {
472                         rte_pktmbuf_free(ut_params->ibuf[i]);
473                         ut_params->ibuf[i] = NULL;
474                 }
475
476                 if (ut_params->testbuf[i]) {
477                         rte_pktmbuf_free(ut_params->testbuf[i]);
478                         ut_params->testbuf[i] = NULL;
479                 }
480         }
481
482         if (ts_params->mbuf_pool != NULL)
483                 RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
484                         rte_mempool_avail_count(ts_params->mbuf_pool));
485
486         /* Stop the device */
487         rte_cryptodev_stop(ts_params->valid_dev);
488 }
489
490 #define IPSEC_MAX_PAD_SIZE      UINT8_MAX
491
492 static const uint8_t esp_pad_bytes[IPSEC_MAX_PAD_SIZE] = {
493         1, 2, 3, 4, 5, 6, 7, 8,
494         9, 10, 11, 12, 13, 14, 15, 16,
495         17, 18, 19, 20, 21, 22, 23, 24,
496         25, 26, 27, 28, 29, 30, 31, 32,
497         33, 34, 35, 36, 37, 38, 39, 40,
498         41, 42, 43, 44, 45, 46, 47, 48,
499         49, 50, 51, 52, 53, 54, 55, 56,
500         57, 58, 59, 60, 61, 62, 63, 64,
501         65, 66, 67, 68, 69, 70, 71, 72,
502         73, 74, 75, 76, 77, 78, 79, 80,
503         81, 82, 83, 84, 85, 86, 87, 88,
504         89, 90, 91, 92, 93, 94, 95, 96,
505         97, 98, 99, 100, 101, 102, 103, 104,
506         105, 106, 107, 108, 109, 110, 111, 112,
507         113, 114, 115, 116, 117, 118, 119, 120,
508         121, 122, 123, 124, 125, 126, 127, 128,
509         129, 130, 131, 132, 133, 134, 135, 136,
510         137, 138, 139, 140, 141, 142, 143, 144,
511         145, 146, 147, 148, 149, 150, 151, 152,
512         153, 154, 155, 156, 157, 158, 159, 160,
513         161, 162, 163, 164, 165, 166, 167, 168,
514         169, 170, 171, 172, 173, 174, 175, 176,
515         177, 178, 179, 180, 181, 182, 183, 184,
516         185, 186, 187, 188, 189, 190, 191, 192,
517         193, 194, 195, 196, 197, 198, 199, 200,
518         201, 202, 203, 204, 205, 206, 207, 208,
519         209, 210, 211, 212, 213, 214, 215, 216,
520         217, 218, 219, 220, 221, 222, 223, 224,
521         225, 226, 227, 228, 229, 230, 231, 232,
522         233, 234, 235, 236, 237, 238, 239, 240,
523         241, 242, 243, 244, 245, 246, 247, 248,
524         249, 250, 251, 252, 253, 254, 255,
525 };
526
527 /* ***** data for tests ***** */
528
529 const char null_plain_data[] =
530         "Network Security People Have A Strange Sense Of Humor unlike Other "
531         "People who have a normal sense of humour";
532
533 const char null_encrypted_data[] =
534         "Network Security People Have A Strange Sense Of Humor unlike Other "
535         "People who have a normal sense of humour";
536
537 struct rte_ipv4_hdr ipv4_outer  = {
538         .version_ihl = IPVERSION << 4 |
539                 sizeof(ipv4_outer) / RTE_IPV4_IHL_MULTIPLIER,
540         .time_to_live = IPDEFTTL,
541         .next_proto_id = IPPROTO_ESP,
542         .src_addr = RTE_IPV4(192, 168, 1, 100),
543         .dst_addr = RTE_IPV4(192, 168, 2, 100),
544 };
545
546 static struct rte_mbuf *
547 setup_test_string(struct rte_mempool *mpool,
548                 const char *string, size_t len, uint8_t blocksize)
549 {
550         struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
551         size_t t_len = len - (blocksize ? (len % blocksize) : 0);
552
553         if (m) {
554                 memset(m->buf_addr, 0, m->buf_len);
555                 char *dst = rte_pktmbuf_append(m, t_len);
556
557                 if (!dst) {
558                         rte_pktmbuf_free(m);
559                         return NULL;
560                 }
561                 if (string != NULL)
562                         rte_memcpy(dst, string, t_len);
563                 else
564                         memset(dst, 0, t_len);
565         }
566
567         return m;
568 }
569
570 static struct rte_mbuf *
571 setup_test_string_tunneled(struct rte_mempool *mpool, const char *string,
572         size_t len, uint32_t spi, uint32_t seq)
573 {
574         struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
575         uint32_t hdrlen = sizeof(struct rte_ipv4_hdr) +
576                 sizeof(struct rte_esp_hdr);
577         uint32_t taillen = sizeof(struct rte_esp_tail);
578         uint32_t t_len = len + hdrlen + taillen;
579         uint32_t padlen;
580
581         struct rte_esp_hdr esph  = {
582                 .spi = rte_cpu_to_be_32(spi),
583                 .seq = rte_cpu_to_be_32(seq)
584         };
585
586         padlen = RTE_ALIGN(t_len, 4) - t_len;
587         t_len += padlen;
588
589         struct rte_esp_tail espt = {
590                 .pad_len = padlen,
591                 .next_proto = IPPROTO_IPIP,
592         };
593
594         if (m == NULL)
595                 return NULL;
596
597         memset(m->buf_addr, 0, m->buf_len);
598         char *dst = rte_pktmbuf_append(m, t_len);
599
600         if (!dst) {
601                 rte_pktmbuf_free(m);
602                 return NULL;
603         }
604         /* copy outer IP and ESP header */
605         ipv4_outer.total_length = rte_cpu_to_be_16(t_len);
606         ipv4_outer.packet_id = rte_cpu_to_be_16(seq);
607         rte_memcpy(dst, &ipv4_outer, sizeof(ipv4_outer));
608         dst += sizeof(ipv4_outer);
609         m->l3_len = sizeof(ipv4_outer);
610         rte_memcpy(dst, &esph, sizeof(esph));
611         dst += sizeof(esph);
612
613         if (string != NULL) {
614                 /* copy payload */
615                 rte_memcpy(dst, string, len);
616                 dst += len;
617                 /* copy pad bytes */
618                 rte_memcpy(dst, esp_pad_bytes, padlen);
619                 dst += padlen;
620                 /* copy ESP tail header */
621                 rte_memcpy(dst, &espt, sizeof(espt));
622         } else
623                 memset(dst, 0, t_len);
624
625         return m;
626 }
627
628 static int
629 create_dummy_sec_session(struct ipsec_unitest_params *ut,
630         struct rte_cryptodev_qp_conf *qp, uint32_t j)
631 {
632         static struct rte_security_session_conf conf;
633
634         ut->ss[j].security.ses = rte_security_session_create(&dummy_sec_ctx,
635                                         &conf, qp->mp_session,
636                                         qp->mp_session_private);
637
638         if (ut->ss[j].security.ses == NULL)
639                 return -ENOMEM;
640
641         ut->ss[j].security.ctx = &dummy_sec_ctx;
642         ut->ss[j].security.ol_flags = 0;
643         return 0;
644 }
645
646 static int
647 create_crypto_session(struct ipsec_unitest_params *ut,
648         struct rte_cryptodev_qp_conf *qp, uint8_t dev_id, uint32_t j)
649 {
650         int32_t rc;
651         struct rte_cryptodev_sym_session *s;
652
653         s = rte_cryptodev_sym_session_create(qp->mp_session);
654         if (s == NULL)
655                 return -ENOMEM;
656
657         /* initiliaze SA crypto session for device */
658         rc = rte_cryptodev_sym_session_init(dev_id, s,
659                         ut->crypto_xforms, qp->mp_session_private);
660         if (rc == 0) {
661                 ut->ss[j].crypto.ses = s;
662                 return 0;
663         } else {
664                 /* failure, do cleanup */
665                 rte_cryptodev_sym_session_clear(dev_id, s);
666                 rte_cryptodev_sym_session_free(s);
667                 return rc;
668         }
669 }
670
671 static int
672 create_session(struct ipsec_unitest_params *ut,
673         struct rte_cryptodev_qp_conf *qp, uint8_t crypto_dev, uint32_t j)
674 {
675         if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE)
676                 return create_crypto_session(ut, qp, crypto_dev, j);
677         else
678                 return create_dummy_sec_session(ut, qp, j);
679 }
680
681 static int
682 fill_ipsec_param(uint32_t replay_win_sz, uint64_t flags)
683 {
684         struct ipsec_unitest_params *ut_params = &unittest_params;
685         struct rte_ipsec_sa_prm *prm = &ut_params->sa_prm;
686         const struct supported_auth_algo *auth_algo;
687         const struct supported_cipher_algo *cipher_algo;
688
689         memset(prm, 0, sizeof(*prm));
690
691         prm->userdata = 1;
692         prm->flags = flags;
693
694         /* setup ipsec xform */
695         prm->ipsec_xform = ut_params->ipsec_xform;
696         prm->ipsec_xform.salt = (uint32_t)rte_rand();
697         prm->ipsec_xform.replay_win_sz = replay_win_sz;
698
699         /* setup tunnel related fields */
700         prm->tun.hdr_len = sizeof(ipv4_outer);
701         prm->tun.next_proto = IPPROTO_IPIP;
702         prm->tun.hdr = &ipv4_outer;
703
704         /* setup crypto section */
705         if (uparams.aead != 0) {
706                 /* TODO: will need to fill out with other test cases */
707         } else {
708                 if (uparams.auth == 0 && uparams.cipher == 0)
709                         return TEST_FAILED;
710
711                 auth_algo = find_match_auth_algo(uparams.auth_algo);
712                 cipher_algo = find_match_cipher_algo(uparams.cipher_algo);
713
714                 fill_crypto_xform(ut_params, auth_algo, cipher_algo);
715         }
716
717         prm->crypto_xform = ut_params->crypto_xforms;
718         return TEST_SUCCESS;
719 }
720
721 static int
722 create_sa(enum rte_security_session_action_type action_type,
723                 uint32_t replay_win_sz, uint64_t flags, uint32_t j)
724 {
725         struct ipsec_testsuite_params *ts = &testsuite_params;
726         struct ipsec_unitest_params *ut = &unittest_params;
727         size_t sz;
728         int rc;
729
730         memset(&ut->ss[j], 0, sizeof(ut->ss[j]));
731
732         rc = fill_ipsec_param(replay_win_sz, flags);
733         if (rc != 0)
734                 return TEST_FAILED;
735
736         /* create rte_ipsec_sa*/
737         sz = rte_ipsec_sa_size(&ut->sa_prm);
738         TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n");
739
740         ut->ss[j].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
741         TEST_ASSERT_NOT_NULL(ut->ss[j].sa,
742                 "failed to allocate memory for rte_ipsec_sa\n");
743
744         ut->ss[j].type = action_type;
745         rc = create_session(ut, &ts->qp_conf, ts->valid_dev, j);
746         if (rc != 0)
747                 return rc;
748
749         rc = rte_ipsec_sa_init(ut->ss[j].sa, &ut->sa_prm, sz);
750         rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL;
751         if (rc == 0)
752                 rc = rte_ipsec_session_prepare(&ut->ss[j]);
753
754         return rc;
755 }
756
757 static int
758 crypto_dequeue_burst(uint16_t num_pkts)
759 {
760         struct ipsec_testsuite_params *ts_params = &testsuite_params;
761         struct ipsec_unitest_params *ut_params = &unittest_params;
762         uint32_t pkt_cnt, k;
763         int i;
764
765         for (i = 0, pkt_cnt = 0;
766                 i < DEQUEUE_COUNT && pkt_cnt != num_pkts; i++) {
767                 k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0,
768                         &ut_params->cop[pkt_cnt], num_pkts - pkt_cnt);
769                 pkt_cnt += k;
770                 rte_delay_us(1);
771         }
772
773         if (pkt_cnt != num_pkts) {
774                 RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n");
775                 return TEST_FAILED;
776         }
777         return TEST_SUCCESS;
778 }
779
780 static int
781 crypto_ipsec(uint16_t num_pkts)
782 {
783         struct ipsec_testsuite_params *ts_params = &testsuite_params;
784         struct ipsec_unitest_params *ut_params = &unittest_params;
785         uint32_t k, ng;
786         struct rte_ipsec_group grp[1];
787
788         /* call crypto prepare */
789         k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf,
790                 ut_params->cop, num_pkts);
791         if (k != num_pkts) {
792                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
793                 return TEST_FAILED;
794         }
795
796         k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
797                 ut_params->cop, num_pkts);
798         if (k != num_pkts) {
799                 RTE_LOG(ERR, USER1, "rte_cryptodev_enqueue_burst fail\n");
800                 return TEST_FAILED;
801         }
802
803         if (crypto_dequeue_burst(num_pkts) == TEST_FAILED)
804                 return TEST_FAILED;
805
806         ng = rte_ipsec_pkt_crypto_group(
807                 (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
808                 ut_params->obuf, grp, num_pkts);
809         if (ng != 1 ||
810                 grp[0].m[0] != ut_params->obuf[0] ||
811                 grp[0].cnt != num_pkts ||
812                 grp[0].id.ptr != &ut_params->ss[0]) {
813                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n");
814                 return TEST_FAILED;
815         }
816
817         /* call crypto process */
818         k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt);
819         if (k != num_pkts) {
820                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
821                 return TEST_FAILED;
822         }
823
824         return TEST_SUCCESS;
825 }
826
827 static int
828 lksd_proto_ipsec(uint16_t num_pkts)
829 {
830         struct ipsec_unitest_params *ut_params = &unittest_params;
831         uint32_t i, k, ng;
832         struct rte_ipsec_group grp[1];
833
834         /* call crypto prepare */
835         k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf,
836                 ut_params->cop, num_pkts);
837         if (k != num_pkts) {
838                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
839                 return TEST_FAILED;
840         }
841
842         /* check crypto ops */
843         for (i = 0; i != num_pkts; i++) {
844                 TEST_ASSERT_EQUAL(ut_params->cop[i]->type,
845                         RTE_CRYPTO_OP_TYPE_SYMMETRIC,
846                         "%s: invalid crypto op type for %u-th packet\n",
847                         __func__, i);
848                 TEST_ASSERT_EQUAL(ut_params->cop[i]->status,
849                         RTE_CRYPTO_OP_STATUS_NOT_PROCESSED,
850                         "%s: invalid crypto op status for %u-th packet\n",
851                         __func__, i);
852                 TEST_ASSERT_EQUAL(ut_params->cop[i]->sess_type,
853                         RTE_CRYPTO_OP_SECURITY_SESSION,
854                         "%s: invalid crypto op sess_type for %u-th packet\n",
855                         __func__, i);
856                 TEST_ASSERT_EQUAL(ut_params->cop[i]->sym->m_src,
857                         ut_params->ibuf[i],
858                         "%s: invalid crypto op m_src for %u-th packet\n",
859                         __func__, i);
860         }
861
862         /* update crypto ops, pretend all finished ok */
863         for (i = 0; i != num_pkts; i++)
864                 ut_params->cop[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
865
866         ng = rte_ipsec_pkt_crypto_group(
867                 (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
868                 ut_params->obuf, grp, num_pkts);
869         if (ng != 1 ||
870                 grp[0].m[0] != ut_params->obuf[0] ||
871                 grp[0].cnt != num_pkts ||
872                 grp[0].id.ptr != &ut_params->ss[0]) {
873                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n");
874                 return TEST_FAILED;
875         }
876
877         /* call crypto process */
878         k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt);
879         if (k != num_pkts) {
880                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
881                 return TEST_FAILED;
882         }
883
884         return TEST_SUCCESS;
885 }
886
887 static void
888 dump_grp_pkt(uint32_t i, struct rte_ipsec_group *grp, uint32_t k)
889 {
890         RTE_LOG(ERR, USER1,
891                 "After rte_ipsec_pkt_process grp[%d].cnt=%d k=%d fail\n",
892                 i, grp[i].cnt, k);
893         RTE_LOG(ERR, USER1,
894                 "After rte_ipsec_pkt_process grp[%d].m=%p grp[%d].m[%d]=%p\n",
895                 i, grp[i].m, i, k, grp[i].m[k]);
896
897         rte_pktmbuf_dump(stdout, grp[i].m[k], grp[i].m[k]->data_len);
898 }
899
900 static int
901 crypto_ipsec_2sa(void)
902 {
903         struct ipsec_testsuite_params *ts_params = &testsuite_params;
904         struct ipsec_unitest_params *ut_params = &unittest_params;
905         struct rte_ipsec_group grp[BURST_SIZE];
906         uint32_t k, ng, i, r;
907
908         for (i = 0; i < BURST_SIZE; i++) {
909                 r = i % 2;
910                 /* call crypto prepare */
911                 k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[r],
912                                 ut_params->ibuf + i, ut_params->cop + i, 1);
913                 if (k != 1) {
914                         RTE_LOG(ERR, USER1,
915                                 "rte_ipsec_pkt_crypto_prepare fail\n");
916                         return TEST_FAILED;
917                 }
918                 k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
919                                 ut_params->cop + i, 1);
920                 if (k != 1) {
921                         RTE_LOG(ERR, USER1,
922                                 "rte_cryptodev_enqueue_burst fail\n");
923                         return TEST_FAILED;
924                 }
925         }
926
927         if (crypto_dequeue_burst(BURST_SIZE) == TEST_FAILED)
928                 return TEST_FAILED;
929
930         ng = rte_ipsec_pkt_crypto_group(
931                 (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
932                 ut_params->obuf, grp, BURST_SIZE);
933         if (ng != BURST_SIZE) {
934                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n",
935                         ng);
936                 return TEST_FAILED;
937         }
938
939         /* call crypto process */
940         for (i = 0; i < ng; i++) {
941                 k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt);
942                 if (k != grp[i].cnt) {
943                         dump_grp_pkt(i, grp, k);
944                         return TEST_FAILED;
945                 }
946         }
947         return TEST_SUCCESS;
948 }
949
950 #define PKT_4   4
951 #define PKT_12  12
952 #define PKT_21  21
953
954 static uint32_t
955 crypto_ipsec_4grp(uint32_t pkt_num)
956 {
957         uint32_t sa_ind;
958
959         /* group packets in 4 different size groups groups, 2 per SA */
960         if (pkt_num < PKT_4)
961                 sa_ind = 0;
962         else if (pkt_num < PKT_12)
963                 sa_ind = 1;
964         else if (pkt_num < PKT_21)
965                 sa_ind = 0;
966         else
967                 sa_ind = 1;
968
969         return sa_ind;
970 }
971
972 static uint32_t
973 crypto_ipsec_4grp_check_mbufs(uint32_t grp_ind, struct rte_ipsec_group *grp)
974 {
975         struct ipsec_unitest_params *ut_params = &unittest_params;
976         uint32_t i, j;
977         uint32_t rc = 0;
978
979         if (grp_ind == 0) {
980                 for (i = 0, j = 0; i < PKT_4; i++, j++)
981                         if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
982                                 rc = TEST_FAILED;
983                                 break;
984                         }
985         } else if (grp_ind == 1) {
986                 for (i = 0, j = PKT_4; i < (PKT_12 - PKT_4); i++, j++) {
987                         if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
988                                 rc = TEST_FAILED;
989                                 break;
990                         }
991                 }
992         } else if (grp_ind == 2) {
993                 for (i = 0, j =  PKT_12; i < (PKT_21 - PKT_12); i++, j++)
994                         if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
995                                 rc = TEST_FAILED;
996                                 break;
997                         }
998         } else if (grp_ind == 3) {
999                 for (i = 0, j = PKT_21; i < (BURST_SIZE - PKT_21); i++, j++)
1000                         if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
1001                                 rc = TEST_FAILED;
1002                                 break;
1003                         }
1004         } else
1005                 rc = TEST_FAILED;
1006
1007         return rc;
1008 }
1009
1010 static uint32_t
1011 crypto_ipsec_4grp_check_cnt(uint32_t grp_ind, struct rte_ipsec_group *grp)
1012 {
1013         uint32_t rc = 0;
1014
1015         if (grp_ind == 0) {
1016                 if (grp[grp_ind].cnt != PKT_4)
1017                         rc = TEST_FAILED;
1018         } else if (grp_ind == 1) {
1019                 if (grp[grp_ind].cnt != PKT_12 - PKT_4)
1020                         rc = TEST_FAILED;
1021         } else if (grp_ind == 2) {
1022                 if (grp[grp_ind].cnt != PKT_21 - PKT_12)
1023                         rc = TEST_FAILED;
1024         } else if (grp_ind == 3) {
1025                 if (grp[grp_ind].cnt != BURST_SIZE - PKT_21)
1026                         rc = TEST_FAILED;
1027         } else
1028                 rc = TEST_FAILED;
1029
1030         return rc;
1031 }
1032
1033 static int
1034 crypto_ipsec_2sa_4grp(void)
1035 {
1036         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1037         struct ipsec_unitest_params *ut_params = &unittest_params;
1038         struct rte_ipsec_group grp[BURST_SIZE];
1039         uint32_t k, ng, i, j;
1040         uint32_t rc = 0;
1041
1042         for (i = 0; i < BURST_SIZE; i++) {
1043                 j = crypto_ipsec_4grp(i);
1044
1045                 /* call crypto prepare */
1046                 k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[j],
1047                                 ut_params->ibuf + i, ut_params->cop + i, 1);
1048                 if (k != 1) {
1049                         RTE_LOG(ERR, USER1,
1050                                 "rte_ipsec_pkt_crypto_prepare fail\n");
1051                         return TEST_FAILED;
1052                 }
1053                 k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
1054                                 ut_params->cop + i, 1);
1055                 if (k != 1) {
1056                         RTE_LOG(ERR, USER1,
1057                                 "rte_cryptodev_enqueue_burst fail\n");
1058                         return TEST_FAILED;
1059                 }
1060         }
1061
1062         if (crypto_dequeue_burst(BURST_SIZE) == TEST_FAILED)
1063                 return TEST_FAILED;
1064
1065         ng = rte_ipsec_pkt_crypto_group(
1066                 (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
1067                 ut_params->obuf, grp, BURST_SIZE);
1068         if (ng != 4) {
1069                 RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n",
1070                         ng);
1071                 return TEST_FAILED;
1072         }
1073
1074         /* call crypto process */
1075         for (i = 0; i < ng; i++) {
1076                 k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt);
1077                 if (k != grp[i].cnt) {
1078                         dump_grp_pkt(i, grp, k);
1079                         return TEST_FAILED;
1080                 }
1081                 rc = crypto_ipsec_4grp_check_cnt(i, grp);
1082                 if (rc != 0) {
1083                         RTE_LOG(ERR, USER1,
1084                                 "crypto_ipsec_4grp_check_cnt fail\n");
1085                         return TEST_FAILED;
1086                 }
1087                 rc = crypto_ipsec_4grp_check_mbufs(i, grp);
1088                 if (rc != 0) {
1089                         RTE_LOG(ERR, USER1,
1090                                 "crypto_ipsec_4grp_check_mbufs fail\n");
1091                         return TEST_FAILED;
1092                 }
1093         }
1094         return TEST_SUCCESS;
1095 }
1096
1097 static void
1098 test_ipsec_reorder_inb_pkt_burst(uint16_t num_pkts)
1099 {
1100         struct ipsec_unitest_params *ut_params = &unittest_params;
1101         struct rte_mbuf *ibuf_tmp[BURST_SIZE];
1102         uint16_t j;
1103
1104         /* reorder packets and create gaps in sequence numbers */
1105         static const uint32_t reorder[BURST_SIZE] = {
1106                         24, 25, 26, 27, 28, 29, 30, 31,
1107                         16, 17, 18, 19, 20, 21, 22, 23,
1108                         8, 9, 10, 11, 12, 13, 14, 15,
1109                         0, 1, 2, 3, 4, 5, 6, 7,
1110         };
1111
1112         if (num_pkts != BURST_SIZE)
1113                 return;
1114
1115         for (j = 0; j != BURST_SIZE; j++)
1116                 ibuf_tmp[j] = ut_params->ibuf[reorder[j]];
1117
1118         memcpy(ut_params->ibuf, ibuf_tmp, sizeof(ut_params->ibuf));
1119 }
1120
1121 static int
1122 test_ipsec_crypto_op_alloc(uint16_t num_pkts)
1123 {
1124         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1125         struct ipsec_unitest_params *ut_params = &unittest_params;
1126         int rc = 0;
1127         uint16_t j;
1128
1129         for (j = 0; j < num_pkts && rc == 0; j++) {
1130                 ut_params->cop[j] = rte_crypto_op_alloc(ts_params->cop_mpool,
1131                                 RTE_CRYPTO_OP_TYPE_SYMMETRIC);
1132                 if (ut_params->cop[j] == NULL) {
1133                         RTE_LOG(ERR, USER1,
1134                                 "Failed to allocate symmetric crypto op\n");
1135                         rc = TEST_FAILED;
1136                 }
1137         }
1138
1139         return rc;
1140 }
1141
1142 static void
1143 test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i)
1144 {
1145         uint16_t j = ut_params->pkt_index;
1146
1147         printf("\ntest config: num %d\n", i);
1148         printf("        replay_win_sz %u\n", test_cfg[i].replay_win_sz);
1149         printf("        esn %u\n", test_cfg[i].esn);
1150         printf("        flags 0x%" PRIx64 "\n", test_cfg[i].flags);
1151         printf("        pkt_sz %zu\n", test_cfg[i].pkt_sz);
1152         printf("        num_pkts %u\n\n", test_cfg[i].num_pkts);
1153
1154         if (ut_params->ibuf[j]) {
1155                 printf("ibuf[%u] data:\n", j);
1156                 rte_pktmbuf_dump(stdout, ut_params->ibuf[j],
1157                         ut_params->ibuf[j]->data_len);
1158         }
1159         if (ut_params->obuf[j]) {
1160                 printf("obuf[%u] data:\n", j);
1161                 rte_pktmbuf_dump(stdout, ut_params->obuf[j],
1162                         ut_params->obuf[j]->data_len);
1163         }
1164         if (ut_params->testbuf[j]) {
1165                 printf("testbuf[%u] data:\n", j);
1166                 rte_pktmbuf_dump(stdout, ut_params->testbuf[j],
1167                         ut_params->testbuf[j]->data_len);
1168         }
1169 }
1170
1171 static void
1172 destroy_dummy_sec_session(struct ipsec_unitest_params *ut,
1173         uint32_t j)
1174 {
1175         rte_security_session_destroy(&dummy_sec_ctx,
1176                                         ut->ss[j].security.ses);
1177         ut->ss[j].security.ctx = NULL;
1178 }
1179
1180 static void
1181 destroy_crypto_session(struct ipsec_unitest_params *ut,
1182         uint8_t crypto_dev, uint32_t j)
1183 {
1184         rte_cryptodev_sym_session_clear(crypto_dev, ut->ss[j].crypto.ses);
1185         rte_cryptodev_sym_session_free(ut->ss[j].crypto.ses);
1186         memset(&ut->ss[j], 0, sizeof(ut->ss[j]));
1187 }
1188
1189 static void
1190 destroy_session(struct ipsec_unitest_params *ut,
1191         uint8_t crypto_dev, uint32_t j)
1192 {
1193         if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE)
1194                 return destroy_crypto_session(ut, crypto_dev, j);
1195         else
1196                 return destroy_dummy_sec_session(ut, j);
1197 }
1198
1199 static void
1200 destroy_sa(uint32_t j)
1201 {
1202         struct ipsec_unitest_params *ut = &unittest_params;
1203         struct ipsec_testsuite_params *ts = &testsuite_params;
1204
1205         rte_ipsec_sa_fini(ut->ss[j].sa);
1206         rte_free(ut->ss[j].sa);
1207
1208         destroy_session(ut, ts->valid_dev, j);
1209 }
1210
1211 static int
1212 crypto_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1213                 uint16_t num_pkts)
1214 {
1215         uint16_t j;
1216
1217         for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1218                 ut_params->pkt_index = j;
1219
1220                 /* compare the data buffers */
1221                 TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
1222                         rte_pktmbuf_mtod(ut_params->obuf[j], void *),
1223                         test_cfg[i].pkt_sz,
1224                         "input and output data does not match\n");
1225                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1226                         ut_params->obuf[j]->pkt_len,
1227                         "data_len is not equal to pkt_len");
1228                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1229                         test_cfg[i].pkt_sz,
1230                         "data_len is not equal to input data");
1231         }
1232
1233         return 0;
1234 }
1235
1236 static int
1237 test_ipsec_crypto_inb_burst_null_null(int i)
1238 {
1239         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1240         struct ipsec_unitest_params *ut_params = &unittest_params;
1241         uint16_t num_pkts = test_cfg[i].num_pkts;
1242         uint16_t j;
1243         int rc;
1244
1245         /* create rte_ipsec_sa */
1246         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1247                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1248         if (rc != 0) {
1249                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1250                 return rc;
1251         }
1252
1253         /* Generate test mbuf data */
1254         for (j = 0; j < num_pkts && rc == 0; j++) {
1255                 /* packet with sequence number 0 is invalid */
1256                 ut_params->ibuf[j] = setup_test_string_tunneled(
1257                         ts_params->mbuf_pool, null_encrypted_data,
1258                         test_cfg[i].pkt_sz, INBOUND_SPI, j + 1);
1259                 if (ut_params->ibuf[j] == NULL)
1260                         rc = TEST_FAILED;
1261         }
1262
1263         if (rc == 0) {
1264                 if (test_cfg[i].reorder_pkts)
1265                         test_ipsec_reorder_inb_pkt_burst(num_pkts);
1266                 rc = test_ipsec_crypto_op_alloc(num_pkts);
1267         }
1268
1269         if (rc == 0) {
1270                 /* call ipsec library api */
1271                 rc = crypto_ipsec(num_pkts);
1272                 if (rc == 0)
1273                         rc = crypto_inb_burst_null_null_check(
1274                                         ut_params, i, num_pkts);
1275                 else {
1276                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1277                                 i);
1278                         rc = TEST_FAILED;
1279                 }
1280         }
1281
1282         if (rc == TEST_FAILED)
1283                 test_ipsec_dump_buffers(ut_params, i);
1284
1285         destroy_sa(0);
1286         return rc;
1287 }
1288
1289 static int
1290 test_ipsec_crypto_inb_burst_null_null_wrapper(void)
1291 {
1292         int i;
1293         int rc = 0;
1294         struct ipsec_unitest_params *ut_params = &unittest_params;
1295
1296         ut_params->ipsec_xform.spi = INBOUND_SPI;
1297         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1298         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1299         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1300         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1301
1302         for (i = 0; i < num_cfg && rc == 0; i++) {
1303                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1304                 rc = test_ipsec_crypto_inb_burst_null_null(i);
1305         }
1306
1307         return rc;
1308 }
1309
1310 static int
1311 crypto_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params,
1312         uint16_t num_pkts)
1313 {
1314         void *obuf_data;
1315         void *testbuf_data;
1316         uint16_t j;
1317
1318         for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1319                 ut_params->pkt_index = j;
1320
1321                 testbuf_data = rte_pktmbuf_mtod(ut_params->testbuf[j], void *);
1322                 obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1323                 /* compare the buffer data */
1324                 TEST_ASSERT_BUFFERS_ARE_EQUAL(testbuf_data, obuf_data,
1325                         ut_params->obuf[j]->pkt_len,
1326                         "test and output data does not match\n");
1327                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1328                         ut_params->testbuf[j]->data_len,
1329                         "obuf data_len is not equal to testbuf data_len");
1330                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->pkt_len,
1331                         ut_params->testbuf[j]->pkt_len,
1332                         "obuf pkt_len is not equal to testbuf pkt_len");
1333         }
1334
1335         return 0;
1336 }
1337
1338 static int
1339 test_ipsec_crypto_outb_burst_null_null(int i)
1340 {
1341         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1342         struct ipsec_unitest_params *ut_params = &unittest_params;
1343         uint16_t num_pkts = test_cfg[i].num_pkts;
1344         uint16_t j;
1345         int32_t rc;
1346
1347         /* create rte_ipsec_sa*/
1348         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1349                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1350         if (rc != 0) {
1351                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1352                 return rc;
1353         }
1354
1355         /* Generate input mbuf data */
1356         for (j = 0; j < num_pkts && rc == 0; j++) {
1357                 ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1358                         null_plain_data, test_cfg[i].pkt_sz, 0);
1359                 if (ut_params->ibuf[j] == NULL)
1360                         rc = TEST_FAILED;
1361                 else {
1362                         /* Generate test mbuf data */
1363                         /* packet with sequence number 0 is invalid */
1364                         ut_params->testbuf[j] = setup_test_string_tunneled(
1365                                         ts_params->mbuf_pool,
1366                                         null_plain_data, test_cfg[i].pkt_sz,
1367                                         OUTBOUND_SPI, j + 1);
1368                         if (ut_params->testbuf[j] == NULL)
1369                                 rc = TEST_FAILED;
1370                 }
1371         }
1372
1373         if (rc == 0)
1374                 rc = test_ipsec_crypto_op_alloc(num_pkts);
1375
1376         if (rc == 0) {
1377                 /* call ipsec library api */
1378                 rc = crypto_ipsec(num_pkts);
1379                 if (rc == 0)
1380                         rc = crypto_outb_burst_null_null_check(ut_params,
1381                                         num_pkts);
1382                 else
1383                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1384                                 i);
1385         }
1386
1387         if (rc == TEST_FAILED)
1388                 test_ipsec_dump_buffers(ut_params, i);
1389
1390         destroy_sa(0);
1391         return rc;
1392 }
1393
1394 static int
1395 test_ipsec_crypto_outb_burst_null_null_wrapper(void)
1396 {
1397         int i;
1398         int rc = 0;
1399         struct ipsec_unitest_params *ut_params = &unittest_params;
1400
1401         ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1402         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1403         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1404         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1405         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1406
1407         for (i = 0; i < num_cfg && rc == 0; i++) {
1408                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1409                 rc = test_ipsec_crypto_outb_burst_null_null(i);
1410         }
1411
1412         return rc;
1413 }
1414
1415 static int
1416 inline_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1417         uint16_t num_pkts)
1418 {
1419         void *ibuf_data;
1420         void *obuf_data;
1421         uint16_t j;
1422
1423         for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1424                 ut_params->pkt_index = j;
1425
1426                 /* compare the buffer data */
1427                 ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *);
1428                 obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1429
1430                 TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
1431                         ut_params->ibuf[j]->data_len,
1432                         "input and output data does not match\n");
1433                 TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1434                         ut_params->obuf[j]->data_len,
1435                         "ibuf data_len is not equal to obuf data_len");
1436                 TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len,
1437                         ut_params->obuf[j]->pkt_len,
1438                         "ibuf pkt_len is not equal to obuf pkt_len");
1439                 TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1440                         test_cfg[i].pkt_sz,
1441                         "data_len is not equal input data");
1442         }
1443         return 0;
1444 }
1445
1446 static int
1447 test_ipsec_inline_crypto_inb_burst_null_null(int i)
1448 {
1449         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1450         struct ipsec_unitest_params *ut_params = &unittest_params;
1451         uint16_t num_pkts = test_cfg[i].num_pkts;
1452         uint16_t j;
1453         int32_t rc;
1454         uint32_t n;
1455
1456         /* create rte_ipsec_sa*/
1457         rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
1458                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1459         if (rc != 0) {
1460                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1461                 return rc;
1462         }
1463
1464         /* Generate inbound mbuf data */
1465         for (j = 0; j < num_pkts && rc == 0; j++) {
1466                 ut_params->ibuf[j] = setup_test_string_tunneled(
1467                         ts_params->mbuf_pool,
1468                         null_plain_data, test_cfg[i].pkt_sz,
1469                         INBOUND_SPI, j + 1);
1470                 if (ut_params->ibuf[j] == NULL)
1471                         rc = TEST_FAILED;
1472                 else {
1473                         /* Generate test mbuf data */
1474                         ut_params->obuf[j] = setup_test_string(
1475                                 ts_params->mbuf_pool,
1476                                 null_plain_data, test_cfg[i].pkt_sz, 0);
1477                         if (ut_params->obuf[j] == NULL)
1478                                 rc = TEST_FAILED;
1479                 }
1480         }
1481
1482         if (rc == 0) {
1483                 n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1484                                 num_pkts);
1485                 if (n == num_pkts)
1486                         rc = inline_inb_burst_null_null_check(ut_params, i,
1487                                         num_pkts);
1488                 else {
1489                         RTE_LOG(ERR, USER1,
1490                                 "rte_ipsec_pkt_process failed, cfg %d\n",
1491                                 i);
1492                         rc = TEST_FAILED;
1493                 }
1494         }
1495
1496         if (rc == TEST_FAILED)
1497                 test_ipsec_dump_buffers(ut_params, i);
1498
1499         destroy_sa(0);
1500         return rc;
1501 }
1502
1503 static int
1504 test_ipsec_inline_crypto_inb_burst_null_null_wrapper(void)
1505 {
1506         int i;
1507         int rc = 0;
1508         struct ipsec_unitest_params *ut_params = &unittest_params;
1509
1510         ut_params->ipsec_xform.spi = INBOUND_SPI;
1511         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1512         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1513         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1514         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1515
1516         for (i = 0; i < num_cfg && rc == 0; i++) {
1517                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1518                 rc = test_ipsec_inline_crypto_inb_burst_null_null(i);
1519         }
1520
1521         return rc;
1522 }
1523
1524 static int
1525 test_ipsec_inline_proto_inb_burst_null_null(int i)
1526 {
1527         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1528         struct ipsec_unitest_params *ut_params = &unittest_params;
1529         uint16_t num_pkts = test_cfg[i].num_pkts;
1530         uint16_t j;
1531         int32_t rc;
1532         uint32_t n;
1533
1534         /* create rte_ipsec_sa*/
1535         rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
1536                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1537         if (rc != 0) {
1538                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1539                 return rc;
1540         }
1541
1542         /* Generate inbound mbuf data */
1543         for (j = 0; j < num_pkts && rc == 0; j++) {
1544                 ut_params->ibuf[j] = setup_test_string(
1545                         ts_params->mbuf_pool,
1546                         null_plain_data, test_cfg[i].pkt_sz, 0);
1547                 if (ut_params->ibuf[j] == NULL)
1548                         rc = TEST_FAILED;
1549                 else {
1550                         /* Generate test mbuf data */
1551                         ut_params->obuf[j] = setup_test_string(
1552                                 ts_params->mbuf_pool,
1553                                 null_plain_data, test_cfg[i].pkt_sz, 0);
1554                         if (ut_params->obuf[j] == NULL)
1555                                 rc = TEST_FAILED;
1556                 }
1557         }
1558
1559         if (rc == 0) {
1560                 n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1561                                 num_pkts);
1562                 if (n == num_pkts)
1563                         rc = inline_inb_burst_null_null_check(ut_params, i,
1564                                         num_pkts);
1565                 else {
1566                         RTE_LOG(ERR, USER1,
1567                                 "rte_ipsec_pkt_process failed, cfg %d\n",
1568                                 i);
1569                         rc = TEST_FAILED;
1570                 }
1571         }
1572
1573         if (rc == TEST_FAILED)
1574                 test_ipsec_dump_buffers(ut_params, i);
1575
1576         destroy_sa(0);
1577         return rc;
1578 }
1579
1580 static int
1581 test_ipsec_inline_proto_inb_burst_null_null_wrapper(void)
1582 {
1583         int i;
1584         int rc = 0;
1585         struct ipsec_unitest_params *ut_params = &unittest_params;
1586
1587         ut_params->ipsec_xform.spi = INBOUND_SPI;
1588         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1589         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1590         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1591         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1592
1593         for (i = 0; i < num_cfg && rc == 0; i++) {
1594                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1595                 rc = test_ipsec_inline_proto_inb_burst_null_null(i);
1596         }
1597
1598         return rc;
1599 }
1600
1601 static int
1602 inline_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params,
1603         uint16_t num_pkts)
1604 {
1605         void *obuf_data;
1606         void *ibuf_data;
1607         uint16_t j;
1608
1609         for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1610                 ut_params->pkt_index = j;
1611
1612                 /* compare the buffer data */
1613                 ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *);
1614                 obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1615                 TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
1616                         ut_params->ibuf[j]->data_len,
1617                         "input and output data does not match\n");
1618                 TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1619                         ut_params->obuf[j]->data_len,
1620                         "ibuf data_len is not equal to obuf data_len");
1621                 TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len,
1622                         ut_params->obuf[j]->pkt_len,
1623                         "ibuf pkt_len is not equal to obuf pkt_len");
1624
1625                 /* check mbuf ol_flags */
1626                 TEST_ASSERT(ut_params->ibuf[j]->ol_flags & PKT_TX_SEC_OFFLOAD,
1627                         "ibuf PKT_TX_SEC_OFFLOAD is not set");
1628         }
1629         return 0;
1630 }
1631
1632 static int
1633 test_ipsec_inline_crypto_outb_burst_null_null(int i)
1634 {
1635         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1636         struct ipsec_unitest_params *ut_params = &unittest_params;
1637         uint16_t num_pkts = test_cfg[i].num_pkts;
1638         uint16_t j;
1639         int32_t rc;
1640         uint32_t n;
1641
1642         /* create rte_ipsec_sa */
1643         rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
1644                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1645         if (rc != 0) {
1646                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1647                 return rc;
1648         }
1649
1650         /* Generate test mbuf data */
1651         for (j = 0; j < num_pkts && rc == 0; j++) {
1652                 ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1653                         null_plain_data, test_cfg[i].pkt_sz, 0);
1654                 if (ut_params->ibuf[0] == NULL)
1655                         rc = TEST_FAILED;
1656
1657                 if (rc == 0) {
1658                         /* Generate test tunneled mbuf data for comparison */
1659                         ut_params->obuf[j] = setup_test_string_tunneled(
1660                                         ts_params->mbuf_pool,
1661                                         null_plain_data, test_cfg[i].pkt_sz,
1662                                         OUTBOUND_SPI, j + 1);
1663                         if (ut_params->obuf[j] == NULL)
1664                                 rc = TEST_FAILED;
1665                 }
1666         }
1667
1668         if (rc == 0) {
1669                 n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1670                                 num_pkts);
1671                 if (n == num_pkts)
1672                         rc = inline_outb_burst_null_null_check(ut_params,
1673                                         num_pkts);
1674                 else {
1675                         RTE_LOG(ERR, USER1,
1676                                 "rte_ipsec_pkt_process failed, cfg %d\n",
1677                                 i);
1678                         rc = TEST_FAILED;
1679                 }
1680         }
1681
1682         if (rc == TEST_FAILED)
1683                 test_ipsec_dump_buffers(ut_params, i);
1684
1685         destroy_sa(0);
1686         return rc;
1687 }
1688
1689 static int
1690 test_ipsec_inline_crypto_outb_burst_null_null_wrapper(void)
1691 {
1692         int i;
1693         int rc = 0;
1694         struct ipsec_unitest_params *ut_params = &unittest_params;
1695
1696         ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1697         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1698         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1699         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1700         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1701
1702         for (i = 0; i < num_cfg && rc == 0; i++) {
1703                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1704                 rc = test_ipsec_inline_crypto_outb_burst_null_null(i);
1705         }
1706
1707         return rc;
1708 }
1709
1710 static int
1711 test_ipsec_inline_proto_outb_burst_null_null(int i)
1712 {
1713         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1714         struct ipsec_unitest_params *ut_params = &unittest_params;
1715         uint16_t num_pkts = test_cfg[i].num_pkts;
1716         uint16_t j;
1717         int32_t rc;
1718         uint32_t n;
1719
1720         /* create rte_ipsec_sa */
1721         rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
1722                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1723         if (rc != 0) {
1724                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1725                 return rc;
1726         }
1727
1728         /* Generate test mbuf data */
1729         for (j = 0; j < num_pkts && rc == 0; j++) {
1730                 ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1731                         null_plain_data, test_cfg[i].pkt_sz, 0);
1732                 if (ut_params->ibuf[0] == NULL)
1733                         rc = TEST_FAILED;
1734
1735                 if (rc == 0) {
1736                         /* Generate test tunneled mbuf data for comparison */
1737                         ut_params->obuf[j] = setup_test_string(
1738                                         ts_params->mbuf_pool,
1739                                         null_plain_data, test_cfg[i].pkt_sz, 0);
1740                         if (ut_params->obuf[j] == NULL)
1741                                 rc = TEST_FAILED;
1742                 }
1743         }
1744
1745         if (rc == 0) {
1746                 n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1747                                 num_pkts);
1748                 if (n == num_pkts)
1749                         rc = inline_outb_burst_null_null_check(ut_params,
1750                                         num_pkts);
1751                 else {
1752                         RTE_LOG(ERR, USER1,
1753                                 "rte_ipsec_pkt_process failed, cfg %d\n",
1754                                 i);
1755                         rc = TEST_FAILED;
1756                 }
1757         }
1758
1759         if (rc == TEST_FAILED)
1760                 test_ipsec_dump_buffers(ut_params, i);
1761
1762         destroy_sa(0);
1763         return rc;
1764 }
1765
1766 static int
1767 test_ipsec_inline_proto_outb_burst_null_null_wrapper(void)
1768 {
1769         int i;
1770         int rc = 0;
1771         struct ipsec_unitest_params *ut_params = &unittest_params;
1772
1773         ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1774         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1775         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1776         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1777         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1778
1779         for (i = 0; i < num_cfg && rc == 0; i++) {
1780                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1781                 rc = test_ipsec_inline_proto_outb_burst_null_null(i);
1782         }
1783
1784         return rc;
1785 }
1786
1787 static int
1788 test_ipsec_lksd_proto_inb_burst_null_null(int i)
1789 {
1790         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1791         struct ipsec_unitest_params *ut_params = &unittest_params;
1792         uint16_t num_pkts = test_cfg[i].num_pkts;
1793         uint16_t j;
1794         int rc;
1795
1796         /* create rte_ipsec_sa */
1797         rc = create_sa(RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
1798                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1799         if (rc != 0) {
1800                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1801                 return rc;
1802         }
1803
1804         /* Generate test mbuf data */
1805         for (j = 0; j < num_pkts && rc == 0; j++) {
1806                 /* packet with sequence number 0 is invalid */
1807                 ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1808                         null_encrypted_data, test_cfg[i].pkt_sz, 0);
1809                 if (ut_params->ibuf[j] == NULL)
1810                         rc = TEST_FAILED;
1811         }
1812
1813         if (rc == 0) {
1814                 if (test_cfg[i].reorder_pkts)
1815                         test_ipsec_reorder_inb_pkt_burst(num_pkts);
1816                 rc = test_ipsec_crypto_op_alloc(num_pkts);
1817         }
1818
1819         if (rc == 0) {
1820                 /* call ipsec library api */
1821                 rc = lksd_proto_ipsec(num_pkts);
1822                 if (rc == 0)
1823                         rc = crypto_inb_burst_null_null_check(ut_params, i,
1824                                         num_pkts);
1825                 else {
1826                         RTE_LOG(ERR, USER1, "%s failed, cfg %d\n",
1827                                 __func__, i);
1828                         rc = TEST_FAILED;
1829                 }
1830         }
1831
1832         if (rc == TEST_FAILED)
1833                 test_ipsec_dump_buffers(ut_params, i);
1834
1835         destroy_sa(0);
1836         return rc;
1837 }
1838
1839 static int
1840 test_ipsec_lksd_proto_inb_burst_null_null_wrapper(void)
1841 {
1842         int i;
1843         int rc = 0;
1844         struct ipsec_unitest_params *ut_params = &unittest_params;
1845
1846         ut_params->ipsec_xform.spi = INBOUND_SPI;
1847         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1848         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1849         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1850         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1851
1852         for (i = 0; i < num_cfg && rc == 0; i++) {
1853                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1854                 rc = test_ipsec_lksd_proto_inb_burst_null_null(i);
1855         }
1856
1857         return rc;
1858 }
1859
1860 static int
1861 test_ipsec_lksd_proto_outb_burst_null_null_wrapper(void)
1862 {
1863         int i;
1864         int rc = 0;
1865         struct ipsec_unitest_params *ut_params = &unittest_params;
1866
1867         ut_params->ipsec_xform.spi = INBOUND_SPI;
1868         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1869         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1870         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1871         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1872
1873         for (i = 0; i < num_cfg && rc == 0; i++) {
1874                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1875                 rc = test_ipsec_lksd_proto_inb_burst_null_null(i);
1876         }
1877
1878         return rc;
1879 }
1880
1881 static int
1882 replay_inb_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1883         int num_pkts)
1884 {
1885         uint16_t j;
1886
1887         for (j = 0; j < num_pkts; j++) {
1888                 /* compare the buffer data */
1889                 TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
1890                         rte_pktmbuf_mtod(ut_params->obuf[j], void *),
1891                         test_cfg[i].pkt_sz,
1892                         "input and output data does not match\n");
1893
1894                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1895                         ut_params->obuf[j]->pkt_len,
1896                         "data_len is not equal to pkt_len");
1897         }
1898
1899         return 0;
1900 }
1901
1902 static int
1903 test_ipsec_replay_inb_inside_null_null(int i)
1904 {
1905         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1906         struct ipsec_unitest_params *ut_params = &unittest_params;
1907         int rc;
1908
1909         /* create rte_ipsec_sa*/
1910         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1911                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1912         if (rc != 0) {
1913                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1914                 return rc;
1915         }
1916
1917         /* Generate inbound mbuf data */
1918         ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
1919                 null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
1920         if (ut_params->ibuf[0] == NULL)
1921                 rc = TEST_FAILED;
1922         else
1923                 rc = test_ipsec_crypto_op_alloc(1);
1924
1925         if (rc == 0) {
1926                 /* call ipsec library api */
1927                 rc = crypto_ipsec(1);
1928                 if (rc == 0)
1929                         rc = replay_inb_null_null_check(ut_params, i, 1);
1930                 else {
1931                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1932                                         i);
1933                         rc = TEST_FAILED;
1934                 }
1935         }
1936
1937         if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
1938                 /* generate packet with seq number inside the replay window */
1939                 if (ut_params->ibuf[0]) {
1940                         rte_pktmbuf_free(ut_params->ibuf[0]);
1941                         ut_params->ibuf[0] = 0;
1942                 }
1943
1944                 ut_params->ibuf[0] = setup_test_string_tunneled(
1945                         ts_params->mbuf_pool, null_encrypted_data,
1946                         test_cfg[i].pkt_sz, INBOUND_SPI,
1947                         test_cfg[i].replay_win_sz);
1948                 if (ut_params->ibuf[0] == NULL)
1949                         rc = TEST_FAILED;
1950                 else
1951                         rc = test_ipsec_crypto_op_alloc(1);
1952
1953                 if (rc == 0) {
1954                         /* call ipsec library api */
1955                         rc = crypto_ipsec(1);
1956                         if (rc == 0)
1957                                 rc = replay_inb_null_null_check(
1958                                                 ut_params, i, 1);
1959                         else {
1960                                 RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
1961                                 rc = TEST_FAILED;
1962                         }
1963                 }
1964         }
1965
1966         if (rc == TEST_FAILED)
1967                 test_ipsec_dump_buffers(ut_params, i);
1968
1969         destroy_sa(0);
1970
1971         return rc;
1972 }
1973
1974 static int
1975 test_ipsec_replay_inb_inside_null_null_wrapper(void)
1976 {
1977         int i;
1978         int rc = 0;
1979         struct ipsec_unitest_params *ut_params = &unittest_params;
1980
1981         ut_params->ipsec_xform.spi = INBOUND_SPI;
1982         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1983         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1984         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1985         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1986
1987         for (i = 0; i < num_cfg && rc == 0; i++) {
1988                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1989                 rc = test_ipsec_replay_inb_inside_null_null(i);
1990         }
1991
1992         return rc;
1993 }
1994
1995 static int
1996 test_ipsec_replay_inb_outside_null_null(int i)
1997 {
1998         struct ipsec_testsuite_params *ts_params = &testsuite_params;
1999         struct ipsec_unitest_params *ut_params = &unittest_params;
2000         int rc;
2001
2002         /* create rte_ipsec_sa */
2003         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2004                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2005         if (rc != 0) {
2006                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2007                 return rc;
2008         }
2009
2010         /* Generate test mbuf data */
2011         ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2012                 null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI,
2013                 test_cfg[i].replay_win_sz + 2);
2014         if (ut_params->ibuf[0] == NULL)
2015                 rc = TEST_FAILED;
2016         else
2017                 rc = test_ipsec_crypto_op_alloc(1);
2018
2019         if (rc == 0) {
2020                 /* call ipsec library api */
2021                 rc = crypto_ipsec(1);
2022                 if (rc == 0)
2023                         rc = replay_inb_null_null_check(ut_params, i, 1);
2024                 else {
2025                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2026                                         i);
2027                         rc = TEST_FAILED;
2028                 }
2029         }
2030
2031         if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2032                 /* generate packet with seq number outside the replay window */
2033                 if (ut_params->ibuf[0]) {
2034                         rte_pktmbuf_free(ut_params->ibuf[0]);
2035                         ut_params->ibuf[0] = 0;
2036                 }
2037                 ut_params->ibuf[0] = setup_test_string_tunneled(
2038                         ts_params->mbuf_pool, null_encrypted_data,
2039                         test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2040                 if (ut_params->ibuf[0] == NULL)
2041                         rc = TEST_FAILED;
2042                 else
2043                         rc = test_ipsec_crypto_op_alloc(1);
2044
2045                 if (rc == 0) {
2046                         /* call ipsec library api */
2047                         rc = crypto_ipsec(1);
2048                         if (rc == 0) {
2049                                 if (test_cfg[i].esn == 0) {
2050                                         RTE_LOG(ERR, USER1,
2051                                                 "packet is not outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n",
2052                                                 i,
2053                                                 test_cfg[i].replay_win_sz + 2,
2054                                                 1);
2055                                         rc = TEST_FAILED;
2056                                 }
2057                         } else {
2058                                 RTE_LOG(ERR, USER1,
2059                                         "packet is outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n",
2060                                         i, test_cfg[i].replay_win_sz + 2, 1);
2061                                 rc = 0;
2062                         }
2063                 }
2064         }
2065
2066         if (rc == TEST_FAILED)
2067                 test_ipsec_dump_buffers(ut_params, i);
2068
2069         destroy_sa(0);
2070
2071         return rc;
2072 }
2073
2074 static int
2075 test_ipsec_replay_inb_outside_null_null_wrapper(void)
2076 {
2077         int i;
2078         int rc = 0;
2079         struct ipsec_unitest_params *ut_params = &unittest_params;
2080
2081         ut_params->ipsec_xform.spi = INBOUND_SPI;
2082         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2083         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2084         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2085         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2086
2087         for (i = 0; i < num_cfg && rc == 0; i++) {
2088                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2089                 rc = test_ipsec_replay_inb_outside_null_null(i);
2090         }
2091
2092         return rc;
2093 }
2094
2095 static int
2096 test_ipsec_replay_inb_repeat_null_null(int i)
2097 {
2098         struct ipsec_testsuite_params *ts_params = &testsuite_params;
2099         struct ipsec_unitest_params *ut_params = &unittest_params;
2100         int rc;
2101
2102         /* create rte_ipsec_sa */
2103         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2104                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2105         if (rc != 0) {
2106                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2107                 return rc;
2108         }
2109
2110         /* Generate test mbuf data */
2111         ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2112                 null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2113         if (ut_params->ibuf[0] == NULL)
2114                 rc = TEST_FAILED;
2115         else
2116                 rc = test_ipsec_crypto_op_alloc(1);
2117
2118         if (rc == 0) {
2119                 /* call ipsec library api */
2120                 rc = crypto_ipsec(1);
2121                 if (rc == 0)
2122                         rc = replay_inb_null_null_check(ut_params, i, 1);
2123                 else {
2124                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2125                                         i);
2126                         rc = TEST_FAILED;
2127                 }
2128         }
2129
2130         if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2131                 /*
2132                  * generate packet with repeat seq number in the replay
2133                  * window
2134                  */
2135                 if (ut_params->ibuf[0]) {
2136                         rte_pktmbuf_free(ut_params->ibuf[0]);
2137                         ut_params->ibuf[0] = 0;
2138                 }
2139
2140                 ut_params->ibuf[0] = setup_test_string_tunneled(
2141                         ts_params->mbuf_pool, null_encrypted_data,
2142                         test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2143                 if (ut_params->ibuf[0] == NULL)
2144                         rc = TEST_FAILED;
2145                 else
2146                         rc = test_ipsec_crypto_op_alloc(1);
2147
2148                 if (rc == 0) {
2149                         /* call ipsec library api */
2150                         rc = crypto_ipsec(1);
2151                         if (rc == 0) {
2152                                 RTE_LOG(ERR, USER1,
2153                                         "packet is not repeated in the replay window, cfg %d seq %u\n",
2154                                         i, 1);
2155                                 rc = TEST_FAILED;
2156                         } else {
2157                                 RTE_LOG(ERR, USER1,
2158                                         "packet is repeated in the replay window, cfg %d seq %u\n",
2159                                         i, 1);
2160                                 rc = 0;
2161                         }
2162                 }
2163         }
2164
2165         if (rc == TEST_FAILED)
2166                 test_ipsec_dump_buffers(ut_params, i);
2167
2168         destroy_sa(0);
2169
2170         return rc;
2171 }
2172
2173 static int
2174 test_ipsec_replay_inb_repeat_null_null_wrapper(void)
2175 {
2176         int i;
2177         int rc = 0;
2178         struct ipsec_unitest_params *ut_params = &unittest_params;
2179
2180         ut_params->ipsec_xform.spi = INBOUND_SPI;
2181         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2182         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2183         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2184         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2185
2186         for (i = 0; i < num_cfg && rc == 0; i++) {
2187                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2188                 rc = test_ipsec_replay_inb_repeat_null_null(i);
2189         }
2190
2191         return rc;
2192 }
2193
2194 static int
2195 test_ipsec_replay_inb_inside_burst_null_null(int i)
2196 {
2197         struct ipsec_testsuite_params *ts_params = &testsuite_params;
2198         struct ipsec_unitest_params *ut_params = &unittest_params;
2199         uint16_t num_pkts = test_cfg[i].num_pkts;
2200         int rc;
2201         int j;
2202
2203         /* create rte_ipsec_sa*/
2204         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2205                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2206         if (rc != 0) {
2207                 RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2208                 return rc;
2209         }
2210
2211         /* Generate inbound mbuf data */
2212         ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2213                 null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2214         if (ut_params->ibuf[0] == NULL)
2215                 rc = TEST_FAILED;
2216         else
2217                 rc = test_ipsec_crypto_op_alloc(1);
2218
2219         if (rc == 0) {
2220                 /* call ipsec library api */
2221                 rc = crypto_ipsec(1);
2222                 if (rc == 0)
2223                         rc = replay_inb_null_null_check(ut_params, i, 1);
2224                 else {
2225                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2226                                         i);
2227                         rc = TEST_FAILED;
2228                 }
2229         }
2230
2231         if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2232                 /*
2233                  *  generate packet(s) with seq number(s) inside the
2234                  *  replay window
2235                  */
2236                 if (ut_params->ibuf[0]) {
2237                         rte_pktmbuf_free(ut_params->ibuf[0]);
2238                         ut_params->ibuf[0] = 0;
2239                 }
2240
2241                 for (j = 0; j < num_pkts && rc == 0; j++) {
2242                         /* packet with sequence number 1 already processed */
2243                         ut_params->ibuf[j] = setup_test_string_tunneled(
2244                                 ts_params->mbuf_pool, null_encrypted_data,
2245                                 test_cfg[i].pkt_sz, INBOUND_SPI, j + 2);
2246                         if (ut_params->ibuf[j] == NULL)
2247                                 rc = TEST_FAILED;
2248                 }
2249
2250                 if (rc == 0) {
2251                         if (test_cfg[i].reorder_pkts)
2252                                 test_ipsec_reorder_inb_pkt_burst(num_pkts);
2253                         rc = test_ipsec_crypto_op_alloc(num_pkts);
2254                 }
2255
2256                 if (rc == 0) {
2257                         /* call ipsec library api */
2258                         rc = crypto_ipsec(num_pkts);
2259                         if (rc == 0)
2260                                 rc = replay_inb_null_null_check(
2261                                                 ut_params, i, num_pkts);
2262                         else {
2263                                 RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
2264                                 rc = TEST_FAILED;
2265                         }
2266                 }
2267         }
2268
2269         if (rc == TEST_FAILED)
2270                 test_ipsec_dump_buffers(ut_params, i);
2271
2272         destroy_sa(0);
2273
2274         return rc;
2275 }
2276
2277 static int
2278 test_ipsec_replay_inb_inside_burst_null_null_wrapper(void)
2279 {
2280         int i;
2281         int rc = 0;
2282         struct ipsec_unitest_params *ut_params = &unittest_params;
2283
2284         ut_params->ipsec_xform.spi = INBOUND_SPI;
2285         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2286         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2287         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2288         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2289
2290         for (i = 0; i < num_cfg && rc == 0; i++) {
2291                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2292                 rc = test_ipsec_replay_inb_inside_burst_null_null(i);
2293         }
2294
2295         return rc;
2296 }
2297
2298
2299 static int
2300 crypto_inb_burst_2sa_null_null_check(struct ipsec_unitest_params *ut_params,
2301                 int i)
2302 {
2303         uint16_t j;
2304
2305         for (j = 0; j < BURST_SIZE; j++) {
2306                 ut_params->pkt_index = j;
2307
2308                 /* compare the data buffers */
2309                 TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
2310                         rte_pktmbuf_mtod(ut_params->obuf[j], void *),
2311                         test_cfg[i].pkt_sz,
2312                         "input and output data does not match\n");
2313                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
2314                         ut_params->obuf[j]->pkt_len,
2315                         "data_len is not equal to pkt_len");
2316                 TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
2317                         test_cfg[i].pkt_sz,
2318                         "data_len is not equal to input data");
2319         }
2320
2321         return 0;
2322 }
2323
2324 static int
2325 test_ipsec_crypto_inb_burst_2sa_null_null(int i)
2326 {
2327         struct ipsec_testsuite_params *ts_params = &testsuite_params;
2328         struct ipsec_unitest_params *ut_params = &unittest_params;
2329         uint16_t num_pkts = test_cfg[i].num_pkts;
2330         uint16_t j, r;
2331         int rc = 0;
2332
2333         if (num_pkts != BURST_SIZE)
2334                 return rc;
2335
2336         /* create rte_ipsec_sa */
2337         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2338                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2339         if (rc != 0) {
2340                 RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i);
2341                 return rc;
2342         }
2343
2344         /* create second rte_ipsec_sa */
2345         ut_params->ipsec_xform.spi = INBOUND_SPI + 1;
2346         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2347                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 1);
2348         if (rc != 0) {
2349                 RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i);
2350                 destroy_sa(0);
2351                 return rc;
2352         }
2353
2354         /* Generate test mbuf data */
2355         for (j = 0; j < num_pkts && rc == 0; j++) {
2356                 r = j % 2;
2357                 /* packet with sequence number 0 is invalid */
2358                 ut_params->ibuf[j] = setup_test_string_tunneled(
2359                         ts_params->mbuf_pool, null_encrypted_data,
2360                         test_cfg[i].pkt_sz, INBOUND_SPI + r, j + 1);
2361                 if (ut_params->ibuf[j] == NULL)
2362                         rc = TEST_FAILED;
2363         }
2364
2365         if (rc == 0)
2366                 rc = test_ipsec_crypto_op_alloc(num_pkts);
2367
2368         if (rc == 0) {
2369                 /* call ipsec library api */
2370                 rc = crypto_ipsec_2sa();
2371                 if (rc == 0)
2372                         rc = crypto_inb_burst_2sa_null_null_check(
2373                                         ut_params, i);
2374                 else {
2375                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2376                                 i);
2377                         rc = TEST_FAILED;
2378                 }
2379         }
2380
2381         if (rc == TEST_FAILED)
2382                 test_ipsec_dump_buffers(ut_params, i);
2383
2384         destroy_sa(0);
2385         destroy_sa(1);
2386         return rc;
2387 }
2388
2389 static int
2390 test_ipsec_crypto_inb_burst_2sa_null_null_wrapper(void)
2391 {
2392         int i;
2393         int rc = 0;
2394         struct ipsec_unitest_params *ut_params = &unittest_params;
2395
2396         ut_params->ipsec_xform.spi = INBOUND_SPI;
2397         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2398         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2399         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2400         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2401
2402         for (i = 0; i < num_cfg && rc == 0; i++) {
2403                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2404                 rc = test_ipsec_crypto_inb_burst_2sa_null_null(i);
2405         }
2406
2407         return rc;
2408 }
2409
2410 static int
2411 test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i)
2412 {
2413         struct ipsec_testsuite_params *ts_params = &testsuite_params;
2414         struct ipsec_unitest_params *ut_params = &unittest_params;
2415         uint16_t num_pkts = test_cfg[i].num_pkts;
2416         uint16_t j, k;
2417         int rc = 0;
2418
2419         if (num_pkts != BURST_SIZE)
2420                 return rc;
2421
2422         /* create rte_ipsec_sa */
2423         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2424                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2425         if (rc != 0) {
2426                 RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i);
2427                 return rc;
2428         }
2429
2430         /* create second rte_ipsec_sa */
2431         ut_params->ipsec_xform.spi = INBOUND_SPI + 1;
2432         rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2433                         test_cfg[i].replay_win_sz, test_cfg[i].flags, 1);
2434         if (rc != 0) {
2435                 RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i);
2436                 destroy_sa(0);
2437                 return rc;
2438         }
2439
2440         /* Generate test mbuf data */
2441         for (j = 0; j < num_pkts && rc == 0; j++) {
2442                 k = crypto_ipsec_4grp(j);
2443
2444                 /* packet with sequence number 0 is invalid */
2445                 ut_params->ibuf[j] = setup_test_string_tunneled(
2446                         ts_params->mbuf_pool, null_encrypted_data,
2447                         test_cfg[i].pkt_sz, INBOUND_SPI + k, j + 1);
2448                 if (ut_params->ibuf[j] == NULL)
2449                         rc = TEST_FAILED;
2450         }
2451
2452         if (rc == 0)
2453                 rc = test_ipsec_crypto_op_alloc(num_pkts);
2454
2455         if (rc == 0) {
2456                 /* call ipsec library api */
2457                 rc = crypto_ipsec_2sa_4grp();
2458                 if (rc == 0)
2459                         rc = crypto_inb_burst_2sa_null_null_check(
2460                                         ut_params, i);
2461                 else {
2462                         RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2463                                 i);
2464                         rc = TEST_FAILED;
2465                 }
2466         }
2467
2468         if (rc == TEST_FAILED)
2469                 test_ipsec_dump_buffers(ut_params, i);
2470
2471         destroy_sa(0);
2472         destroy_sa(1);
2473         return rc;
2474 }
2475
2476 static int
2477 test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper(void)
2478 {
2479         int i;
2480         int rc = 0;
2481         struct ipsec_unitest_params *ut_params = &unittest_params;
2482
2483         ut_params->ipsec_xform.spi = INBOUND_SPI;
2484         ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2485         ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2486         ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2487         ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2488
2489         for (i = 0; i < num_cfg && rc == 0; i++) {
2490                 ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2491                 rc = test_ipsec_crypto_inb_burst_2sa_4grp_null_null(i);
2492         }
2493
2494         return rc;
2495 }
2496
2497 static struct unit_test_suite ipsec_testsuite  = {
2498         .suite_name = "IPsec NULL Unit Test Suite",
2499         .setup = testsuite_setup,
2500         .teardown = testsuite_teardown,
2501         .unit_test_cases = {
2502                 TEST_CASE_ST(ut_setup, ut_teardown,
2503                         test_ipsec_crypto_inb_burst_null_null_wrapper),
2504                 TEST_CASE_ST(ut_setup, ut_teardown,
2505                         test_ipsec_crypto_outb_burst_null_null_wrapper),
2506                 TEST_CASE_ST(ut_setup, ut_teardown,
2507                         test_ipsec_inline_crypto_inb_burst_null_null_wrapper),
2508                 TEST_CASE_ST(ut_setup, ut_teardown,
2509                         test_ipsec_inline_crypto_outb_burst_null_null_wrapper),
2510                 TEST_CASE_ST(ut_setup, ut_teardown,
2511                         test_ipsec_inline_proto_inb_burst_null_null_wrapper),
2512                 TEST_CASE_ST(ut_setup, ut_teardown,
2513                         test_ipsec_inline_proto_outb_burst_null_null_wrapper),
2514                 TEST_CASE_ST(ut_setup, ut_teardown,
2515                         test_ipsec_lksd_proto_inb_burst_null_null_wrapper),
2516                 TEST_CASE_ST(ut_setup, ut_teardown,
2517                         test_ipsec_lksd_proto_outb_burst_null_null_wrapper),
2518                 TEST_CASE_ST(ut_setup, ut_teardown,
2519                         test_ipsec_replay_inb_inside_null_null_wrapper),
2520                 TEST_CASE_ST(ut_setup, ut_teardown,
2521                         test_ipsec_replay_inb_outside_null_null_wrapper),
2522                 TEST_CASE_ST(ut_setup, ut_teardown,
2523                         test_ipsec_replay_inb_repeat_null_null_wrapper),
2524                 TEST_CASE_ST(ut_setup, ut_teardown,
2525                         test_ipsec_replay_inb_inside_burst_null_null_wrapper),
2526                 TEST_CASE_ST(ut_setup, ut_teardown,
2527                         test_ipsec_crypto_inb_burst_2sa_null_null_wrapper),
2528                 TEST_CASE_ST(ut_setup, ut_teardown,
2529                         test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper),
2530                 TEST_CASES_END() /**< NULL terminate unit test array */
2531         }
2532 };
2533
2534 static int
2535 test_ipsec(void)
2536 {
2537         return unit_test_suite_runner(&ipsec_testsuite);
2538 }
2539
2540 REGISTER_TEST_COMMAND(ipsec_autotest, test_ipsec);