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