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