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