xref: /dpdk/app/test-crypto-perf/cperf_options_parsing.c (revision f6cefe253cc814a01575b1f1604afac8c81453ed)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <getopt.h>
34 #include <unistd.h>
35 
36 #include <rte_cryptodev.h>
37 #include <rte_malloc.h>
38 
39 #include "cperf_options.h"
40 
41 struct name_id_map {
42 	const char *name;
43 	uint32_t id;
44 };
45 
46 static int
47 get_str_key_id_mapping(struct name_id_map *map, unsigned int map_len,
48 		const char *str_key)
49 {
50 	unsigned int i;
51 
52 	for (i = 0; i < map_len; i++) {
53 
54 		if (strcmp(str_key, map[i].name) == 0)
55 			return map[i].id;
56 	}
57 
58 	return -1;
59 }
60 
61 static int
62 parse_cperf_test_type(struct cperf_options *opts, const char *arg)
63 {
64 	struct name_id_map cperftest_namemap[] = {
65 		{
66 			cperf_test_type_strs[CPERF_TEST_TYPE_THROUGHPUT],
67 			CPERF_TEST_TYPE_THROUGHPUT
68 		},
69 		{
70 			cperf_test_type_strs[CPERF_TEST_TYPE_VERIFY],
71 			CPERF_TEST_TYPE_VERIFY
72 		},
73 		{
74 			cperf_test_type_strs[CPERF_TEST_TYPE_LATENCY],
75 			CPERF_TEST_TYPE_LATENCY
76 		}
77 	};
78 
79 	int id = get_str_key_id_mapping(
80 			(struct name_id_map *)cperftest_namemap,
81 			RTE_DIM(cperftest_namemap), arg);
82 	if (id < 0) {
83 		RTE_LOG(ERR, USER1, "failed to parse test type");
84 		return -1;
85 	}
86 
87 	opts->test = (enum cperf_perf_test_type)id;
88 
89 	return 0;
90 }
91 
92 static int
93 parse_uint32_t(uint32_t *value, const char *arg)
94 {
95 	char *end = NULL;
96 	unsigned long n = strtoul(arg, &end, 10);
97 
98 	if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
99 		return -1;
100 
101 	if (n > UINT32_MAX)
102 		return -ERANGE;
103 
104 	*value = (uint32_t) n;
105 
106 	return 0;
107 }
108 
109 static int
110 parse_uint16_t(uint16_t *value, const char *arg)
111 {
112 	uint32_t val = 0;
113 	int ret = parse_uint32_t(&val, arg);
114 
115 	if (ret < 0)
116 		return ret;
117 
118 	if (val > UINT16_MAX)
119 		return -ERANGE;
120 
121 	*value = (uint16_t) val;
122 
123 	return 0;
124 }
125 
126 static int
127 parse_range(const char *arg, uint32_t *min, uint32_t *max, uint32_t *inc)
128 {
129 	char *token;
130 	uint32_t number;
131 
132 	char *copy_arg = strdup(arg);
133 
134 	if (copy_arg == NULL)
135 		return -1;
136 
137 	token = strtok(copy_arg, ":");
138 
139 	/* Parse minimum value */
140 	if (token != NULL) {
141 		number = strtoul(token, NULL, 10);
142 
143 		if (errno == EINVAL || errno == ERANGE ||
144 				number == 0)
145 			goto err_range;
146 
147 		*min = number;
148 	} else
149 		goto err_range;
150 
151 	token = strtok(NULL, ":");
152 
153 	/* Parse increment value */
154 	if (token != NULL) {
155 		number = strtoul(token, NULL, 10);
156 
157 		if (errno == EINVAL || errno == ERANGE ||
158 				number == 0)
159 			goto err_range;
160 
161 		*inc = number;
162 	} else
163 		goto err_range;
164 
165 	token = strtok(NULL, ":");
166 
167 	/* Parse maximum value */
168 	if (token != NULL) {
169 		number = strtoul(token, NULL, 10);
170 
171 		if (errno == EINVAL || errno == ERANGE ||
172 				number == 0 ||
173 				number < *min)
174 			goto err_range;
175 
176 		*max = number;
177 	} else
178 		goto err_range;
179 
180 	if (strtok(NULL, ":") != NULL)
181 		goto err_range;
182 
183 	free(copy_arg);
184 	return 0;
185 
186 err_range:
187 	free(copy_arg);
188 	return -1;
189 }
190 
191 static int
192 parse_list(const char *arg, uint32_t *list, uint32_t *min, uint32_t *max)
193 {
194 	char *token;
195 	uint32_t number;
196 	uint8_t count = 0;
197 
198 	char *copy_arg = strdup(arg);
199 
200 	if (copy_arg == NULL)
201 		return -1;
202 
203 	token = strtok(copy_arg, ",");
204 
205 	/* Parse first value */
206 	if (token != NULL) {
207 		number = strtoul(token, NULL, 10);
208 
209 		if (errno == EINVAL || errno == ERANGE ||
210 				number == 0)
211 			goto err_list;
212 
213 		list[count++] = number;
214 		*min = number;
215 		*max = number;
216 	} else
217 		goto err_list;
218 
219 	token = strtok(NULL, ",");
220 
221 	while (token != NULL) {
222 		if (count == MAX_LIST) {
223 			RTE_LOG(WARNING, USER1, "Using only the first %u sizes\n",
224 					MAX_LIST);
225 			break;
226 		}
227 
228 		number = strtoul(token, NULL, 10);
229 
230 		if (errno == EINVAL || errno == ERANGE ||
231 				number == 0)
232 			goto err_list;
233 
234 		list[count++] = number;
235 
236 		if (number < *min)
237 			*min = number;
238 		if (number > *max)
239 			*max = number;
240 
241 		token = strtok(NULL, ",");
242 	}
243 
244 	free(copy_arg);
245 	return count;
246 
247 err_list:
248 	free(copy_arg);
249 	return -1;
250 }
251 
252 static int
253 parse_total_ops(struct cperf_options *opts, const char *arg)
254 {
255 	int ret = parse_uint32_t(&opts->total_ops, arg);
256 
257 	if (ret)
258 		RTE_LOG(ERR, USER1, "failed to parse total operations count\n");
259 
260 	if (opts->total_ops == 0) {
261 		RTE_LOG(ERR, USER1,
262 				"invalid total operations count number specified\n");
263 		return -1;
264 	}
265 
266 	return ret;
267 }
268 
269 static int
270 parse_pool_sz(struct cperf_options *opts, const char *arg)
271 {
272 	int ret =  parse_uint32_t(&opts->pool_sz, arg);
273 
274 	if (ret)
275 		RTE_LOG(ERR, USER1, "failed to parse pool size");
276 	return ret;
277 }
278 
279 static int
280 parse_burst_sz(struct cperf_options *opts, const char *arg)
281 {
282 	int ret;
283 
284 	/* Try parsing the argument as a range, if it fails, parse it as a list */
285 	if (parse_range(arg, &opts->min_burst_size, &opts->max_burst_size,
286 			&opts->inc_burst_size) < 0) {
287 		ret = parse_list(arg, opts->burst_size_list,
288 					&opts->min_burst_size,
289 					&opts->max_burst_size);
290 		if (ret < 0) {
291 			RTE_LOG(ERR, USER1, "failed to parse burst size/s\n");
292 			return -1;
293 		}
294 		opts->burst_size_count = ret;
295 	}
296 
297 	return 0;
298 }
299 
300 static int
301 parse_buffer_sz(struct cperf_options *opts, const char *arg)
302 {
303 	int ret;
304 
305 	/* Try parsing the argument as a range, if it fails, parse it as a list */
306 	if (parse_range(arg, &opts->min_buffer_size, &opts->max_buffer_size,
307 			&opts->inc_buffer_size) < 0) {
308 		ret = parse_list(arg, opts->buffer_size_list,
309 					&opts->min_buffer_size,
310 					&opts->max_buffer_size);
311 		if (ret < 0) {
312 			RTE_LOG(ERR, USER1, "failed to parse burst size/s\n");
313 			return -1;
314 		}
315 		opts->buffer_size_count = ret;
316 	}
317 
318 	return 0;
319 }
320 
321 static int
322 parse_segments_nb(struct cperf_options *opts, const char *arg)
323 {
324 	int ret = parse_uint32_t(&opts->segments_nb, arg);
325 
326 	if (ret) {
327 		RTE_LOG(ERR, USER1, "failed to parse segments number\n");
328 		return -1;
329 	}
330 
331 	if ((opts->segments_nb == 0) || (opts->segments_nb > 255)) {
332 		RTE_LOG(ERR, USER1, "invalid segments number specified\n");
333 		return -1;
334 	}
335 
336 	return 0;
337 }
338 
339 static int
340 parse_device_type(struct cperf_options *opts, const char *arg)
341 {
342 	if (strlen(arg) > (sizeof(opts->device_type) - 1))
343 		return -1;
344 
345 	strncpy(opts->device_type, arg, sizeof(opts->device_type) - 1);
346 	*(opts->device_type + sizeof(opts->device_type) - 1) = '\0';
347 
348 	return 0;
349 }
350 
351 static int
352 parse_op_type(struct cperf_options *opts, const char *arg)
353 {
354 	struct name_id_map optype_namemap[] = {
355 		{
356 			cperf_op_type_strs[CPERF_CIPHER_ONLY],
357 			CPERF_CIPHER_ONLY
358 		},
359 		{
360 			cperf_op_type_strs[CPERF_AUTH_ONLY],
361 			CPERF_AUTH_ONLY
362 		},
363 		{
364 			cperf_op_type_strs[CPERF_CIPHER_THEN_AUTH],
365 			CPERF_CIPHER_THEN_AUTH
366 		},
367 		{
368 			cperf_op_type_strs[CPERF_AUTH_THEN_CIPHER],
369 			CPERF_AUTH_THEN_CIPHER
370 		},
371 		{
372 			cperf_op_type_strs[CPERF_AEAD],
373 			CPERF_AEAD
374 		}
375 	};
376 
377 	int id = get_str_key_id_mapping(optype_namemap,
378 			RTE_DIM(optype_namemap), arg);
379 	if (id < 0) {
380 		RTE_LOG(ERR, USER1, "invalid opt type specified\n");
381 		return -1;
382 	}
383 
384 	opts->op_type = (enum cperf_op_type)id;
385 
386 	return 0;
387 }
388 
389 static int
390 parse_sessionless(struct cperf_options *opts,
391 		const char *arg __rte_unused)
392 {
393 	opts->sessionless = 1;
394 	return 0;
395 }
396 
397 static int
398 parse_out_of_place(struct cperf_options *opts,
399 		const char *arg __rte_unused)
400 {
401 	opts->out_of_place = 1;
402 	return 0;
403 }
404 
405 static int
406 parse_test_file(struct cperf_options *opts,
407 		const char *arg)
408 {
409 	opts->test_file = strdup(arg);
410 	if (access(opts->test_file, F_OK) != -1)
411 		return 0;
412 	RTE_LOG(ERR, USER1, "Test vector file doesn't exist\n");
413 
414 	return -1;
415 }
416 
417 static int
418 parse_test_name(struct cperf_options *opts,
419 		const char *arg)
420 {
421 	char *test_name = (char *) rte_zmalloc(NULL,
422 		sizeof(char) * (strlen(arg) + 3), 0);
423 	snprintf(test_name, strlen(arg) + 3, "[%s]", arg);
424 	opts->test_name = test_name;
425 
426 	return 0;
427 }
428 
429 static int
430 parse_silent(struct cperf_options *opts,
431 		const char *arg __rte_unused)
432 {
433 	opts->silent = 1;
434 
435 	return 0;
436 }
437 
438 static int
439 parse_cipher_algo(struct cperf_options *opts, const char *arg)
440 {
441 
442 	enum rte_crypto_cipher_algorithm cipher_algo;
443 
444 	if (rte_cryptodev_get_cipher_algo_enum(&cipher_algo, arg) < 0) {
445 		RTE_LOG(ERR, USER1, "Invalid cipher algorithm specified\n");
446 		return -1;
447 	}
448 
449 	opts->cipher_algo = cipher_algo;
450 
451 	return 0;
452 }
453 
454 static int
455 parse_cipher_op(struct cperf_options *opts, const char *arg)
456 {
457 	struct name_id_map cipher_op_namemap[] = {
458 		{
459 			rte_crypto_cipher_operation_strings
460 			[RTE_CRYPTO_CIPHER_OP_ENCRYPT],
461 			RTE_CRYPTO_CIPHER_OP_ENCRYPT },
462 		{
463 			rte_crypto_cipher_operation_strings
464 			[RTE_CRYPTO_CIPHER_OP_DECRYPT],
465 			RTE_CRYPTO_CIPHER_OP_DECRYPT
466 		}
467 	};
468 
469 	int id = get_str_key_id_mapping(cipher_op_namemap,
470 			RTE_DIM(cipher_op_namemap), arg);
471 	if (id < 0) {
472 		RTE_LOG(ERR, USER1, "Invalid cipher operation specified\n");
473 		return -1;
474 	}
475 
476 	opts->cipher_op = (enum rte_crypto_cipher_operation)id;
477 
478 	return 0;
479 }
480 
481 static int
482 parse_cipher_key_sz(struct cperf_options *opts, const char *arg)
483 {
484 	return parse_uint16_t(&opts->cipher_key_sz, arg);
485 }
486 
487 static int
488 parse_cipher_iv_sz(struct cperf_options *opts, const char *arg)
489 {
490 	return parse_uint16_t(&opts->cipher_iv_sz, arg);
491 }
492 
493 static int
494 parse_auth_algo(struct cperf_options *opts, const char *arg)
495 {
496 	enum rte_crypto_auth_algorithm auth_algo;
497 
498 	if (rte_cryptodev_get_auth_algo_enum(&auth_algo, arg) < 0) {
499 		RTE_LOG(ERR, USER1, "Invalid authentication algorithm specified\n");
500 		return -1;
501 	}
502 
503 	opts->auth_algo = auth_algo;
504 
505 	return 0;
506 }
507 
508 static int
509 parse_auth_op(struct cperf_options *opts, const char *arg)
510 {
511 	struct name_id_map auth_op_namemap[] = {
512 		{
513 			rte_crypto_auth_operation_strings
514 			[RTE_CRYPTO_AUTH_OP_GENERATE],
515 			RTE_CRYPTO_AUTH_OP_GENERATE },
516 		{
517 			rte_crypto_auth_operation_strings
518 			[RTE_CRYPTO_AUTH_OP_VERIFY],
519 			RTE_CRYPTO_AUTH_OP_VERIFY
520 		}
521 	};
522 
523 	int id = get_str_key_id_mapping(auth_op_namemap,
524 			RTE_DIM(auth_op_namemap), arg);
525 	if (id < 0) {
526 		RTE_LOG(ERR, USER1, "invalid authentication operation specified"
527 				"\n");
528 		return -1;
529 	}
530 
531 	opts->auth_op = (enum rte_crypto_auth_operation)id;
532 
533 	return 0;
534 }
535 
536 static int
537 parse_auth_key_sz(struct cperf_options *opts, const char *arg)
538 {
539 	return parse_uint16_t(&opts->auth_key_sz, arg);
540 }
541 
542 static int
543 parse_auth_digest_sz(struct cperf_options *opts, const char *arg)
544 {
545 	return parse_uint16_t(&opts->auth_digest_sz, arg);
546 }
547 
548 static int
549 parse_auth_aad_sz(struct cperf_options *opts, const char *arg)
550 {
551 	return parse_uint16_t(&opts->auth_aad_sz, arg);
552 }
553 
554 static int
555 parse_csv_friendly(struct cperf_options *opts, const char *arg __rte_unused)
556 {
557 	opts->csv = 1;
558 	opts->silent = 1;
559 	return 0;
560 }
561 
562 typedef int (*option_parser_t)(struct cperf_options *opts,
563 		const char *arg);
564 
565 struct long_opt_parser {
566 	const char *lgopt_name;
567 	option_parser_t parser_fn;
568 
569 };
570 
571 static struct option lgopts[] = {
572 
573 	{ CPERF_PTEST_TYPE, required_argument, 0, 0 },
574 
575 	{ CPERF_POOL_SIZE, required_argument, 0, 0 },
576 	{ CPERF_TOTAL_OPS, required_argument, 0, 0 },
577 	{ CPERF_BURST_SIZE, required_argument, 0, 0 },
578 	{ CPERF_BUFFER_SIZE, required_argument, 0, 0 },
579 	{ CPERF_SEGMENTS_NB, required_argument, 0, 0 },
580 
581 	{ CPERF_DEVTYPE, required_argument, 0, 0 },
582 	{ CPERF_OPTYPE, required_argument, 0, 0 },
583 
584 	{ CPERF_SILENT, no_argument, 0, 0 },
585 	{ CPERF_SESSIONLESS, no_argument, 0, 0 },
586 	{ CPERF_OUT_OF_PLACE, no_argument, 0, 0 },
587 	{ CPERF_TEST_FILE, required_argument, 0, 0 },
588 	{ CPERF_TEST_NAME, required_argument, 0, 0 },
589 
590 	{ CPERF_CIPHER_ALGO, required_argument, 0, 0 },
591 	{ CPERF_CIPHER_OP, required_argument, 0, 0 },
592 
593 	{ CPERF_CIPHER_KEY_SZ, required_argument, 0, 0 },
594 	{ CPERF_CIPHER_IV_SZ, required_argument, 0, 0 },
595 
596 	{ CPERF_AUTH_ALGO, required_argument, 0, 0 },
597 	{ CPERF_AUTH_OP, required_argument, 0, 0 },
598 
599 	{ CPERF_AUTH_KEY_SZ, required_argument, 0, 0 },
600 	{ CPERF_AUTH_DIGEST_SZ, required_argument, 0, 0 },
601 	{ CPERF_AUTH_AAD_SZ, required_argument, 0, 0 },
602 	{ CPERF_CSV, no_argument, 0, 0},
603 
604 	{ NULL, 0, 0, 0 }
605 };
606 
607 void
608 cperf_options_default(struct cperf_options *opts)
609 {
610 	opts->test = CPERF_TEST_TYPE_THROUGHPUT;
611 
612 	opts->pool_sz = 8192;
613 	opts->total_ops = 10000000;
614 
615 	opts->buffer_size_list[0] = 64;
616 	opts->buffer_size_count = 1;
617 	opts->max_buffer_size = 64;
618 	opts->min_buffer_size = 64;
619 	opts->inc_buffer_size = 0;
620 
621 	opts->burst_size_list[0] = 32;
622 	opts->burst_size_count = 1;
623 	opts->max_burst_size = 32;
624 	opts->min_burst_size = 32;
625 	opts->inc_burst_size = 0;
626 
627 	opts->segments_nb = 1;
628 
629 	strncpy(opts->device_type, "crypto_aesni_mb",
630 			sizeof(opts->device_type));
631 
632 	opts->op_type = CPERF_CIPHER_THEN_AUTH;
633 
634 	opts->silent = 0;
635 	opts->test_file = NULL;
636 	opts->test_name = NULL;
637 	opts->sessionless = 0;
638 	opts->out_of_place = 0;
639 	opts->csv = 0;
640 
641 	opts->cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC;
642 	opts->cipher_op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
643 	opts->cipher_key_sz = 16;
644 	opts->cipher_iv_sz = 16;
645 
646 	opts->auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
647 	opts->auth_op = RTE_CRYPTO_AUTH_OP_GENERATE;
648 
649 	opts->auth_key_sz = 64;
650 	opts->auth_digest_sz = 12;
651 	opts->auth_aad_sz = 0;
652 }
653 
654 static int
655 cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)
656 {
657 	struct long_opt_parser parsermap[] = {
658 		{ CPERF_PTEST_TYPE,	parse_cperf_test_type },
659 		{ CPERF_SILENT,		parse_silent },
660 		{ CPERF_POOL_SIZE,	parse_pool_sz },
661 		{ CPERF_TOTAL_OPS,	parse_total_ops },
662 		{ CPERF_BURST_SIZE,	parse_burst_sz },
663 		{ CPERF_BUFFER_SIZE,	parse_buffer_sz },
664 		{ CPERF_SEGMENTS_NB,	parse_segments_nb },
665 		{ CPERF_DEVTYPE,	parse_device_type },
666 		{ CPERF_OPTYPE,		parse_op_type },
667 		{ CPERF_SESSIONLESS,	parse_sessionless },
668 		{ CPERF_OUT_OF_PLACE,	parse_out_of_place },
669 		{ CPERF_TEST_FILE,	parse_test_file },
670 		{ CPERF_TEST_NAME,	parse_test_name },
671 		{ CPERF_CIPHER_ALGO,	parse_cipher_algo },
672 		{ CPERF_CIPHER_OP,	parse_cipher_op },
673 		{ CPERF_CIPHER_KEY_SZ,	parse_cipher_key_sz },
674 		{ CPERF_CIPHER_IV_SZ,	parse_cipher_iv_sz },
675 		{ CPERF_AUTH_ALGO,	parse_auth_algo },
676 		{ CPERF_AUTH_OP,	parse_auth_op },
677 		{ CPERF_AUTH_KEY_SZ,	parse_auth_key_sz },
678 		{ CPERF_AUTH_DIGEST_SZ,	parse_auth_digest_sz },
679 		{ CPERF_AUTH_AAD_SZ,	parse_auth_aad_sz },
680 		{ CPERF_CSV,	parse_csv_friendly},
681 	};
682 	unsigned int i;
683 
684 	for (i = 0; i < RTE_DIM(parsermap); i++) {
685 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
686 				strlen(lgopts[opt_idx].name)) == 0)
687 			return parsermap[i].parser_fn(opts, optarg);
688 	}
689 
690 	return -EINVAL;
691 }
692 
693 int
694 cperf_options_parse(struct cperf_options *options, int argc, char **argv)
695 {
696 	int opt, retval, opt_idx;
697 
698 	while ((opt = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) {
699 		switch (opt) {
700 		/* long options */
701 		case 0:
702 
703 			retval = cperf_opts_parse_long(opt_idx, options);
704 			if (retval != 0)
705 				return retval;
706 
707 			break;
708 
709 		default:
710 			return -EINVAL;
711 		}
712 	}
713 
714 	return 0;
715 }
716 
717 int
718 cperf_options_check(struct cperf_options *options)
719 {
720 	if (options->segments_nb > options->min_buffer_size) {
721 		RTE_LOG(ERR, USER1,
722 				"Segments number greater than buffer size.\n");
723 		return -EINVAL;
724 	}
725 
726 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
727 			options->test_file == NULL) {
728 		RTE_LOG(ERR, USER1, "Define path to the file with test"
729 				" vectors.\n");
730 		return -EINVAL;
731 	}
732 
733 	if (options->test_name != NULL && options->test_file == NULL) {
734 		RTE_LOG(ERR, USER1, "Define path to the file with test"
735 				" vectors.\n");
736 		return -EINVAL;
737 	}
738 
739 	if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY &&
740 			options->test_file == NULL) {
741 		RTE_LOG(ERR, USER1, "Define path to the file with test"
742 				" vectors.\n");
743 		return -EINVAL;
744 	}
745 
746 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
747 			options->total_ops > options->pool_sz) {
748 		RTE_LOG(ERR, USER1, "Total number of ops must be less than or"
749 				" equal to the pool size.\n");
750 		return -EINVAL;
751 	}
752 
753 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
754 			(options->inc_buffer_size != 0 ||
755 			options->buffer_size_count > 1)) {
756 		RTE_LOG(ERR, USER1, "Only one buffer size is allowed when "
757 				"using the verify test.\n");
758 		return -EINVAL;
759 	}
760 
761 	if (options->test == CPERF_TEST_TYPE_VERIFY &&
762 			(options->inc_burst_size != 0 ||
763 			options->burst_size_count > 1)) {
764 		RTE_LOG(ERR, USER1, "Only one burst size is allowed when "
765 				"using the verify test.\n");
766 		return -EINVAL;
767 	}
768 
769 	if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
770 		if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
771 				options->auth_op !=
772 				RTE_CRYPTO_AUTH_OP_GENERATE) {
773 			RTE_LOG(ERR, USER1, "Option cipher then auth must use"
774 					" options: encrypt and generate.\n");
775 			return -EINVAL;
776 		}
777 	} else if (options->op_type == CPERF_AUTH_THEN_CIPHER) {
778 		if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_DECRYPT &&
779 				options->auth_op !=
780 				RTE_CRYPTO_AUTH_OP_VERIFY) {
781 			RTE_LOG(ERR, USER1, "Option auth then cipher must use"
782 					" options: decrypt and verify.\n");
783 			return -EINVAL;
784 		}
785 	} else if (options->op_type == CPERF_AEAD) {
786 		if (!(options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
787 				options->auth_op ==
788 				RTE_CRYPTO_AUTH_OP_GENERATE) &&
789 				!(options->cipher_op ==
790 				RTE_CRYPTO_CIPHER_OP_DECRYPT &&
791 				options->auth_op ==
792 				RTE_CRYPTO_AUTH_OP_VERIFY)) {
793 			RTE_LOG(ERR, USER1, "Use together options: encrypt and"
794 					" generate or decrypt and verify.\n");
795 			return -EINVAL;
796 		}
797 	}
798 
799 	if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM ||
800 			options->cipher_algo == RTE_CRYPTO_CIPHER_AES_CCM ||
801 			options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM ||
802 			options->auth_algo == RTE_CRYPTO_AUTH_AES_CCM ||
803 			options->auth_algo == RTE_CRYPTO_AUTH_AES_GMAC) {
804 		if (options->op_type != CPERF_AEAD) {
805 			RTE_LOG(ERR, USER1, "Use --optype aead\n");
806 			return -EINVAL;
807 		}
808 	}
809 
810 	return 0;
811 }
812 
813 void
814 cperf_options_dump(struct cperf_options *opts)
815 {
816 	uint8_t size_idx;
817 
818 	printf("# Crypto Performance Application Options:\n");
819 	printf("#\n");
820 	printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]);
821 	printf("#\n");
822 	printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz);
823 	printf("# total number of ops: %u\n", opts->total_ops);
824 	if (opts->inc_buffer_size != 0) {
825 		printf("# buffer size:\n");
826 		printf("#\t min: %u\n", opts->min_buffer_size);
827 		printf("#\t max: %u\n", opts->max_buffer_size);
828 		printf("#\t inc: %u\n", opts->inc_buffer_size);
829 	} else {
830 		printf("# buffer sizes: ");
831 		for (size_idx = 0; size_idx < opts->buffer_size_count; size_idx++)
832 			printf("%u ", opts->buffer_size_list[size_idx]);
833 		printf("\n");
834 	}
835 	if (opts->inc_burst_size != 0) {
836 		printf("# burst size:\n");
837 		printf("#\t min: %u\n", opts->min_burst_size);
838 		printf("#\t max: %u\n", opts->max_burst_size);
839 		printf("#\t inc: %u\n", opts->inc_burst_size);
840 	} else {
841 		printf("# burst sizes: ");
842 		for (size_idx = 0; size_idx < opts->burst_size_count; size_idx++)
843 			printf("%u ", opts->burst_size_list[size_idx]);
844 		printf("\n");
845 	}
846 	printf("\n# segments per buffer: %u\n", opts->segments_nb);
847 	printf("#\n");
848 	printf("# cryptodev type: %s\n", opts->device_type);
849 	printf("#\n");
850 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
851 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
852 	printf("# out of place: %s\n", opts->out_of_place ? "yes" : "no");
853 
854 	printf("#\n");
855 
856 	if (opts->op_type == CPERF_AUTH_ONLY ||
857 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
858 			opts->op_type == CPERF_AUTH_THEN_CIPHER ||
859 			opts->op_type == CPERF_AEAD) {
860 		printf("# auth algorithm: %s\n",
861 			rte_crypto_auth_algorithm_strings[opts->auth_algo]);
862 		printf("# auth operation: %s\n",
863 			rte_crypto_auth_operation_strings[opts->auth_op]);
864 		printf("# auth key size: %u\n", opts->auth_key_sz);
865 		printf("# auth digest size: %u\n", opts->auth_digest_sz);
866 		printf("# auth aad size: %u\n", opts->auth_aad_sz);
867 		printf("#\n");
868 	}
869 
870 	if (opts->op_type == CPERF_CIPHER_ONLY ||
871 			opts->op_type == CPERF_CIPHER_THEN_AUTH ||
872 			opts->op_type == CPERF_AUTH_THEN_CIPHER ||
873 			opts->op_type == CPERF_AEAD) {
874 		printf("# cipher algorithm: %s\n",
875 			rte_crypto_cipher_algorithm_strings[opts->cipher_algo]);
876 		printf("# cipher operation: %s\n",
877 			rte_crypto_cipher_operation_strings[opts->cipher_op]);
878 		printf("# cipher key size: %u\n", opts->cipher_key_sz);
879 		printf("# cipher iv size: %u\n", opts->cipher_iv_sz);
880 		printf("#\n");
881 	}
882 }
883