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