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