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