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