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