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