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