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