xref: /dpdk/app/test-crypto-perf/cperf_options_parsing.c (revision 981a1ed32a7920bf0f5e2864ab1f78c296bdfaec)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2017 Intel Corporation
3  */
4 
5 #include <getopt.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 
9 #include <rte_cryptodev.h>
10 #include <rte_malloc.h>
11 #include <rte_ether.h>
12 
13 #include "cperf_options.h"
14 #include "cperf_test_common.h"
15 #include "cperf_test_vectors.h"
16 
17 #define AES_BLOCK_SIZE 16
18 #define DES_BLOCK_SIZE 8
19 
20 struct name_id_map {
21 	const char *name;
22 	uint32_t id;
23 };
24 
25 static void
26 usage(char *progname)
27 {
28 	printf("%s [EAL options] --\n"
29 		" --silent: disable options dump\n"
30 		" --ptest throughput / latency / verify / pmd-cyclecount :"
31 		" set test type\n"
32 		" --pool_sz N: set the number of crypto ops/mbufs allocated\n"
33 		" --total-ops N: set the number of total operations performed\n"
34 		" --burst-sz N: set the number of packets per burst\n"
35 		" --buffer-sz N: set the size of a single packet\n"
36 		" --imix N: set the distribution of packet sizes\n"
37 		" --segment-sz N: set the size of the segment to use\n"
38 		" --desc-nb N: set number of descriptors for each crypto device\n"
39 		" --devtype TYPE: set crypto device type to use\n"
40 		" --low-prio-qp-mask mask: set low priority for queues set in mask(hex)\n"
41 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
42 		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
43 		" --sessionless: enable session-less crypto operations\n"
44 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
45 		" --out-of-place: enable out-of-place crypto operations\n"
46 		" --test-file NAME: set the test vector file path\n"
47 		" --test-name NAME: set specific test name section in test file\n"
48 		" --cipher-algo ALGO: set cipher algorithm\n"
49 		" --cipher-op encrypt / decrypt: set the cipher operation\n"
50 		" --cipher-key-sz N: set the cipher key size\n"
51 		" --cipher-iv-sz N: set the cipher IV size\n"
52 		" --auth-algo ALGO: set auth algorithm\n"
53 		" --auth-op generate / verify: set the auth operation\n"
54 		" --auth-key-sz N: set the auth key size\n"
55 		" --auth-iv-sz N: set the auth IV size\n"
56 		" --aead-algo ALGO: set AEAD algorithm\n"
57 		" --aead-op encrypt / decrypt: set the AEAD operation\n"
58 		" --aead-key-sz N: set the AEAD key size\n"
59 		" --aead-iv-sz N: set the AEAD IV size\n"
60 		" --aead-aad-sz N: set the AEAD AAD size\n"
61 		" --digest-sz N: set the digest size\n"
62 		" --pmd-cyclecount-delay-ms N: set delay between enqueue\n"
63 		"           and dequeue in pmd-cyclecount benchmarking mode\n"
64 		" --csv-friendly: enable test result output CSV friendly\n"
65 		" --modex-len N: modex length, supported lengths are "
66 		"60, 128, 255, 448. Default: 128\n"
67 		" --asym-op encrypt / decrypt / sign / verify : set asym operation type\n"
68 #ifdef RTE_LIB_SECURITY
69 		" --pdcp-sn-sz N: set PDCP SN size N <5/7/12/15/18>\n"
70 		" --pdcp-domain DOMAIN: set PDCP domain <control/user>\n"
71 		" --pdcp-ses-hfn-en: enable session based fixed HFN\n"
72 		" --enable-sdap: enable sdap\n"
73 		" --docsis-hdr-sz: set DOCSIS header size\n"
74 		" --tls-version VER: set TLS VERSION <TLS1.2/TLS1.3/DTLS1.2>\n"
75 #endif
76 		" -h: prints this help\n",
77 		progname);
78 }
79 
80 static int
81 get_str_key_id_mapping(struct name_id_map *map, unsigned int map_len,
82 		const char *str_key)
83 {
84 	unsigned int i;
85 
86 	for (i = 0; i < map_len; i++) {
87 
88 		if (strcmp(str_key, map[i].name) == 0)
89 			return map[i].id;
90 	}
91 
92 	return -1;
93 }
94 
95 static int
96 parse_cperf_test_type(struct cperf_options *opts, const char *arg)
97 {
98 	struct name_id_map cperftest_namemap[] = {
99 		{
100 			cperf_test_type_strs[CPERF_TEST_TYPE_THROUGHPUT],
101 			CPERF_TEST_TYPE_THROUGHPUT
102 		},
103 		{
104 			cperf_test_type_strs[CPERF_TEST_TYPE_VERIFY],
105 			CPERF_TEST_TYPE_VERIFY
106 		},
107 		{
108 			cperf_test_type_strs[CPERF_TEST_TYPE_LATENCY],
109 			CPERF_TEST_TYPE_LATENCY
110 		},
111 		{
112 			cperf_test_type_strs[CPERF_TEST_TYPE_PMDCC],
113 			CPERF_TEST_TYPE_PMDCC
114 		}
115 	};
116 
117 	int id = get_str_key_id_mapping(
118 			(struct name_id_map *)cperftest_namemap,
119 			RTE_DIM(cperftest_namemap), arg);
120 	if (id < 0) {
121 		RTE_LOG(ERR, USER1, "failed to parse test type");
122 		return -1;
123 	}
124 
125 	opts->test = (enum cperf_perf_test_type)id;
126 
127 	return 0;
128 }
129 
130 static int
131 parse_uint32_t(uint32_t *value, const char *arg)
132 {
133 	char *end = NULL;
134 	unsigned long n = strtoul(arg, &end, 10);
135 
136 	if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
137 		return -1;
138 
139 	if (n > UINT32_MAX)
140 		return -ERANGE;
141 
142 	*value = (uint32_t) n;
143 
144 	return 0;
145 }
146 
147 static int
148 parse_uint16_t(uint16_t *value, const char *arg)
149 {
150 	uint32_t val = 0;
151 	int ret = parse_uint32_t(&val, arg);
152 
153 	if (ret < 0)
154 		return ret;
155 
156 	if (val > UINT16_MAX)
157 		return -ERANGE;
158 
159 	*value = (uint16_t) val;
160 
161 	return 0;
162 }
163 
164 static int
165 parse_range(const char *arg, uint32_t *min, uint32_t *max, uint32_t *inc)
166 {
167 	char *token;
168 	uint32_t number;
169 
170 	char *copy_arg = strdup(arg);
171 
172 	if (copy_arg == NULL)
173 		return -1;
174 
175 	errno = 0;
176 	token = strtok(copy_arg, ":");
177 
178 	/* Parse minimum value */
179 	if (token != NULL) {
180 		number = strtoul(token, NULL, 10);
181 
182 		if (errno == EINVAL || errno == ERANGE ||
183 				number == 0)
184 			goto err_range;
185 
186 		*min = number;
187 	} else
188 		goto err_range;
189 
190 	token = strtok(NULL, ":");
191 
192 	/* Parse increment value */
193 	if (token != NULL) {
194 		number = strtoul(token, NULL, 10);
195 
196 		if (errno == EINVAL || errno == ERANGE ||
197 				number == 0)
198 			goto err_range;
199 
200 		*inc = number;
201 	} else
202 		goto err_range;
203 
204 	token = strtok(NULL, ":");
205 
206 	/* Parse maximum value */
207 	if (token != NULL) {
208 		number = strtoul(token, NULL, 10);
209 
210 		if (errno == EINVAL || errno == ERANGE ||
211 				number == 0 ||
212 				number < *min)
213 			goto err_range;
214 
215 		*max = number;
216 	} else
217 		goto err_range;
218 
219 	if (strtok(NULL, ":") != NULL)
220 		goto err_range;
221 
222 	free(copy_arg);
223 	return 0;
224 
225 err_range:
226 	free(copy_arg);
227 	return -1;
228 }
229 
230 static int
231 parse_list(const char *arg, uint32_t *list, uint32_t *min, uint32_t *max)
232 {
233 	char *token;
234 	uint32_t number;
235 	uint8_t count = 0;
236 	uint32_t temp_min;
237 	uint32_t temp_max;
238 
239 	char *copy_arg = strdup(arg);
240 
241 	if (copy_arg == NULL)
242 		return -1;
243 
244 	errno = 0;
245 	token = strtok(copy_arg, ",");
246 
247 	/* Parse first value */
248 	if (token != NULL) {
249 		number = strtoul(token, NULL, 10);
250 
251 		if (errno == EINVAL || errno == ERANGE ||
252 				number == 0)
253 			goto err_list;
254 
255 		list[count++] = number;
256 		temp_min = number;
257 		temp_max = number;
258 	} else
259 		goto err_list;
260 
261 	token = strtok(NULL, ",");
262 
263 	while (token != NULL) {
264 		if (count == MAX_LIST) {
265 			RTE_LOG(WARNING, USER1, "Using only the first %u sizes\n",
266 					MAX_LIST);
267 			break;
268 		}
269 
270 		number = strtoul(token, NULL, 10);
271 
272 		if (errno == EINVAL || errno == ERANGE ||
273 				number == 0)
274 			goto err_list;
275 
276 		list[count++] = number;
277 
278 		if (number < temp_min)
279 			temp_min = number;
280 		if (number > temp_max)
281 			temp_max = number;
282 
283 		token = strtok(NULL, ",");
284 	}
285 
286 	if (min)
287 		*min = temp_min;
288 	if (max)
289 		*max = temp_max;
290 
291 	free(copy_arg);
292 	return count;
293 
294 err_list:
295 	free(copy_arg);
296 	return -1;
297 }
298 
299 static int
300 parse_total_ops(struct cperf_options *opts, const char *arg)
301 {
302 	int ret = parse_uint32_t(&opts->total_ops, arg);
303 
304 	if (ret)
305 		RTE_LOG(ERR, USER1, "failed to parse total operations count\n");
306 
307 	if (opts->total_ops == 0) {
308 		RTE_LOG(ERR, USER1,
309 				"invalid total operations count number specified\n");
310 		return -1;
311 	}
312 
313 	return ret;
314 }
315 
316 static int
317 parse_pool_sz(struct cperf_options *opts, const char *arg)
318 {
319 	int ret =  parse_uint32_t(&opts->pool_sz, arg);
320 
321 	if (ret)
322 		RTE_LOG(ERR, USER1, "failed to parse pool size");
323 	return ret;
324 }
325 
326 static int
327 parse_modex_len(struct cperf_options *opts, const char *arg)
328 {
329 	int ret =  parse_uint16_t(&opts->modex_len, arg);
330 
331 	if (ret)
332 		RTE_LOG(ERR, USER1, "failed to parse modex len");
333 	return ret;
334 }
335 
336 static int
337 parse_burst_sz(struct cperf_options *opts, const char *arg)
338 {
339 	int ret;
340 
341 	/* Try parsing the argument as a range, if it fails, parse it as a list */
342 	if (parse_range(arg, &opts->min_burst_size, &opts->max_burst_size,
343 			&opts->inc_burst_size) < 0) {
344 		ret = parse_list(arg, opts->burst_size_list,
345 					&opts->min_burst_size,
346 					&opts->max_burst_size);
347 		if (ret < 0) {
348 			RTE_LOG(ERR, USER1, "failed to parse burst size/s\n");
349 			return -1;
350 		}
351 		opts->burst_size_count = ret;
352 	}
353 
354 	return 0;
355 }
356 
357 static int
358 parse_buffer_sz(struct cperf_options *opts, const char *arg)
359 {
360 	int ret;
361 
362 	/* Try parsing the argument as a range, if it fails, parse it as a list */
363 	if (parse_range(arg, &opts->min_buffer_size, &opts->max_buffer_size,
364 			&opts->inc_buffer_size) < 0) {
365 		ret = parse_list(arg, opts->buffer_size_list,
366 					&opts->min_buffer_size,
367 					&opts->max_buffer_size);
368 		if (ret < 0) {
369 			RTE_LOG(ERR, USER1, "failed to parse buffer size/s\n");
370 			return -1;
371 		}
372 		opts->buffer_size_count = ret;
373 	}
374 
375 	return 0;
376 }
377 
378 static int
379 parse_segment_sz(struct cperf_options *opts, const char *arg)
380 {
381 	int ret = parse_uint32_t(&opts->segment_sz, arg);
382 
383 	if (ret) {
384 		RTE_LOG(ERR, USER1, "failed to parse segment size\n");
385 		return -1;
386 	}
387 
388 	if (opts->segment_sz == 0) {
389 		RTE_LOG(ERR, USER1, "Segment size has to be bigger than 0\n");
390 		return -1;
391 	}
392 
393 	return 0;
394 }
395 
396 static int
397 parse_imix(struct cperf_options *opts, const char *arg)
398 {
399 	int ret;
400 
401 	ret = parse_list(arg, opts->imix_distribution_list,
402 				NULL, NULL);
403 	if (ret < 0) {
404 		RTE_LOG(ERR, USER1, "failed to parse imix distribution\n");
405 		return -1;
406 	}
407 
408 	opts->imix_distribution_count = ret;
409 
410 	if (opts->imix_distribution_count <= 1) {
411 		RTE_LOG(ERR, USER1, "imix distribution should have "
412 				"at least two entries\n");
413 		return -1;
414 	}
415 
416 	return 0;
417 }
418 
419 static int
420 parse_desc_nb(struct cperf_options *opts, const char *arg)
421 {
422 	int ret = parse_uint32_t(&opts->nb_descriptors, arg);
423 
424 	if (ret) {
425 		RTE_LOG(ERR, USER1, "failed to parse descriptors number\n");
426 		return -1;
427 	}
428 
429 	if (opts->nb_descriptors == 0) {
430 		RTE_LOG(ERR, USER1, "invalid descriptors number specified\n");
431 		return -1;
432 	}
433 
434 	return 0;
435 }
436 
437 static int
438 parse_device_type(struct cperf_options *opts, const char *arg)
439 {
440 	if (strlen(arg) > (sizeof(opts->device_type) - 1))
441 		return -1;
442 
443 	strncpy(opts->device_type, arg, sizeof(opts->device_type) - 1);
444 	*(opts->device_type + sizeof(opts->device_type) - 1) = '\0';
445 
446 	return 0;
447 }
448 
449 static int
450 parse_op_type(struct cperf_options *opts, const char *arg)
451 {
452 	struct name_id_map optype_namemap[] = {
453 		{
454 			cperf_op_type_strs[CPERF_CIPHER_ONLY],
455 			CPERF_CIPHER_ONLY
456 		},
457 		{
458 			cperf_op_type_strs[CPERF_AUTH_ONLY],
459 			CPERF_AUTH_ONLY
460 		},
461 		{
462 			cperf_op_type_strs[CPERF_CIPHER_THEN_AUTH],
463 			CPERF_CIPHER_THEN_AUTH
464 		},
465 		{
466 			cperf_op_type_strs[CPERF_AUTH_THEN_CIPHER],
467 			CPERF_AUTH_THEN_CIPHER
468 		},
469 		{
470 			cperf_op_type_strs[CPERF_AEAD],
471 			CPERF_AEAD
472 		},
473 		{
474 			cperf_op_type_strs[CPERF_PDCP],
475 			CPERF_PDCP
476 		},
477 		{
478 			cperf_op_type_strs[CPERF_DOCSIS],
479 			CPERF_DOCSIS
480 		},
481 		{
482 			cperf_op_type_strs[CPERF_IPSEC],
483 			CPERF_IPSEC
484 		},
485 		{
486 			cperf_op_type_strs[CPERF_ASYM_MODEX],
487 			CPERF_ASYM_MODEX
488 		},
489 		{
490 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
491 			CPERF_ASYM_SECP256R1
492 		},
493 		{
494 			cperf_op_type_strs[CPERF_ASYM_ED25519],
495 			CPERF_ASYM_ED25519
496 		},
497 		{
498 			cperf_op_type_strs[CPERF_ASYM_SM2],
499 			CPERF_ASYM_SM2
500 		},
501 		{
502 			cperf_op_type_strs[CPERF_TLS],
503 			CPERF_TLS
504 		},
505 	};
506 
507 	int id = get_str_key_id_mapping(optype_namemap,
508 			RTE_DIM(optype_namemap), arg);
509 	if (id < 0) {
510 		RTE_LOG(ERR, USER1, "invalid opt type specified\n");
511 		return -1;
512 	}
513 
514 	opts->op_type = (enum cperf_op_type)id;
515 
516 	return 0;
517 }
518 
519 static int
520 parse_sessionless(struct cperf_options *opts,
521 		const char *arg __rte_unused)
522 {
523 	opts->sessionless = 1;
524 	return 0;
525 }
526 
527 static int
528 parse_shared_session(struct cperf_options *opts,
529 		const char *arg __rte_unused)
530 {
531 	opts->shared_session = 1;
532 	return 0;
533 }
534 
535 static int
536 parse_out_of_place(struct cperf_options *opts,
537 		const char *arg __rte_unused)
538 {
539 	opts->out_of_place = 1;
540 	return 0;
541 }
542 
543 static int
544 parse_test_file(struct cperf_options *opts,
545 		const char *arg)
546 {
547 	opts->test_file = strdup(arg);
548 	if (opts->test_file == NULL) {
549 		RTE_LOG(ERR, USER1, "Dup vector file failed!\n");
550 		return -1;
551 	}
552 	if (access(opts->test_file, F_OK) != -1)
553 		return 0;
554 	RTE_LOG(ERR, USER1, "Test vector file doesn't exist\n");
555 	free(opts->test_file);
556 
557 	return -1;
558 }
559 
560 static int
561 parse_test_name(struct cperf_options *opts,
562 		const char *arg)
563 {
564 	char *test_name = (char *) rte_zmalloc(NULL,
565 		sizeof(char) * (strlen(arg) + 3), 0);
566 	if (test_name == NULL) {
567 		RTE_LOG(ERR, USER1, "Failed to rte zmalloc with size: %zu\n",
568 			strlen(arg) + 3);
569 		return -1;
570 	}
571 
572 	snprintf(test_name, strlen(arg) + 3, "[%s]", arg);
573 	opts->test_name = test_name;
574 
575 	return 0;
576 }
577 
578 static int
579 parse_silent(struct cperf_options *opts,
580 		const char *arg __rte_unused)
581 {
582 	opts->silent = 1;
583 
584 	return 0;
585 }
586 
587 static int
588 parse_enable_sdap(struct cperf_options *opts,
589 		const char *arg __rte_unused)
590 {
591 	opts->pdcp_sdap = 1;
592 
593 	return 0;
594 }
595 
596 static int
597 parse_cipher_algo(struct cperf_options *opts, const char *arg)
598 {
599 
600 	enum rte_crypto_cipher_algorithm cipher_algo;
601 
602 	if (rte_cryptodev_get_cipher_algo_enum(&cipher_algo, arg) < 0) {
603 		RTE_LOG(ERR, USER1, "Invalid cipher algorithm specified\n");
604 		return -1;
605 	}
606 
607 	opts->cipher_algo = cipher_algo;
608 
609 	return 0;
610 }
611 
612 static int
613 parse_cipher_op(struct cperf_options *opts, const char *arg)
614 {
615 	struct name_id_map cipher_op_namemap[] = {
616 		{
617 			rte_crypto_cipher_operation_strings
618 			[RTE_CRYPTO_CIPHER_OP_ENCRYPT],
619 			RTE_CRYPTO_CIPHER_OP_ENCRYPT },
620 		{
621 			rte_crypto_cipher_operation_strings
622 			[RTE_CRYPTO_CIPHER_OP_DECRYPT],
623 			RTE_CRYPTO_CIPHER_OP_DECRYPT
624 		}
625 	};
626 
627 	int id = get_str_key_id_mapping(cipher_op_namemap,
628 			RTE_DIM(cipher_op_namemap), arg);
629 	if (id < 0) {
630 		RTE_LOG(ERR, USER1, "Invalid cipher operation specified\n");
631 		return -1;
632 	}
633 
634 	opts->cipher_op = (enum rte_crypto_cipher_operation)id;
635 
636 	return 0;
637 }
638 
639 static int
640 parse_cipher_key_sz(struct cperf_options *opts, const char *arg)
641 {
642 	return parse_uint16_t(&opts->cipher_key_sz, arg);
643 }
644 
645 static int
646 parse_cipher_iv_sz(struct cperf_options *opts, const char *arg)
647 {
648 	return parse_uint16_t(&opts->cipher_iv_sz, arg);
649 }
650 
651 static int
652 parse_auth_algo(struct cperf_options *opts, const char *arg)
653 {
654 	enum rte_crypto_auth_algorithm auth_algo;
655 
656 	if (rte_cryptodev_get_auth_algo_enum(&auth_algo, arg) < 0) {
657 		RTE_LOG(ERR, USER1, "Invalid authentication algorithm specified\n");
658 		return -1;
659 	}
660 
661 	opts->auth_algo = auth_algo;
662 
663 	return 0;
664 }
665 
666 static int
667 parse_auth_op(struct cperf_options *opts, const char *arg)
668 {
669 	struct name_id_map auth_op_namemap[] = {
670 		{
671 			rte_crypto_auth_operation_strings
672 			[RTE_CRYPTO_AUTH_OP_GENERATE],
673 			RTE_CRYPTO_AUTH_OP_GENERATE },
674 		{
675 			rte_crypto_auth_operation_strings
676 			[RTE_CRYPTO_AUTH_OP_VERIFY],
677 			RTE_CRYPTO_AUTH_OP_VERIFY
678 		}
679 	};
680 
681 	int id = get_str_key_id_mapping(auth_op_namemap,
682 			RTE_DIM(auth_op_namemap), arg);
683 	if (id < 0) {
684 		RTE_LOG(ERR, USER1, "invalid authentication operation specified"
685 				"\n");
686 		return -1;
687 	}
688 
689 	opts->auth_op = (enum rte_crypto_auth_operation)id;
690 
691 	return 0;
692 }
693 
694 static int
695 parse_auth_key_sz(struct cperf_options *opts, const char *arg)
696 {
697 	return parse_uint16_t(&opts->auth_key_sz, arg);
698 }
699 
700 static int
701 parse_digest_sz(struct cperf_options *opts, const char *arg)
702 {
703 	return parse_uint16_t(&opts->digest_sz, arg);
704 }
705 
706 #ifdef RTE_LIB_SECURITY
707 static int
708 parse_pdcp_sn_sz(struct cperf_options *opts, const char *arg)
709 {
710 	uint32_t val = 0;
711 	int ret = parse_uint32_t(&val, arg);
712 
713 	if (ret < 0)
714 		return ret;
715 
716 	if (val != RTE_SECURITY_PDCP_SN_SIZE_5 &&
717 			val != RTE_SECURITY_PDCP_SN_SIZE_7 &&
718 			val != RTE_SECURITY_PDCP_SN_SIZE_12 &&
719 			val != RTE_SECURITY_PDCP_SN_SIZE_15 &&
720 			val != RTE_SECURITY_PDCP_SN_SIZE_18) {
721 		printf("\nInvalid pdcp SN size: %u\n", val);
722 		return -ERANGE;
723 	}
724 	opts->pdcp_sn_sz = val;
725 
726 	return 0;
727 }
728 
729 const char *cperf_pdcp_domain_strs[] = {
730 	[RTE_SECURITY_PDCP_MODE_CONTROL] = "control",
731 	[RTE_SECURITY_PDCP_MODE_DATA] = "data",
732 	[RTE_SECURITY_PDCP_MODE_SHORT_MAC] = "short_mac"
733 };
734 
735 static int
736 parse_pdcp_domain(struct cperf_options *opts, const char *arg)
737 {
738 	struct name_id_map pdcp_domain_namemap[] = {
739 		{
740 			cperf_pdcp_domain_strs
741 			[RTE_SECURITY_PDCP_MODE_CONTROL],
742 			RTE_SECURITY_PDCP_MODE_CONTROL },
743 		{
744 			cperf_pdcp_domain_strs
745 			[RTE_SECURITY_PDCP_MODE_DATA],
746 			RTE_SECURITY_PDCP_MODE_DATA
747 		},
748 		{
749 			cperf_pdcp_domain_strs
750 			[RTE_SECURITY_PDCP_MODE_SHORT_MAC],
751 			RTE_SECURITY_PDCP_MODE_SHORT_MAC
752 		}
753 	};
754 
755 	int id = get_str_key_id_mapping(pdcp_domain_namemap,
756 			RTE_DIM(pdcp_domain_namemap), arg);
757 	if (id < 0) {
758 		RTE_LOG(ERR, USER1, "invalid pdcp domain specified"
759 				"\n");
760 		return -1;
761 	}
762 
763 	opts->pdcp_domain = (enum rte_security_pdcp_domain)id;
764 
765 	return 0;
766 }
767 
768 const char *cperf_tls_version_strs[] = {
769 	[RTE_SECURITY_VERSION_TLS_1_2] = "TLS1.2",
770 	[RTE_SECURITY_VERSION_TLS_1_3] = "TLS1.3",
771 	[RTE_SECURITY_VERSION_DTLS_1_2] = "DTLS1.2"
772 };
773 
774 static int
775 parse_tls_version(struct cperf_options *opts, const char *arg)
776 {
777 	struct name_id_map tls_version_namemap[] = {
778 		{
779 			cperf_tls_version_strs
780 			[RTE_SECURITY_VERSION_TLS_1_2],
781 			RTE_SECURITY_VERSION_TLS_1_2
782 		},
783 		{
784 			cperf_tls_version_strs
785 			[RTE_SECURITY_VERSION_TLS_1_3],
786 			RTE_SECURITY_VERSION_TLS_1_3
787 		},
788 		{
789 			cperf_tls_version_strs
790 			[RTE_SECURITY_VERSION_DTLS_1_2],
791 			RTE_SECURITY_VERSION_DTLS_1_2
792 		},
793 	};
794 
795 	int id = get_str_key_id_mapping(tls_version_namemap,
796 			RTE_DIM(tls_version_namemap), arg);
797 	if (id < 0) {
798 		RTE_LOG(ERR, USER1, "invalid TLS version specified\n");
799 		return -1;
800 	}
801 
802 	opts->tls_version = (enum rte_security_tls_version)id;
803 
804 	return 0;
805 }
806 
807 static int
808 parse_pdcp_ses_hfn_en(struct cperf_options *opts, const char *arg __rte_unused)
809 {
810 	opts->pdcp_ses_hfn_en = 1;
811 	return 0;
812 }
813 
814 static int
815 parse_docsis_hdr_sz(struct cperf_options *opts, const char *arg)
816 {
817 	return parse_uint16_t(&opts->docsis_hdr_sz, arg);
818 }
819 #endif
820 
821 static int
822 parse_auth_iv_sz(struct cperf_options *opts, const char *arg)
823 {
824 	return parse_uint16_t(&opts->auth_iv_sz, arg);
825 }
826 
827 static int
828 parse_aead_algo(struct cperf_options *opts, const char *arg)
829 {
830 	enum rte_crypto_aead_algorithm aead_algo;
831 
832 	if (rte_cryptodev_get_aead_algo_enum(&aead_algo, arg) < 0) {
833 		RTE_LOG(ERR, USER1, "Invalid AEAD algorithm specified\n");
834 		return -1;
835 	}
836 
837 	opts->aead_algo = aead_algo;
838 
839 	return 0;
840 }
841 
842 static int
843 parse_aead_op(struct cperf_options *opts, const char *arg)
844 {
845 	struct name_id_map aead_op_namemap[] = {
846 		{
847 			rte_crypto_aead_operation_strings
848 			[RTE_CRYPTO_AEAD_OP_ENCRYPT],
849 			RTE_CRYPTO_AEAD_OP_ENCRYPT },
850 		{
851 			rte_crypto_aead_operation_strings
852 			[RTE_CRYPTO_AEAD_OP_DECRYPT],
853 			RTE_CRYPTO_AEAD_OP_DECRYPT
854 		}
855 	};
856 
857 	int id = get_str_key_id_mapping(aead_op_namemap,
858 			RTE_DIM(aead_op_namemap), arg);
859 	if (id < 0) {
860 		RTE_LOG(ERR, USER1, "invalid AEAD operation specified"
861 				"\n");
862 		return -1;
863 	}
864 
865 	opts->aead_op = (enum rte_crypto_aead_operation)id;
866 
867 	return 0;
868 }
869 
870 static int
871 parse_aead_key_sz(struct cperf_options *opts, const char *arg)
872 {
873 	return parse_uint16_t(&opts->aead_key_sz, arg);
874 }
875 
876 static int
877 parse_aead_iv_sz(struct cperf_options *opts, const char *arg)
878 {
879 	return parse_uint16_t(&opts->aead_iv_sz, arg);
880 }
881 
882 static int
883 parse_aead_aad_sz(struct cperf_options *opts, const char *arg)
884 {
885 	return parse_uint16_t(&opts->aead_aad_sz, arg);
886 }
887 
888 static int
889 parse_asym_op(struct cperf_options *opts, const char *arg)
890 {
891 	struct name_id_map asym_op_namemap[] = {
892 		{
893 			rte_crypto_asym_op_strings
894 			[RTE_CRYPTO_ASYM_OP_ENCRYPT],
895 			RTE_CRYPTO_ASYM_OP_ENCRYPT
896 		},
897 		{
898 			rte_crypto_asym_op_strings
899 			[RTE_CRYPTO_ASYM_OP_DECRYPT],
900 			RTE_CRYPTO_ASYM_OP_DECRYPT
901 		},
902 		{
903 			rte_crypto_asym_op_strings
904 			[RTE_CRYPTO_ASYM_OP_SIGN],
905 			RTE_CRYPTO_ASYM_OP_SIGN
906 		},
907 		{
908 			rte_crypto_asym_op_strings
909 			[RTE_CRYPTO_ASYM_OP_VERIFY],
910 			RTE_CRYPTO_ASYM_OP_VERIFY
911 		}
912 	};
913 
914 	int id = get_str_key_id_mapping(asym_op_namemap,
915 			RTE_DIM(asym_op_namemap), arg);
916 	if (id < 0) {
917 		RTE_LOG(ERR, USER1, "invalid ASYM operation specified\n");
918 		return -1;
919 	}
920 
921 	opts->asym_op_type = (enum rte_crypto_asym_op_type)id;
922 
923 	return 0;
924 }
925 
926 
927 static int
928 parse_csv_friendly(struct cperf_options *opts, const char *arg __rte_unused)
929 {
930 	opts->csv = 1;
931 	opts->silent = 1;
932 	return 0;
933 }
934 
935 static int
936 parse_pmd_cyclecount_delay_ms(struct cperf_options *opts,
937 			const char *arg)
938 {
939 	int ret = parse_uint32_t(&opts->pmdcc_delay, arg);
940 
941 	if (ret) {
942 		RTE_LOG(ERR, USER1, "failed to parse pmd-cyclecount delay\n");
943 		return -1;
944 	}
945 
946 	return 0;
947 }
948 
949 static int
950 parse_low_prio_qp_mask(struct cperf_options *opts, const char *arg)
951 {
952 	char *end = NULL;
953 	unsigned long n;
954 
955 	/* parse hexadecimal string */
956 	n = strtoul(arg, &end, 16);
957 	if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
958 		return -1;
959 
960 	opts->low_prio_qp_mask = n;
961 
962 	return 0;
963 }
964 
965 typedef int (*option_parser_t)(struct cperf_options *opts,
966 		const char *arg);
967 
968 struct long_opt_parser {
969 	const char *lgopt_name;
970 	option_parser_t parser_fn;
971 
972 };
973 
974 static struct option lgopts[] = {
975 
976 	{ CPERF_PTEST_TYPE, required_argument, 0, 0 },
977 	{ CPERF_MODEX_LEN, required_argument, 0, 0 },
978 
979 	{ CPERF_POOL_SIZE, required_argument, 0, 0 },
980 	{ CPERF_TOTAL_OPS, required_argument, 0, 0 },
981 	{ CPERF_BURST_SIZE, required_argument, 0, 0 },
982 	{ CPERF_BUFFER_SIZE, required_argument, 0, 0 },
983 	{ CPERF_SEGMENT_SIZE, required_argument, 0, 0 },
984 	{ CPERF_DESC_NB, required_argument, 0, 0 },
985 
986 	{ CPERF_LOW_PRIO_QP_MASK, required_argument, 0, 0 },
987 
988 	{ CPERF_IMIX, required_argument, 0, 0 },
989 	{ CPERF_DEVTYPE, required_argument, 0, 0 },
990 	{ CPERF_OPTYPE, required_argument, 0, 0 },
991 
992 	{ CPERF_SILENT, no_argument, 0, 0 },
993 	{ CPERF_SESSIONLESS, no_argument, 0, 0 },
994 	{ CPERF_SHARED_SESSION, no_argument, 0, 0 },
995 	{ CPERF_OUT_OF_PLACE, no_argument, 0, 0 },
996 	{ CPERF_TEST_FILE, required_argument, 0, 0 },
997 	{ CPERF_TEST_NAME, required_argument, 0, 0 },
998 
999 	{ CPERF_CIPHER_ALGO, required_argument, 0, 0 },
1000 	{ CPERF_CIPHER_OP, required_argument, 0, 0 },
1001 
1002 	{ CPERF_CIPHER_KEY_SZ, required_argument, 0, 0 },
1003 	{ CPERF_CIPHER_IV_SZ, required_argument, 0, 0 },
1004 
1005 	{ CPERF_AUTH_ALGO, required_argument, 0, 0 },
1006 	{ CPERF_AUTH_OP, required_argument, 0, 0 },
1007 
1008 	{ CPERF_AUTH_KEY_SZ, required_argument, 0, 0 },
1009 	{ CPERF_AUTH_IV_SZ, required_argument, 0, 0 },
1010 
1011 	{ CPERF_AEAD_ALGO, required_argument, 0, 0 },
1012 	{ CPERF_AEAD_OP, required_argument, 0, 0 },
1013 
1014 	{ CPERF_AEAD_KEY_SZ, required_argument, 0, 0 },
1015 	{ CPERF_AEAD_AAD_SZ, required_argument, 0, 0 },
1016 	{ CPERF_AEAD_IV_SZ, required_argument, 0, 0 },
1017 
1018 	{ CPERF_DIGEST_SZ, required_argument, 0, 0 },
1019 
1020 	{ CPERF_ASYM_OP, required_argument, 0, 0 },
1021 
1022 #ifdef RTE_LIB_SECURITY
1023 	{ CPERF_PDCP_SN_SZ, required_argument, 0, 0 },
1024 	{ CPERF_PDCP_DOMAIN, required_argument, 0, 0 },
1025 	{ CPERF_PDCP_SES_HFN_EN, no_argument, 0, 0 },
1026 	{ CPERF_ENABLE_SDAP, no_argument, 0, 0 },
1027 	{ CPERF_DOCSIS_HDR_SZ, required_argument, 0, 0 },
1028 	{ CPERF_TLS_VERSION, required_argument, 0, 0 },
1029 #endif
1030 	{ CPERF_CSV, no_argument, 0, 0},
1031 
1032 	{ CPERF_PMDCC_DELAY_MS, required_argument, 0, 0 },
1033 
1034 	{ NULL, 0, 0, 0 }
1035 };
1036 
1037 void
1038 cperf_options_default(struct cperf_options *opts)
1039 {
1040 	opts->test = CPERF_TEST_TYPE_THROUGHPUT;
1041 
1042 	opts->pool_sz = 8192;
1043 	opts->total_ops = 10000000;
1044 	opts->nb_descriptors = 2048;
1045 
1046 	opts->buffer_size_list[0] = 64;
1047 	opts->buffer_size_count = 1;
1048 	opts->max_buffer_size = 64;
1049 	opts->min_buffer_size = 64;
1050 	opts->inc_buffer_size = 0;
1051 
1052 	opts->burst_size_list[0] = 32;
1053 	opts->burst_size_count = 1;
1054 	opts->max_burst_size = 32;
1055 	opts->min_burst_size = 32;
1056 	opts->inc_burst_size = 0;
1057 
1058 	/*
1059 	 * Will be parsed from command line or set to
1060 	 * maximum buffer size + digest, later
1061 	 */
1062 	opts->segment_sz = 0;
1063 
1064 	opts->imix_distribution_count = 0;
1065 	strncpy(opts->device_type, "crypto_aesni_mb",
1066 			sizeof(opts->device_type));
1067 	opts->nb_qps = 1;
1068 
1069 	opts->op_type = CPERF_CIPHER_THEN_AUTH;
1070 
1071 	opts->silent = 0;
1072 	opts->test_file = NULL;
1073 	opts->test_name = NULL;
1074 	opts->sessionless = 0;
1075 	opts->out_of_place = 0;
1076 	opts->csv = 0;
1077 
1078 	opts->cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC;
1079 	opts->cipher_op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
1080 	opts->cipher_key_sz = 16;
1081 	opts->cipher_iv_sz = 16;
1082 
1083 	opts->auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
1084 	opts->auth_op = RTE_CRYPTO_AUTH_OP_GENERATE;
1085 
1086 	opts->auth_key_sz = 64;
1087 	opts->auth_iv_sz = 0;
1088 
1089 	opts->aead_key_sz = 0;
1090 	opts->aead_iv_sz = 0;
1091 	opts->aead_aad_sz = 0;
1092 
1093 	opts->digest_sz = 12;
1094 
1095 	opts->pmdcc_delay = 0;
1096 #ifdef RTE_LIB_SECURITY
1097 	opts->pdcp_sn_sz = 12;
1098 	opts->pdcp_domain = RTE_SECURITY_PDCP_MODE_CONTROL;
1099 	opts->pdcp_ses_hfn_en = 0;
1100 	opts->pdcp_sdap = 0;
1101 	opts->docsis_hdr_sz = 17;
1102 #endif
1103 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
1104 
1105 	opts->secp256r1_data = &secp256r1_perf_data;
1106 	opts->eddsa_data = &ed25519_perf_data;
1107 	opts->sm2_data = &sm2_perf_data;
1108 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1109 }
1110 
1111 static int
1112 cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)
1113 {
1114 	struct long_opt_parser parsermap[] = {
1115 		{ CPERF_PTEST_TYPE,	parse_cperf_test_type },
1116 		{ CPERF_MODEX_LEN,	parse_modex_len },
1117 		{ CPERF_SILENT,		parse_silent },
1118 		{ CPERF_POOL_SIZE,	parse_pool_sz },
1119 		{ CPERF_TOTAL_OPS,	parse_total_ops },
1120 		{ CPERF_BURST_SIZE,	parse_burst_sz },
1121 		{ CPERF_BUFFER_SIZE,	parse_buffer_sz },
1122 		{ CPERF_SEGMENT_SIZE,	parse_segment_sz },
1123 		{ CPERF_DESC_NB,	parse_desc_nb },
1124 		{ CPERF_LOW_PRIO_QP_MASK,	parse_low_prio_qp_mask },
1125 		{ CPERF_DEVTYPE,	parse_device_type },
1126 		{ CPERF_OPTYPE,		parse_op_type },
1127 		{ CPERF_SESSIONLESS,	parse_sessionless },
1128 		{ CPERF_SHARED_SESSION,	parse_shared_session },
1129 		{ CPERF_OUT_OF_PLACE,	parse_out_of_place },
1130 		{ CPERF_IMIX,		parse_imix },
1131 		{ CPERF_TEST_FILE,	parse_test_file },
1132 		{ CPERF_TEST_NAME,	parse_test_name },
1133 		{ CPERF_CIPHER_ALGO,	parse_cipher_algo },
1134 		{ CPERF_CIPHER_OP,	parse_cipher_op },
1135 		{ CPERF_CIPHER_KEY_SZ,	parse_cipher_key_sz },
1136 		{ CPERF_CIPHER_IV_SZ,	parse_cipher_iv_sz },
1137 		{ CPERF_AUTH_ALGO,	parse_auth_algo },
1138 		{ CPERF_AUTH_OP,	parse_auth_op },
1139 		{ CPERF_AUTH_KEY_SZ,	parse_auth_key_sz },
1140 		{ CPERF_AUTH_IV_SZ,	parse_auth_iv_sz },
1141 		{ CPERF_AEAD_ALGO,	parse_aead_algo },
1142 		{ CPERF_AEAD_OP,	parse_aead_op },
1143 		{ CPERF_AEAD_KEY_SZ,	parse_aead_key_sz },
1144 		{ CPERF_AEAD_IV_SZ,	parse_aead_iv_sz },
1145 		{ CPERF_AEAD_AAD_SZ,	parse_aead_aad_sz },
1146 		{ CPERF_DIGEST_SZ,	parse_digest_sz },
1147 		{ CPERF_ASYM_OP,	parse_asym_op },
1148 #ifdef RTE_LIB_SECURITY
1149 		{ CPERF_PDCP_SN_SZ,	parse_pdcp_sn_sz },
1150 		{ CPERF_PDCP_DOMAIN,	parse_pdcp_domain },
1151 		{ CPERF_PDCP_SES_HFN_EN,	parse_pdcp_ses_hfn_en },
1152 		{ CPERF_ENABLE_SDAP,	parse_enable_sdap },
1153 		{ CPERF_DOCSIS_HDR_SZ,	parse_docsis_hdr_sz },
1154 		{ CPERF_TLS_VERSION,	parse_tls_version },
1155 #endif
1156 		{ CPERF_CSV,		parse_csv_friendly},
1157 		{ CPERF_PMDCC_DELAY_MS,	parse_pmd_cyclecount_delay_ms},
1158 	};
1159 	unsigned int i;
1160 
1161 	for (i = 0; i < RTE_DIM(parsermap); i++) {
1162 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
1163 				strlen(lgopts[opt_idx].name)) == 0)
1164 			return parsermap[i].parser_fn(opts, optarg);
1165 	}
1166 
1167 	return -EINVAL;
1168 }
1169 
1170 int
1171 cperf_options_parse(struct cperf_options *options, int argc, char **argv)
1172 {
1173 	int opt, retval, opt_idx;
1174 
1175 	while ((opt = getopt_long(argc, argv, "h", lgopts, &opt_idx)) != EOF) {
1176 		switch (opt) {
1177 		case 'h':
1178 			usage(argv[0]);
1179 			exit(EXIT_SUCCESS);
1180 			break;
1181 		/* long options */
1182 		case 0:
1183 			retval = cperf_opts_parse_long(opt_idx, options);
1184 			if (retval != 0)
1185 				return retval;
1186 
1187 			break;
1188 
1189 		default:
1190 			usage(argv[0]);
1191 			return -EINVAL;
1192 		}
1193 	}
1194 
1195 	return 0;
1196 }
1197 
1198 static int
1199 check_cipher_buffer_length(struct cperf_options *options)
1200 {
1201 	uint32_t buffer_size, buffer_size_idx = 0;
1202 
1203 	if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1204 			options->cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) {
1205 		if (options->inc_buffer_size != 0)
1206 			buffer_size = options->min_buffer_size;
1207 		else
1208 			buffer_size = options->buffer_size_list[0];
1209 
1210 		if ((options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE) &&
1211 				(options->op_type == CPERF_AUTH_THEN_CIPHER))
1212 			buffer_size += options->digest_sz;
1213 
1214 		while (buffer_size <= options->max_buffer_size) {
1215 			if ((buffer_size % AES_BLOCK_SIZE) != 0) {
1216 				RTE_LOG(ERR, USER1, "Some of the buffer sizes are "
1217 					"not suitable for the algorithm selected\n");
1218 				return -EINVAL;
1219 			}
1220 
1221 			if (options->inc_buffer_size != 0)
1222 				buffer_size += options->inc_buffer_size;
1223 			else {
1224 				if (++buffer_size_idx == options->buffer_size_count)
1225 					break;
1226 				buffer_size = options->buffer_size_list[buffer_size_idx];
1227 			}
1228 
1229 		}
1230 	}
1231 
1232 	if (options->cipher_algo == RTE_CRYPTO_CIPHER_DES_CBC ||
1233 			options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_CBC ||
1234 			options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_ECB) {
1235 		if (options->inc_buffer_size != 0)
1236 			buffer_size = options->min_buffer_size;
1237 		else
1238 			buffer_size = options->buffer_size_list[0];
1239 
1240 		if ((options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE) &&
1241 				(options->op_type == CPERF_AUTH_THEN_CIPHER))
1242 			buffer_size += options->digest_sz;
1243 
1244 		while (buffer_size <= options->max_buffer_size) {
1245 			if ((buffer_size % DES_BLOCK_SIZE) != 0) {
1246 				RTE_LOG(ERR, USER1, "Some of the buffer sizes are "
1247 					"not suitable for the algorithm selected\n");
1248 				return -EINVAL;
1249 			}
1250 
1251 			if (options->inc_buffer_size != 0)
1252 				buffer_size += options->inc_buffer_size;
1253 			else {
1254 				if (++buffer_size_idx == options->buffer_size_count)
1255 					break;
1256 				buffer_size = options->buffer_size_list[buffer_size_idx];
1257 			}
1258 
1259 		}
1260 	}
1261 
1262 	return 0;
1263 }
1264 
1265 #ifdef RTE_LIB_SECURITY
1266 static int
1267 check_docsis_buffer_length(struct cperf_options *options)
1268 {
1269 	uint32_t buffer_size, buffer_size_idx = 0;
1270 
1271 	if (options->inc_buffer_size != 0)
1272 		buffer_size = options->min_buffer_size;
1273 	else
1274 		buffer_size = options->buffer_size_list[0];
1275 
1276 	while (buffer_size <= options->max_buffer_size) {
1277 		if (buffer_size < (uint32_t)(options->docsis_hdr_sz +
1278 				RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN)) {
1279 			RTE_LOG(ERR, USER1, "Some of the buffer sizes are not "
1280 				"valid for DOCSIS\n");
1281 			return -EINVAL;
1282 		}
1283 
1284 		if (options->inc_buffer_size != 0)
1285 			buffer_size += options->inc_buffer_size;
1286 		else {
1287 			if (++buffer_size_idx == options->buffer_size_count)
1288 				break;
1289 			buffer_size =
1290 				options->buffer_size_list[buffer_size_idx];
1291 		}
1292 	}
1293 
1294 	return 0;
1295 }
1296 #endif
1297 
1298 static bool
1299 is_valid_chained_op(struct cperf_options *options)
1300 {
1301 	if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1302 			options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
1303 		return true;
1304 
1305 	if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
1306 			options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
1307 		return true;
1308 
1309 	return false;
1310 }
1311 
1312 int
1313 cperf_options_check(struct cperf_options *options)
1314 {
1315 	int i;
1316 
1317 	if (options->op_type == CPERF_CIPHER_ONLY ||
1318 			options->op_type == CPERF_DOCSIS)
1319 		options->digest_sz = 0;
1320 
1321 	if (options->out_of_place &&
1322 			options->segment_sz <= options->max_buffer_size) {
1323 		RTE_LOG(ERR, USER1, "Out of place mode can only work "
1324 					"with non segmented buffers\n");
1325 		return -EINVAL;
1326 	}
1327 
1328 	/*
1329 	 * If segment size is not set, assume only one segment,
1330 	 * big enough to contain the largest buffer and the digest
1331 	 */
1332 	if (options->segment_sz == 0) {
1333 		options->segment_sz = options->max_buffer_size +
1334 				options->digest_sz;
1335 		/* In IPsec and TLS operation, packet length will be increased
1336 		 * by some bytes depend upon the algorithm, so increasing
1337 		 * the segment size by headroom to cover most of
1338 		 * the scenarios.
1339 		 */
1340 		if (options->op_type == CPERF_IPSEC || options->op_type == CPERF_TLS)
1341 			options->segment_sz += RTE_PKTMBUF_HEADROOM;
1342 	}
1343 
1344 	if (options->segment_sz < options->digest_sz) {
1345 		RTE_LOG(ERR, USER1,
1346 				"Segment size should be at least "
1347 				"the size of the digest\n");
1348 		return -EINVAL;
1349 	}
1350 
1351 	if ((options->imix_distribution_count != 0) &&
1352 			(options->imix_distribution_count !=
1353 				options->buffer_size_count)) {
1354 		RTE_LOG(ERR, USER1, "IMIX distribution must have the same "
1355 				"number of buffer sizes\n");
1356 		return -EINVAL;
1357 	}
1358 
1359 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1360 			options->test_file == NULL) {
1361 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1362 				" vectors.\n");
1363 		return -EINVAL;
1364 	}
1365 
1366 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1367 			options->op_type != CPERF_CIPHER_ONLY &&
1368 			options->test_name == NULL) {
1369 		RTE_LOG(ERR, USER1, "Define test name to get the correct digest"
1370 				" from the test vectors.\n");
1371 		return -EINVAL;
1372 	}
1373 
1374 	if (options->test_name != NULL && options->test_file == NULL) {
1375 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1376 				" vectors.\n");
1377 		return -EINVAL;
1378 	}
1379 
1380 	if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY &&
1381 			options->test_file == NULL) {
1382 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1383 				" vectors.\n");
1384 		return -EINVAL;
1385 	}
1386 
1387 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1388 			(options->inc_buffer_size != 0 ||
1389 			options->buffer_size_count > 1)) {
1390 		RTE_LOG(ERR, USER1, "Only one buffer size is allowed when "
1391 				"using the verify test.\n");
1392 		return -EINVAL;
1393 	}
1394 
1395 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1396 			(options->inc_burst_size != 0 ||
1397 			options->burst_size_count > 1)) {
1398 		RTE_LOG(ERR, USER1, "Only one burst size is allowed when "
1399 				"using the verify test.\n");
1400 		return -EINVAL;
1401 	}
1402 
1403 	if (options->test == CPERF_TEST_TYPE_PMDCC &&
1404 			options->pool_sz < options->nb_descriptors) {
1405 		RTE_LOG(ERR, USER1, "For pmd cyclecount benchmarks, pool size "
1406 				"must be equal or greater than the number of "
1407 				"cryptodev descriptors.\n");
1408 		return -EINVAL;
1409 	}
1410 
1411 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1412 			options->imix_distribution_count > 0) {
1413 		RTE_LOG(ERR, USER1, "IMIX is not allowed when "
1414 				"using the verify test.\n");
1415 		return -EINVAL;
1416 	}
1417 
1418 	if (options->op_type == CPERF_CIPHER_THEN_AUTH ||
1419 			options->op_type == CPERF_AUTH_THEN_CIPHER) {
1420 		if (!is_valid_chained_op(options)) {
1421 			RTE_LOG(ERR, USER1, "Invalid chained operation.\n");
1422 			return -EINVAL;
1423 		}
1424 	}
1425 
1426 	if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
1427 		if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1428 				options->auth_op !=
1429 				RTE_CRYPTO_AUTH_OP_GENERATE) {
1430 			RTE_LOG(ERR, USER1, "Option cipher then auth must use"
1431 					" options: encrypt and generate.\n");
1432 			return -EINVAL;
1433 		}
1434 	}
1435 
1436 	if (options->test == CPERF_TEST_TYPE_THROUGHPUT &&
1437 	    (options->aead_op == RTE_CRYPTO_AEAD_OP_DECRYPT ||
1438 	     options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) &&
1439 	    !options->out_of_place) {
1440 		RTE_LOG(ERR, USER1, "Only out-of-place is allowed in throughput decryption.\n");
1441 		return -EINVAL;
1442 	}
1443 
1444 	if (options->op_type == CPERF_CIPHER_ONLY ||
1445 			options->op_type == CPERF_CIPHER_THEN_AUTH ||
1446 			options->op_type == CPERF_AUTH_THEN_CIPHER) {
1447 		if (check_cipher_buffer_length(options) < 0)
1448 			return -EINVAL;
1449 	}
1450 
1451 	if (options->modex_len) {
1452 		if (options->op_type != CPERF_ASYM_MODEX) {
1453 			RTE_LOG(ERR, USER1, "Option modex len should be used only with "
1454 					" optype: modex.\n");
1455 			return -EINVAL;
1456 		}
1457 
1458 		for (i = 0; i < (int)RTE_DIM(modex_perf_data); i++) {
1459 			if (modex_perf_data[i].modulus.len ==
1460 			    options->modex_len) {
1461 				options->modex_data =
1462 					(struct cperf_modex_test_data
1463 						 *)&modex_perf_data[i];
1464 				break;
1465 			}
1466 		}
1467 		if (i == (int)RTE_DIM(modex_perf_data)) {
1468 			RTE_LOG(ERR, USER1,
1469 				"Option modex len: %d is not supported\n",
1470 				options->modex_len);
1471 			return -EINVAL;
1472 		}
1473 	}
1474 
1475 #ifdef RTE_LIB_SECURITY
1476 	if (options->op_type == CPERF_DOCSIS) {
1477 		if (check_docsis_buffer_length(options) < 0)
1478 			return -EINVAL;
1479 	}
1480 
1481 	if (options->op_type == CPERF_IPSEC || options->op_type == CPERF_TLS) {
1482 		if (options->aead_algo) {
1483 			if (options->aead_op == RTE_CRYPTO_AEAD_OP_ENCRYPT)
1484 				options->is_outbound = 1;
1485 			else
1486 				options->is_outbound = 0;
1487 		} else {
1488 			if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1489 			    options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
1490 				options->is_outbound = 1;
1491 			else
1492 				options->is_outbound = 0;
1493 		}
1494 	}
1495 #endif
1496 
1497 	return 0;
1498 }
1499 
1500 void
1501 cperf_options_dump(struct cperf_options *opts)
1502 {
1503 	uint8_t size_idx;
1504 
1505 	printf("# Crypto Performance Application Options:\n");
1506 	printf("#\n");
1507 	printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]);
1508 	printf("#\n");
1509 	printf("# cperf operation type: %s\n", cperf_op_type_strs[opts->op_type]);
1510 	printf("#\n");
1511 	printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz);
1512 	printf("# total number of ops: %u\n", opts->total_ops);
1513 	if (opts->inc_buffer_size != 0) {
1514 		printf("# buffer size:\n");
1515 		printf("#\t min: %u\n", opts->min_buffer_size);
1516 		printf("#\t max: %u\n", opts->max_buffer_size);
1517 		printf("#\t inc: %u\n", opts->inc_buffer_size);
1518 	} else {
1519 		printf("# buffer sizes: ");
1520 		for (size_idx = 0; size_idx < opts->buffer_size_count; size_idx++)
1521 			printf("%u ", opts->buffer_size_list[size_idx]);
1522 		printf("\n");
1523 	}
1524 	if (opts->inc_burst_size != 0) {
1525 		printf("# burst size:\n");
1526 		printf("#\t min: %u\n", opts->min_burst_size);
1527 		printf("#\t max: %u\n", opts->max_burst_size);
1528 		printf("#\t inc: %u\n", opts->inc_burst_size);
1529 	} else {
1530 		printf("# burst sizes: ");
1531 		for (size_idx = 0; size_idx < opts->burst_size_count; size_idx++)
1532 			printf("%u ", opts->burst_size_list[size_idx]);
1533 		printf("\n");
1534 	}
1535 	printf("\n# segment size: %u\n", opts->segment_sz);
1536 	printf("#\n");
1537 	printf("# cryptodev type: %s\n", opts->device_type);
1538 	printf("#\n");
1539 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
1540 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
1541 	if (cperf_is_asym_test(opts))
1542 		printf("# asym operation type: %s\n",
1543 				rte_crypto_asym_op_strings[opts->asym_op_type]);
1544 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
1545 	printf("# shared session: %s\n", opts->shared_session ? "yes" : "no");
1546 	printf("# out of place: %s\n", opts->out_of_place ? "yes" : "no");
1547 	if (opts->test == CPERF_TEST_TYPE_PMDCC)
1548 		printf("# inter-burst delay: %u ms\n", opts->pmdcc_delay);
1549 
1550 	printf("#\n");
1551 
1552 	if (opts->op_type == CPERF_AUTH_ONLY ||
1553 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
1554 			opts->op_type == CPERF_AUTH_THEN_CIPHER) {
1555 		printf("# auth algorithm: %s\n",
1556 			rte_cryptodev_get_auth_algo_string(opts->auth_algo));
1557 		printf("# auth operation: %s\n",
1558 			rte_crypto_auth_operation_strings[opts->auth_op]);
1559 		printf("# auth key size: %u\n", opts->auth_key_sz);
1560 		printf("# auth iv size: %u\n", opts->auth_iv_sz);
1561 		printf("# auth digest size: %u\n", opts->digest_sz);
1562 		printf("#\n");
1563 	}
1564 
1565 	if (opts->op_type == CPERF_CIPHER_ONLY ||
1566 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
1567 			opts->op_type == CPERF_AUTH_THEN_CIPHER) {
1568 		printf("# cipher algorithm: %s\n",
1569 			rte_cryptodev_get_cipher_algo_string(opts->cipher_algo));
1570 		printf("# cipher operation: %s\n",
1571 			rte_crypto_cipher_operation_strings[opts->cipher_op]);
1572 		printf("# cipher key size: %u\n", opts->cipher_key_sz);
1573 		printf("# cipher iv size: %u\n", opts->cipher_iv_sz);
1574 		printf("#\n");
1575 	}
1576 
1577 	if (opts->op_type == CPERF_AEAD) {
1578 		printf("# aead algorithm: %s\n",
1579 			rte_cryptodev_get_aead_algo_string(opts->aead_algo));
1580 		printf("# aead operation: %s\n",
1581 			rte_crypto_aead_operation_strings[opts->aead_op]);
1582 		printf("# aead key size: %u\n", opts->aead_key_sz);
1583 		printf("# aead iv size: %u\n", opts->aead_iv_sz);
1584 		printf("# aead digest size: %u\n", opts->digest_sz);
1585 		printf("# aead aad size: %u\n", opts->aead_aad_sz);
1586 		printf("#\n");
1587 	}
1588 
1589 #ifdef RTE_LIB_SECURITY
1590 	if (opts->op_type == CPERF_DOCSIS) {
1591 		printf("# docsis header size: %u\n", opts->docsis_hdr_sz);
1592 		printf("#\n");
1593 	}
1594 #endif
1595 }
1596