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