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