xref: /dpdk/app/test-crypto-perf/cperf_options_parsing.c (revision 8bd4315ceba8d9de9dedafdaa963ffecc09cc971)
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 / 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_SM2],
495 			CPERF_ASYM_SM2
496 		},
497 		{
498 			cperf_op_type_strs[CPERF_TLS],
499 			CPERF_TLS
500 		},
501 	};
502 
503 	int id = get_str_key_id_mapping(optype_namemap,
504 			RTE_DIM(optype_namemap), arg);
505 	if (id < 0) {
506 		RTE_LOG(ERR, USER1, "invalid opt type specified\n");
507 		return -1;
508 	}
509 
510 	opts->op_type = (enum cperf_op_type)id;
511 
512 	return 0;
513 }
514 
515 static int
516 parse_sessionless(struct cperf_options *opts,
517 		const char *arg __rte_unused)
518 {
519 	opts->sessionless = 1;
520 	return 0;
521 }
522 
523 static int
524 parse_shared_session(struct cperf_options *opts,
525 		const char *arg __rte_unused)
526 {
527 	opts->shared_session = 1;
528 	return 0;
529 }
530 
531 static int
532 parse_out_of_place(struct cperf_options *opts,
533 		const char *arg __rte_unused)
534 {
535 	opts->out_of_place = 1;
536 	return 0;
537 }
538 
539 static int
540 parse_test_file(struct cperf_options *opts,
541 		const char *arg)
542 {
543 	opts->test_file = strdup(arg);
544 	if (opts->test_file == NULL) {
545 		RTE_LOG(ERR, USER1, "Dup vector file failed!\n");
546 		return -1;
547 	}
548 	if (access(opts->test_file, F_OK) != -1)
549 		return 0;
550 	RTE_LOG(ERR, USER1, "Test vector file doesn't exist\n");
551 	free(opts->test_file);
552 
553 	return -1;
554 }
555 
556 static int
557 parse_test_name(struct cperf_options *opts,
558 		const char *arg)
559 {
560 	char *test_name = (char *) rte_zmalloc(NULL,
561 		sizeof(char) * (strlen(arg) + 3), 0);
562 	if (test_name == NULL) {
563 		RTE_LOG(ERR, USER1, "Failed to rte zmalloc with size: %zu\n",
564 			strlen(arg) + 3);
565 		return -1;
566 	}
567 
568 	snprintf(test_name, strlen(arg) + 3, "[%s]", arg);
569 	opts->test_name = test_name;
570 
571 	return 0;
572 }
573 
574 static int
575 parse_silent(struct cperf_options *opts,
576 		const char *arg __rte_unused)
577 {
578 	opts->silent = 1;
579 
580 	return 0;
581 }
582 
583 static int
584 parse_enable_sdap(struct cperf_options *opts,
585 		const char *arg __rte_unused)
586 {
587 	opts->pdcp_sdap = 1;
588 
589 	return 0;
590 }
591 
592 static int
593 parse_cipher_algo(struct cperf_options *opts, const char *arg)
594 {
595 
596 	enum rte_crypto_cipher_algorithm cipher_algo;
597 
598 	if (rte_cryptodev_get_cipher_algo_enum(&cipher_algo, arg) < 0) {
599 		RTE_LOG(ERR, USER1, "Invalid cipher algorithm specified\n");
600 		return -1;
601 	}
602 
603 	opts->cipher_algo = cipher_algo;
604 
605 	return 0;
606 }
607 
608 static int
609 parse_cipher_op(struct cperf_options *opts, const char *arg)
610 {
611 	struct name_id_map cipher_op_namemap[] = {
612 		{
613 			rte_crypto_cipher_operation_strings
614 			[RTE_CRYPTO_CIPHER_OP_ENCRYPT],
615 			RTE_CRYPTO_CIPHER_OP_ENCRYPT },
616 		{
617 			rte_crypto_cipher_operation_strings
618 			[RTE_CRYPTO_CIPHER_OP_DECRYPT],
619 			RTE_CRYPTO_CIPHER_OP_DECRYPT
620 		}
621 	};
622 
623 	int id = get_str_key_id_mapping(cipher_op_namemap,
624 			RTE_DIM(cipher_op_namemap), arg);
625 	if (id < 0) {
626 		RTE_LOG(ERR, USER1, "Invalid cipher operation specified\n");
627 		return -1;
628 	}
629 
630 	opts->cipher_op = (enum rte_crypto_cipher_operation)id;
631 
632 	return 0;
633 }
634 
635 static int
636 parse_cipher_key_sz(struct cperf_options *opts, const char *arg)
637 {
638 	return parse_uint16_t(&opts->cipher_key_sz, arg);
639 }
640 
641 static int
642 parse_cipher_iv_sz(struct cperf_options *opts, const char *arg)
643 {
644 	return parse_uint16_t(&opts->cipher_iv_sz, arg);
645 }
646 
647 static int
648 parse_auth_algo(struct cperf_options *opts, const char *arg)
649 {
650 	enum rte_crypto_auth_algorithm auth_algo;
651 
652 	if (rte_cryptodev_get_auth_algo_enum(&auth_algo, arg) < 0) {
653 		RTE_LOG(ERR, USER1, "Invalid authentication algorithm specified\n");
654 		return -1;
655 	}
656 
657 	opts->auth_algo = auth_algo;
658 
659 	return 0;
660 }
661 
662 static int
663 parse_auth_op(struct cperf_options *opts, const char *arg)
664 {
665 	struct name_id_map auth_op_namemap[] = {
666 		{
667 			rte_crypto_auth_operation_strings
668 			[RTE_CRYPTO_AUTH_OP_GENERATE],
669 			RTE_CRYPTO_AUTH_OP_GENERATE },
670 		{
671 			rte_crypto_auth_operation_strings
672 			[RTE_CRYPTO_AUTH_OP_VERIFY],
673 			RTE_CRYPTO_AUTH_OP_VERIFY
674 		}
675 	};
676 
677 	int id = get_str_key_id_mapping(auth_op_namemap,
678 			RTE_DIM(auth_op_namemap), arg);
679 	if (id < 0) {
680 		RTE_LOG(ERR, USER1, "invalid authentication operation specified"
681 				"\n");
682 		return -1;
683 	}
684 
685 	opts->auth_op = (enum rte_crypto_auth_operation)id;
686 
687 	return 0;
688 }
689 
690 static int
691 parse_auth_key_sz(struct cperf_options *opts, const char *arg)
692 {
693 	return parse_uint16_t(&opts->auth_key_sz, arg);
694 }
695 
696 static int
697 parse_digest_sz(struct cperf_options *opts, const char *arg)
698 {
699 	return parse_uint16_t(&opts->digest_sz, arg);
700 }
701 
702 #ifdef RTE_LIB_SECURITY
703 static int
704 parse_pdcp_sn_sz(struct cperf_options *opts, const char *arg)
705 {
706 	uint32_t val = 0;
707 	int ret = parse_uint32_t(&val, arg);
708 
709 	if (ret < 0)
710 		return ret;
711 
712 	if (val != RTE_SECURITY_PDCP_SN_SIZE_5 &&
713 			val != RTE_SECURITY_PDCP_SN_SIZE_7 &&
714 			val != RTE_SECURITY_PDCP_SN_SIZE_12 &&
715 			val != RTE_SECURITY_PDCP_SN_SIZE_15 &&
716 			val != RTE_SECURITY_PDCP_SN_SIZE_18) {
717 		printf("\nInvalid pdcp SN size: %u\n", val);
718 		return -ERANGE;
719 	}
720 	opts->pdcp_sn_sz = val;
721 
722 	return 0;
723 }
724 
725 const char *cperf_pdcp_domain_strs[] = {
726 	[RTE_SECURITY_PDCP_MODE_CONTROL] = "control",
727 	[RTE_SECURITY_PDCP_MODE_DATA] = "data",
728 	[RTE_SECURITY_PDCP_MODE_SHORT_MAC] = "short_mac"
729 };
730 
731 static int
732 parse_pdcp_domain(struct cperf_options *opts, const char *arg)
733 {
734 	struct name_id_map pdcp_domain_namemap[] = {
735 		{
736 			cperf_pdcp_domain_strs
737 			[RTE_SECURITY_PDCP_MODE_CONTROL],
738 			RTE_SECURITY_PDCP_MODE_CONTROL },
739 		{
740 			cperf_pdcp_domain_strs
741 			[RTE_SECURITY_PDCP_MODE_DATA],
742 			RTE_SECURITY_PDCP_MODE_DATA
743 		},
744 		{
745 			cperf_pdcp_domain_strs
746 			[RTE_SECURITY_PDCP_MODE_SHORT_MAC],
747 			RTE_SECURITY_PDCP_MODE_SHORT_MAC
748 		}
749 	};
750 
751 	int id = get_str_key_id_mapping(pdcp_domain_namemap,
752 			RTE_DIM(pdcp_domain_namemap), arg);
753 	if (id < 0) {
754 		RTE_LOG(ERR, USER1, "invalid pdcp domain specified"
755 				"\n");
756 		return -1;
757 	}
758 
759 	opts->pdcp_domain = (enum rte_security_pdcp_domain)id;
760 
761 	return 0;
762 }
763 
764 const char *cperf_tls_version_strs[] = {
765 	[RTE_SECURITY_VERSION_TLS_1_2] = "TLS1.2",
766 	[RTE_SECURITY_VERSION_TLS_1_3] = "TLS1.3",
767 	[RTE_SECURITY_VERSION_DTLS_1_2] = "DTLS1.2"
768 };
769 
770 static int
771 parse_tls_version(struct cperf_options *opts, const char *arg)
772 {
773 	struct name_id_map tls_version_namemap[] = {
774 		{
775 			cperf_tls_version_strs
776 			[RTE_SECURITY_VERSION_TLS_1_2],
777 			RTE_SECURITY_VERSION_TLS_1_2
778 		},
779 		{
780 			cperf_tls_version_strs
781 			[RTE_SECURITY_VERSION_TLS_1_3],
782 			RTE_SECURITY_VERSION_TLS_1_3
783 		},
784 		{
785 			cperf_tls_version_strs
786 			[RTE_SECURITY_VERSION_DTLS_1_2],
787 			RTE_SECURITY_VERSION_DTLS_1_2
788 		},
789 	};
790 
791 	int id = get_str_key_id_mapping(tls_version_namemap,
792 			RTE_DIM(tls_version_namemap), arg);
793 	if (id < 0) {
794 		RTE_LOG(ERR, USER1, "invalid TLS version specified\n");
795 		return -1;
796 	}
797 
798 	opts->tls_version = (enum rte_security_tls_version)id;
799 
800 	return 0;
801 }
802 
803 static int
804 parse_pdcp_ses_hfn_en(struct cperf_options *opts, const char *arg __rte_unused)
805 {
806 	opts->pdcp_ses_hfn_en = 1;
807 	return 0;
808 }
809 
810 static int
811 parse_docsis_hdr_sz(struct cperf_options *opts, const char *arg)
812 {
813 	return parse_uint16_t(&opts->docsis_hdr_sz, arg);
814 }
815 #endif
816 
817 static int
818 parse_auth_iv_sz(struct cperf_options *opts, const char *arg)
819 {
820 	return parse_uint16_t(&opts->auth_iv_sz, arg);
821 }
822 
823 static int
824 parse_aead_algo(struct cperf_options *opts, const char *arg)
825 {
826 	enum rte_crypto_aead_algorithm aead_algo;
827 
828 	if (rte_cryptodev_get_aead_algo_enum(&aead_algo, arg) < 0) {
829 		RTE_LOG(ERR, USER1, "Invalid AEAD algorithm specified\n");
830 		return -1;
831 	}
832 
833 	opts->aead_algo = aead_algo;
834 
835 	return 0;
836 }
837 
838 static int
839 parse_aead_op(struct cperf_options *opts, const char *arg)
840 {
841 	struct name_id_map aead_op_namemap[] = {
842 		{
843 			rte_crypto_aead_operation_strings
844 			[RTE_CRYPTO_AEAD_OP_ENCRYPT],
845 			RTE_CRYPTO_AEAD_OP_ENCRYPT },
846 		{
847 			rte_crypto_aead_operation_strings
848 			[RTE_CRYPTO_AEAD_OP_DECRYPT],
849 			RTE_CRYPTO_AEAD_OP_DECRYPT
850 		}
851 	};
852 
853 	int id = get_str_key_id_mapping(aead_op_namemap,
854 			RTE_DIM(aead_op_namemap), arg);
855 	if (id < 0) {
856 		RTE_LOG(ERR, USER1, "invalid AEAD operation specified"
857 				"\n");
858 		return -1;
859 	}
860 
861 	opts->aead_op = (enum rte_crypto_aead_operation)id;
862 
863 	return 0;
864 }
865 
866 static int
867 parse_aead_key_sz(struct cperf_options *opts, const char *arg)
868 {
869 	return parse_uint16_t(&opts->aead_key_sz, arg);
870 }
871 
872 static int
873 parse_aead_iv_sz(struct cperf_options *opts, const char *arg)
874 {
875 	return parse_uint16_t(&opts->aead_iv_sz, arg);
876 }
877 
878 static int
879 parse_aead_aad_sz(struct cperf_options *opts, const char *arg)
880 {
881 	return parse_uint16_t(&opts->aead_aad_sz, arg);
882 }
883 
884 static int
885 parse_asym_op(struct cperf_options *opts, const char *arg)
886 {
887 	struct name_id_map asym_op_namemap[] = {
888 		{
889 			rte_crypto_asym_op_strings
890 			[RTE_CRYPTO_ASYM_OP_ENCRYPT],
891 			RTE_CRYPTO_ASYM_OP_ENCRYPT
892 		},
893 		{
894 			rte_crypto_asym_op_strings
895 			[RTE_CRYPTO_ASYM_OP_DECRYPT],
896 			RTE_CRYPTO_ASYM_OP_DECRYPT
897 		},
898 		{
899 			rte_crypto_asym_op_strings
900 			[RTE_CRYPTO_ASYM_OP_SIGN],
901 			RTE_CRYPTO_ASYM_OP_SIGN
902 		},
903 		{
904 			rte_crypto_asym_op_strings
905 			[RTE_CRYPTO_ASYM_OP_VERIFY],
906 			RTE_CRYPTO_ASYM_OP_VERIFY
907 		}
908 	};
909 
910 	int id = get_str_key_id_mapping(asym_op_namemap,
911 			RTE_DIM(asym_op_namemap), arg);
912 	if (id < 0) {
913 		RTE_LOG(ERR, USER1, "invalid ASYM operation specified\n");
914 		return -1;
915 	}
916 
917 	opts->asym_op_type = (enum rte_crypto_asym_op_type)id;
918 
919 	return 0;
920 }
921 
922 
923 static int
924 parse_csv_friendly(struct cperf_options *opts, const char *arg __rte_unused)
925 {
926 	opts->csv = 1;
927 	opts->silent = 1;
928 	return 0;
929 }
930 
931 static int
932 parse_pmd_cyclecount_delay_ms(struct cperf_options *opts,
933 			const char *arg)
934 {
935 	int ret = parse_uint32_t(&opts->pmdcc_delay, arg);
936 
937 	if (ret) {
938 		RTE_LOG(ERR, USER1, "failed to parse pmd-cyclecount delay\n");
939 		return -1;
940 	}
941 
942 	return 0;
943 }
944 
945 static int
946 parse_low_prio_qp_mask(struct cperf_options *opts, const char *arg)
947 {
948 	char *end = NULL;
949 	unsigned long n;
950 
951 	/* parse hexadecimal string */
952 	n = strtoul(arg, &end, 16);
953 	if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
954 		return -1;
955 
956 	opts->low_prio_qp_mask = n;
957 
958 	return 0;
959 }
960 
961 typedef int (*option_parser_t)(struct cperf_options *opts,
962 		const char *arg);
963 
964 struct long_opt_parser {
965 	const char *lgopt_name;
966 	option_parser_t parser_fn;
967 
968 };
969 
970 static struct option lgopts[] = {
971 
972 	{ CPERF_PTEST_TYPE, required_argument, 0, 0 },
973 	{ CPERF_MODEX_LEN, required_argument, 0, 0 },
974 
975 	{ CPERF_POOL_SIZE, required_argument, 0, 0 },
976 	{ CPERF_TOTAL_OPS, required_argument, 0, 0 },
977 	{ CPERF_BURST_SIZE, required_argument, 0, 0 },
978 	{ CPERF_BUFFER_SIZE, required_argument, 0, 0 },
979 	{ CPERF_SEGMENT_SIZE, required_argument, 0, 0 },
980 	{ CPERF_DESC_NB, required_argument, 0, 0 },
981 
982 	{ CPERF_LOW_PRIO_QP_MASK, required_argument, 0, 0 },
983 
984 	{ CPERF_IMIX, required_argument, 0, 0 },
985 	{ CPERF_DEVTYPE, required_argument, 0, 0 },
986 	{ CPERF_OPTYPE, required_argument, 0, 0 },
987 
988 	{ CPERF_SILENT, no_argument, 0, 0 },
989 	{ CPERF_SESSIONLESS, no_argument, 0, 0 },
990 	{ CPERF_SHARED_SESSION, no_argument, 0, 0 },
991 	{ CPERF_OUT_OF_PLACE, no_argument, 0, 0 },
992 	{ CPERF_TEST_FILE, required_argument, 0, 0 },
993 	{ CPERF_TEST_NAME, required_argument, 0, 0 },
994 
995 	{ CPERF_CIPHER_ALGO, required_argument, 0, 0 },
996 	{ CPERF_CIPHER_OP, required_argument, 0, 0 },
997 
998 	{ CPERF_CIPHER_KEY_SZ, required_argument, 0, 0 },
999 	{ CPERF_CIPHER_IV_SZ, required_argument, 0, 0 },
1000 
1001 	{ CPERF_AUTH_ALGO, required_argument, 0, 0 },
1002 	{ CPERF_AUTH_OP, required_argument, 0, 0 },
1003 
1004 	{ CPERF_AUTH_KEY_SZ, required_argument, 0, 0 },
1005 	{ CPERF_AUTH_IV_SZ, required_argument, 0, 0 },
1006 
1007 	{ CPERF_AEAD_ALGO, required_argument, 0, 0 },
1008 	{ CPERF_AEAD_OP, required_argument, 0, 0 },
1009 
1010 	{ CPERF_AEAD_KEY_SZ, required_argument, 0, 0 },
1011 	{ CPERF_AEAD_AAD_SZ, required_argument, 0, 0 },
1012 	{ CPERF_AEAD_IV_SZ, required_argument, 0, 0 },
1013 
1014 	{ CPERF_DIGEST_SZ, required_argument, 0, 0 },
1015 
1016 	{ CPERF_ASYM_OP, required_argument, 0, 0 },
1017 
1018 #ifdef RTE_LIB_SECURITY
1019 	{ CPERF_PDCP_SN_SZ, required_argument, 0, 0 },
1020 	{ CPERF_PDCP_DOMAIN, required_argument, 0, 0 },
1021 	{ CPERF_PDCP_SES_HFN_EN, no_argument, 0, 0 },
1022 	{ CPERF_ENABLE_SDAP, no_argument, 0, 0 },
1023 	{ CPERF_DOCSIS_HDR_SZ, required_argument, 0, 0 },
1024 	{ CPERF_TLS_VERSION, required_argument, 0, 0 },
1025 #endif
1026 	{ CPERF_CSV, no_argument, 0, 0},
1027 
1028 	{ CPERF_PMDCC_DELAY_MS, required_argument, 0, 0 },
1029 
1030 	{ NULL, 0, 0, 0 }
1031 };
1032 
1033 void
1034 cperf_options_default(struct cperf_options *opts)
1035 {
1036 	opts->test = CPERF_TEST_TYPE_THROUGHPUT;
1037 
1038 	opts->pool_sz = 8192;
1039 	opts->total_ops = 10000000;
1040 	opts->nb_descriptors = 2048;
1041 
1042 	opts->buffer_size_list[0] = 64;
1043 	opts->buffer_size_count = 1;
1044 	opts->max_buffer_size = 64;
1045 	opts->min_buffer_size = 64;
1046 	opts->inc_buffer_size = 0;
1047 
1048 	opts->burst_size_list[0] = 32;
1049 	opts->burst_size_count = 1;
1050 	opts->max_burst_size = 32;
1051 	opts->min_burst_size = 32;
1052 	opts->inc_burst_size = 0;
1053 
1054 	/*
1055 	 * Will be parsed from command line or set to
1056 	 * maximum buffer size + digest, later
1057 	 */
1058 	opts->segment_sz = 0;
1059 
1060 	opts->imix_distribution_count = 0;
1061 	strncpy(opts->device_type, "crypto_aesni_mb",
1062 			sizeof(opts->device_type));
1063 	opts->nb_qps = 1;
1064 
1065 	opts->op_type = CPERF_CIPHER_THEN_AUTH;
1066 
1067 	opts->silent = 0;
1068 	opts->test_file = NULL;
1069 	opts->test_name = NULL;
1070 	opts->sessionless = 0;
1071 	opts->out_of_place = 0;
1072 	opts->csv = 0;
1073 
1074 	opts->cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC;
1075 	opts->cipher_op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
1076 	opts->cipher_key_sz = 16;
1077 	opts->cipher_iv_sz = 16;
1078 
1079 	opts->auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
1080 	opts->auth_op = RTE_CRYPTO_AUTH_OP_GENERATE;
1081 
1082 	opts->auth_key_sz = 64;
1083 	opts->auth_iv_sz = 0;
1084 
1085 	opts->aead_key_sz = 0;
1086 	opts->aead_iv_sz = 0;
1087 	opts->aead_aad_sz = 0;
1088 
1089 	opts->digest_sz = 12;
1090 
1091 	opts->pmdcc_delay = 0;
1092 #ifdef RTE_LIB_SECURITY
1093 	opts->pdcp_sn_sz = 12;
1094 	opts->pdcp_domain = RTE_SECURITY_PDCP_MODE_CONTROL;
1095 	opts->pdcp_ses_hfn_en = 0;
1096 	opts->pdcp_sdap = 0;
1097 	opts->docsis_hdr_sz = 17;
1098 #endif
1099 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
1100 
1101 	opts->secp256r1_data = &secp256r1_perf_data;
1102 	opts->sm2_data = &sm2_perf_data;
1103 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1104 }
1105 
1106 static int
1107 cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)
1108 {
1109 	struct long_opt_parser parsermap[] = {
1110 		{ CPERF_PTEST_TYPE,	parse_cperf_test_type },
1111 		{ CPERF_MODEX_LEN,	parse_modex_len },
1112 		{ CPERF_SILENT,		parse_silent },
1113 		{ CPERF_POOL_SIZE,	parse_pool_sz },
1114 		{ CPERF_TOTAL_OPS,	parse_total_ops },
1115 		{ CPERF_BURST_SIZE,	parse_burst_sz },
1116 		{ CPERF_BUFFER_SIZE,	parse_buffer_sz },
1117 		{ CPERF_SEGMENT_SIZE,	parse_segment_sz },
1118 		{ CPERF_DESC_NB,	parse_desc_nb },
1119 		{ CPERF_LOW_PRIO_QP_MASK,	parse_low_prio_qp_mask },
1120 		{ CPERF_DEVTYPE,	parse_device_type },
1121 		{ CPERF_OPTYPE,		parse_op_type },
1122 		{ CPERF_SESSIONLESS,	parse_sessionless },
1123 		{ CPERF_SHARED_SESSION,	parse_shared_session },
1124 		{ CPERF_OUT_OF_PLACE,	parse_out_of_place },
1125 		{ CPERF_IMIX,		parse_imix },
1126 		{ CPERF_TEST_FILE,	parse_test_file },
1127 		{ CPERF_TEST_NAME,	parse_test_name },
1128 		{ CPERF_CIPHER_ALGO,	parse_cipher_algo },
1129 		{ CPERF_CIPHER_OP,	parse_cipher_op },
1130 		{ CPERF_CIPHER_KEY_SZ,	parse_cipher_key_sz },
1131 		{ CPERF_CIPHER_IV_SZ,	parse_cipher_iv_sz },
1132 		{ CPERF_AUTH_ALGO,	parse_auth_algo },
1133 		{ CPERF_AUTH_OP,	parse_auth_op },
1134 		{ CPERF_AUTH_KEY_SZ,	parse_auth_key_sz },
1135 		{ CPERF_AUTH_IV_SZ,	parse_auth_iv_sz },
1136 		{ CPERF_AEAD_ALGO,	parse_aead_algo },
1137 		{ CPERF_AEAD_OP,	parse_aead_op },
1138 		{ CPERF_AEAD_KEY_SZ,	parse_aead_key_sz },
1139 		{ CPERF_AEAD_IV_SZ,	parse_aead_iv_sz },
1140 		{ CPERF_AEAD_AAD_SZ,	parse_aead_aad_sz },
1141 		{ CPERF_DIGEST_SZ,	parse_digest_sz },
1142 		{ CPERF_ASYM_OP,	parse_asym_op },
1143 #ifdef RTE_LIB_SECURITY
1144 		{ CPERF_PDCP_SN_SZ,	parse_pdcp_sn_sz },
1145 		{ CPERF_PDCP_DOMAIN,	parse_pdcp_domain },
1146 		{ CPERF_PDCP_SES_HFN_EN,	parse_pdcp_ses_hfn_en },
1147 		{ CPERF_ENABLE_SDAP,	parse_enable_sdap },
1148 		{ CPERF_DOCSIS_HDR_SZ,	parse_docsis_hdr_sz },
1149 		{ CPERF_TLS_VERSION,	parse_tls_version },
1150 #endif
1151 		{ CPERF_CSV,		parse_csv_friendly},
1152 		{ CPERF_PMDCC_DELAY_MS,	parse_pmd_cyclecount_delay_ms},
1153 	};
1154 	unsigned int i;
1155 
1156 	for (i = 0; i < RTE_DIM(parsermap); i++) {
1157 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
1158 				strlen(lgopts[opt_idx].name)) == 0)
1159 			return parsermap[i].parser_fn(opts, optarg);
1160 	}
1161 
1162 	return -EINVAL;
1163 }
1164 
1165 int
1166 cperf_options_parse(struct cperf_options *options, int argc, char **argv)
1167 {
1168 	int opt, retval, opt_idx;
1169 
1170 	while ((opt = getopt_long(argc, argv, "h", lgopts, &opt_idx)) != EOF) {
1171 		switch (opt) {
1172 		case 'h':
1173 			usage(argv[0]);
1174 			exit(EXIT_SUCCESS);
1175 			break;
1176 		/* long options */
1177 		case 0:
1178 			retval = cperf_opts_parse_long(opt_idx, options);
1179 			if (retval != 0)
1180 				return retval;
1181 
1182 			break;
1183 
1184 		default:
1185 			usage(argv[0]);
1186 			return -EINVAL;
1187 		}
1188 	}
1189 
1190 	return 0;
1191 }
1192 
1193 static int
1194 check_cipher_buffer_length(struct cperf_options *options)
1195 {
1196 	uint32_t buffer_size, buffer_size_idx = 0;
1197 
1198 	if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1199 			options->cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) {
1200 		if (options->inc_buffer_size != 0)
1201 			buffer_size = options->min_buffer_size;
1202 		else
1203 			buffer_size = options->buffer_size_list[0];
1204 
1205 		if ((options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE) &&
1206 				(options->op_type == CPERF_AUTH_THEN_CIPHER))
1207 			buffer_size += options->digest_sz;
1208 
1209 		while (buffer_size <= options->max_buffer_size) {
1210 			if ((buffer_size % AES_BLOCK_SIZE) != 0) {
1211 				RTE_LOG(ERR, USER1, "Some of the buffer sizes are "
1212 					"not suitable for the algorithm selected\n");
1213 				return -EINVAL;
1214 			}
1215 
1216 			if (options->inc_buffer_size != 0)
1217 				buffer_size += options->inc_buffer_size;
1218 			else {
1219 				if (++buffer_size_idx == options->buffer_size_count)
1220 					break;
1221 				buffer_size = options->buffer_size_list[buffer_size_idx];
1222 			}
1223 
1224 		}
1225 	}
1226 
1227 	if (options->cipher_algo == RTE_CRYPTO_CIPHER_DES_CBC ||
1228 			options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_CBC ||
1229 			options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_ECB) {
1230 		if (options->inc_buffer_size != 0)
1231 			buffer_size = options->min_buffer_size;
1232 		else
1233 			buffer_size = options->buffer_size_list[0];
1234 
1235 		if ((options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE) &&
1236 				(options->op_type == CPERF_AUTH_THEN_CIPHER))
1237 			buffer_size += options->digest_sz;
1238 
1239 		while (buffer_size <= options->max_buffer_size) {
1240 			if ((buffer_size % DES_BLOCK_SIZE) != 0) {
1241 				RTE_LOG(ERR, USER1, "Some of the buffer sizes are "
1242 					"not suitable for the algorithm selected\n");
1243 				return -EINVAL;
1244 			}
1245 
1246 			if (options->inc_buffer_size != 0)
1247 				buffer_size += options->inc_buffer_size;
1248 			else {
1249 				if (++buffer_size_idx == options->buffer_size_count)
1250 					break;
1251 				buffer_size = options->buffer_size_list[buffer_size_idx];
1252 			}
1253 
1254 		}
1255 	}
1256 
1257 	return 0;
1258 }
1259 
1260 #ifdef RTE_LIB_SECURITY
1261 static int
1262 check_docsis_buffer_length(struct cperf_options *options)
1263 {
1264 	uint32_t buffer_size, buffer_size_idx = 0;
1265 
1266 	if (options->inc_buffer_size != 0)
1267 		buffer_size = options->min_buffer_size;
1268 	else
1269 		buffer_size = options->buffer_size_list[0];
1270 
1271 	while (buffer_size <= options->max_buffer_size) {
1272 		if (buffer_size < (uint32_t)(options->docsis_hdr_sz +
1273 				RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN)) {
1274 			RTE_LOG(ERR, USER1, "Some of the buffer sizes are not "
1275 				"valid for DOCSIS\n");
1276 			return -EINVAL;
1277 		}
1278 
1279 		if (options->inc_buffer_size != 0)
1280 			buffer_size += options->inc_buffer_size;
1281 		else {
1282 			if (++buffer_size_idx == options->buffer_size_count)
1283 				break;
1284 			buffer_size =
1285 				options->buffer_size_list[buffer_size_idx];
1286 		}
1287 	}
1288 
1289 	return 0;
1290 }
1291 #endif
1292 
1293 static bool
1294 is_valid_chained_op(struct cperf_options *options)
1295 {
1296 	if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1297 			options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
1298 		return true;
1299 
1300 	if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
1301 			options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
1302 		return true;
1303 
1304 	return false;
1305 }
1306 
1307 int
1308 cperf_options_check(struct cperf_options *options)
1309 {
1310 	int i;
1311 
1312 	if (options->op_type == CPERF_CIPHER_ONLY ||
1313 			options->op_type == CPERF_DOCSIS)
1314 		options->digest_sz = 0;
1315 
1316 	if (options->out_of_place &&
1317 			options->segment_sz <= options->max_buffer_size) {
1318 		RTE_LOG(ERR, USER1, "Out of place mode can only work "
1319 					"with non segmented buffers\n");
1320 		return -EINVAL;
1321 	}
1322 
1323 	/*
1324 	 * If segment size is not set, assume only one segment,
1325 	 * big enough to contain the largest buffer and the digest
1326 	 */
1327 	if (options->segment_sz == 0) {
1328 		options->segment_sz = options->max_buffer_size +
1329 				options->digest_sz;
1330 		/* In IPsec and TLS operation, packet length will be increased
1331 		 * by some bytes depend upon the algorithm, so increasing
1332 		 * the segment size by headroom to cover most of
1333 		 * the scenarios.
1334 		 */
1335 		if (options->op_type == CPERF_IPSEC || options->op_type == CPERF_TLS)
1336 			options->segment_sz += RTE_PKTMBUF_HEADROOM;
1337 	}
1338 
1339 	if (options->segment_sz < options->digest_sz) {
1340 		RTE_LOG(ERR, USER1,
1341 				"Segment size should be at least "
1342 				"the size of the digest\n");
1343 		return -EINVAL;
1344 	}
1345 
1346 	if ((options->imix_distribution_count != 0) &&
1347 			(options->imix_distribution_count !=
1348 				options->buffer_size_count)) {
1349 		RTE_LOG(ERR, USER1, "IMIX distribution must have the same "
1350 				"number of buffer sizes\n");
1351 		return -EINVAL;
1352 	}
1353 
1354 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1355 			options->test_file == NULL) {
1356 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1357 				" vectors.\n");
1358 		return -EINVAL;
1359 	}
1360 
1361 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1362 			options->op_type != CPERF_CIPHER_ONLY &&
1363 			options->test_name == NULL) {
1364 		RTE_LOG(ERR, USER1, "Define test name to get the correct digest"
1365 				" from the test vectors.\n");
1366 		return -EINVAL;
1367 	}
1368 
1369 	if (options->test_name != NULL && options->test_file == NULL) {
1370 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1371 				" vectors.\n");
1372 		return -EINVAL;
1373 	}
1374 
1375 	if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY &&
1376 			options->test_file == NULL) {
1377 		RTE_LOG(ERR, USER1, "Define path to the file with test"
1378 				" vectors.\n");
1379 		return -EINVAL;
1380 	}
1381 
1382 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1383 			(options->inc_buffer_size != 0 ||
1384 			options->buffer_size_count > 1)) {
1385 		RTE_LOG(ERR, USER1, "Only one buffer size is allowed when "
1386 				"using the verify test.\n");
1387 		return -EINVAL;
1388 	}
1389 
1390 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1391 			(options->inc_burst_size != 0 ||
1392 			options->burst_size_count > 1)) {
1393 		RTE_LOG(ERR, USER1, "Only one burst size is allowed when "
1394 				"using the verify test.\n");
1395 		return -EINVAL;
1396 	}
1397 
1398 	if (options->test == CPERF_TEST_TYPE_PMDCC &&
1399 			options->pool_sz < options->nb_descriptors) {
1400 		RTE_LOG(ERR, USER1, "For pmd cyclecount benchmarks, pool size "
1401 				"must be equal or greater than the number of "
1402 				"cryptodev descriptors.\n");
1403 		return -EINVAL;
1404 	}
1405 
1406 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
1407 			options->imix_distribution_count > 0) {
1408 		RTE_LOG(ERR, USER1, "IMIX is not allowed when "
1409 				"using the verify test.\n");
1410 		return -EINVAL;
1411 	}
1412 
1413 	if (options->op_type == CPERF_CIPHER_THEN_AUTH ||
1414 			options->op_type == CPERF_AUTH_THEN_CIPHER) {
1415 		if (!is_valid_chained_op(options)) {
1416 			RTE_LOG(ERR, USER1, "Invalid chained operation.\n");
1417 			return -EINVAL;
1418 		}
1419 	}
1420 
1421 	if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
1422 		if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1423 				options->auth_op !=
1424 				RTE_CRYPTO_AUTH_OP_GENERATE) {
1425 			RTE_LOG(ERR, USER1, "Option cipher then auth must use"
1426 					" options: encrypt and generate.\n");
1427 			return -EINVAL;
1428 		}
1429 	}
1430 
1431 	if (options->test == CPERF_TEST_TYPE_THROUGHPUT &&
1432 	    (options->aead_op == RTE_CRYPTO_AEAD_OP_DECRYPT ||
1433 	     options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) &&
1434 	    !options->out_of_place) {
1435 		RTE_LOG(ERR, USER1, "Only out-of-place is allowed in throughput decryption.\n");
1436 		return -EINVAL;
1437 	}
1438 
1439 	if (options->op_type == CPERF_CIPHER_ONLY ||
1440 			options->op_type == CPERF_CIPHER_THEN_AUTH ||
1441 			options->op_type == CPERF_AUTH_THEN_CIPHER) {
1442 		if (check_cipher_buffer_length(options) < 0)
1443 			return -EINVAL;
1444 	}
1445 
1446 	if (options->modex_len) {
1447 		if (options->op_type != CPERF_ASYM_MODEX) {
1448 			RTE_LOG(ERR, USER1, "Option modex len should be used only with "
1449 					" optype: modex.\n");
1450 			return -EINVAL;
1451 		}
1452 
1453 		for (i = 0; i < (int)RTE_DIM(modex_perf_data); i++) {
1454 			if (modex_perf_data[i].modulus.len ==
1455 			    options->modex_len) {
1456 				options->modex_data =
1457 					(struct cperf_modex_test_data
1458 						 *)&modex_perf_data[i];
1459 				break;
1460 			}
1461 		}
1462 		if (i == (int)RTE_DIM(modex_perf_data)) {
1463 			RTE_LOG(ERR, USER1,
1464 				"Option modex len: %d is not supported\n",
1465 				options->modex_len);
1466 			return -EINVAL;
1467 		}
1468 	}
1469 
1470 #ifdef RTE_LIB_SECURITY
1471 	if (options->op_type == CPERF_DOCSIS) {
1472 		if (check_docsis_buffer_length(options) < 0)
1473 			return -EINVAL;
1474 	}
1475 
1476 	if (options->op_type == CPERF_IPSEC || options->op_type == CPERF_TLS) {
1477 		if (options->aead_algo) {
1478 			if (options->aead_op == RTE_CRYPTO_AEAD_OP_ENCRYPT)
1479 				options->is_outbound = 1;
1480 			else
1481 				options->is_outbound = 0;
1482 		} else {
1483 			if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
1484 			    options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
1485 				options->is_outbound = 1;
1486 			else
1487 				options->is_outbound = 0;
1488 		}
1489 	}
1490 #endif
1491 
1492 	return 0;
1493 }
1494 
1495 void
1496 cperf_options_dump(struct cperf_options *opts)
1497 {
1498 	uint8_t size_idx;
1499 
1500 	printf("# Crypto Performance Application Options:\n");
1501 	printf("#\n");
1502 	printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]);
1503 	printf("#\n");
1504 	printf("# cperf operation type: %s\n", cperf_op_type_strs[opts->op_type]);
1505 	printf("#\n");
1506 	printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz);
1507 	printf("# total number of ops: %u\n", opts->total_ops);
1508 	if (opts->inc_buffer_size != 0) {
1509 		printf("# buffer size:\n");
1510 		printf("#\t min: %u\n", opts->min_buffer_size);
1511 		printf("#\t max: %u\n", opts->max_buffer_size);
1512 		printf("#\t inc: %u\n", opts->inc_buffer_size);
1513 	} else {
1514 		printf("# buffer sizes: ");
1515 		for (size_idx = 0; size_idx < opts->buffer_size_count; size_idx++)
1516 			printf("%u ", opts->buffer_size_list[size_idx]);
1517 		printf("\n");
1518 	}
1519 	if (opts->inc_burst_size != 0) {
1520 		printf("# burst size:\n");
1521 		printf("#\t min: %u\n", opts->min_burst_size);
1522 		printf("#\t max: %u\n", opts->max_burst_size);
1523 		printf("#\t inc: %u\n", opts->inc_burst_size);
1524 	} else {
1525 		printf("# burst sizes: ");
1526 		for (size_idx = 0; size_idx < opts->burst_size_count; size_idx++)
1527 			printf("%u ", opts->burst_size_list[size_idx]);
1528 		printf("\n");
1529 	}
1530 	printf("\n# segment size: %u\n", opts->segment_sz);
1531 	printf("#\n");
1532 	printf("# cryptodev type: %s\n", opts->device_type);
1533 	printf("#\n");
1534 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
1535 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
1536 	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
1537 		printf("# asym operation type: %s\n",
1538 				rte_crypto_asym_op_strings[opts->asym_op_type]);
1539 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
1540 	printf("# shared session: %s\n", opts->shared_session ? "yes" : "no");
1541 	printf("# out of place: %s\n", opts->out_of_place ? "yes" : "no");
1542 	if (opts->test == CPERF_TEST_TYPE_PMDCC)
1543 		printf("# inter-burst delay: %u ms\n", opts->pmdcc_delay);
1544 
1545 	printf("#\n");
1546 
1547 	if (opts->op_type == CPERF_AUTH_ONLY ||
1548 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
1549 			opts->op_type == CPERF_AUTH_THEN_CIPHER) {
1550 		printf("# auth algorithm: %s\n",
1551 			rte_cryptodev_get_auth_algo_string(opts->auth_algo));
1552 		printf("# auth operation: %s\n",
1553 			rte_crypto_auth_operation_strings[opts->auth_op]);
1554 		printf("# auth key size: %u\n", opts->auth_key_sz);
1555 		printf("# auth iv size: %u\n", opts->auth_iv_sz);
1556 		printf("# auth digest size: %u\n", opts->digest_sz);
1557 		printf("#\n");
1558 	}
1559 
1560 	if (opts->op_type == CPERF_CIPHER_ONLY ||
1561 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
1562 			opts->op_type == CPERF_AUTH_THEN_CIPHER) {
1563 		printf("# cipher algorithm: %s\n",
1564 			rte_cryptodev_get_cipher_algo_string(opts->cipher_algo));
1565 		printf("# cipher operation: %s\n",
1566 			rte_crypto_cipher_operation_strings[opts->cipher_op]);
1567 		printf("# cipher key size: %u\n", opts->cipher_key_sz);
1568 		printf("# cipher iv size: %u\n", opts->cipher_iv_sz);
1569 		printf("#\n");
1570 	}
1571 
1572 	if (opts->op_type == CPERF_AEAD) {
1573 		printf("# aead algorithm: %s\n",
1574 			rte_cryptodev_get_aead_algo_string(opts->aead_algo));
1575 		printf("# aead operation: %s\n",
1576 			rte_crypto_aead_operation_strings[opts->aead_op]);
1577 		printf("# aead key size: %u\n", opts->aead_key_sz);
1578 		printf("# aead iv size: %u\n", opts->aead_iv_sz);
1579 		printf("# aead digest size: %u\n", opts->digest_sz);
1580 		printf("# aead aad size: %u\n", opts->aead_aad_sz);
1581 		printf("#\n");
1582 	}
1583 
1584 #ifdef RTE_LIB_SECURITY
1585 	if (opts->op_type == CPERF_DOCSIS) {
1586 		printf("# docsis header size: %u\n", opts->docsis_hdr_sz);
1587 		printf("#\n");
1588 	}
1589 #endif
1590 }
1591