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