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