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