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