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