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