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