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