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_digest_sz(struct cperf_options *opts, const char *arg) 547 { 548 return parse_uint16_t(&opts->digest_sz, arg); 549 } 550 551 static int 552 parse_auth_iv_sz(struct cperf_options *opts, const char *arg) 553 { 554 return parse_uint16_t(&opts->auth_iv_sz, arg); 555 } 556 557 static int 558 parse_aead_algo(struct cperf_options *opts, const char *arg) 559 { 560 enum rte_crypto_aead_algorithm aead_algo; 561 562 if (rte_cryptodev_get_aead_algo_enum(&aead_algo, arg) < 0) { 563 RTE_LOG(ERR, USER1, "Invalid AEAD algorithm specified\n"); 564 return -1; 565 } 566 567 opts->aead_algo = aead_algo; 568 569 return 0; 570 } 571 572 static int 573 parse_aead_op(struct cperf_options *opts, const char *arg) 574 { 575 struct name_id_map aead_op_namemap[] = { 576 { 577 rte_crypto_aead_operation_strings 578 [RTE_CRYPTO_AEAD_OP_ENCRYPT], 579 RTE_CRYPTO_AEAD_OP_ENCRYPT }, 580 { 581 rte_crypto_aead_operation_strings 582 [RTE_CRYPTO_AEAD_OP_DECRYPT], 583 RTE_CRYPTO_AEAD_OP_DECRYPT 584 } 585 }; 586 587 int id = get_str_key_id_mapping(aead_op_namemap, 588 RTE_DIM(aead_op_namemap), arg); 589 if (id < 0) { 590 RTE_LOG(ERR, USER1, "invalid AEAD operation specified" 591 "\n"); 592 return -1; 593 } 594 595 opts->aead_op = (enum rte_crypto_aead_operation)id; 596 597 return 0; 598 } 599 600 static int 601 parse_aead_key_sz(struct cperf_options *opts, const char *arg) 602 { 603 return parse_uint16_t(&opts->aead_key_sz, arg); 604 } 605 606 static int 607 parse_aead_iv_sz(struct cperf_options *opts, const char *arg) 608 { 609 return parse_uint16_t(&opts->aead_iv_sz, arg); 610 } 611 612 static int 613 parse_aead_aad_sz(struct cperf_options *opts, const char *arg) 614 { 615 return parse_uint16_t(&opts->aead_aad_sz, arg); 616 } 617 618 static int 619 parse_csv_friendly(struct cperf_options *opts, const char *arg __rte_unused) 620 { 621 opts->csv = 1; 622 opts->silent = 1; 623 return 0; 624 } 625 626 typedef int (*option_parser_t)(struct cperf_options *opts, 627 const char *arg); 628 629 struct long_opt_parser { 630 const char *lgopt_name; 631 option_parser_t parser_fn; 632 633 }; 634 635 static struct option lgopts[] = { 636 637 { CPERF_PTEST_TYPE, required_argument, 0, 0 }, 638 639 { CPERF_POOL_SIZE, required_argument, 0, 0 }, 640 { CPERF_TOTAL_OPS, required_argument, 0, 0 }, 641 { CPERF_BURST_SIZE, required_argument, 0, 0 }, 642 { CPERF_BUFFER_SIZE, required_argument, 0, 0 }, 643 { CPERF_SEGMENTS_NB, required_argument, 0, 0 }, 644 645 { CPERF_DEVTYPE, required_argument, 0, 0 }, 646 { CPERF_OPTYPE, required_argument, 0, 0 }, 647 648 { CPERF_SILENT, no_argument, 0, 0 }, 649 { CPERF_SESSIONLESS, no_argument, 0, 0 }, 650 { CPERF_OUT_OF_PLACE, no_argument, 0, 0 }, 651 { CPERF_TEST_FILE, required_argument, 0, 0 }, 652 { CPERF_TEST_NAME, required_argument, 0, 0 }, 653 654 { CPERF_CIPHER_ALGO, required_argument, 0, 0 }, 655 { CPERF_CIPHER_OP, required_argument, 0, 0 }, 656 657 { CPERF_CIPHER_KEY_SZ, required_argument, 0, 0 }, 658 { CPERF_CIPHER_IV_SZ, required_argument, 0, 0 }, 659 660 { CPERF_AUTH_ALGO, required_argument, 0, 0 }, 661 { CPERF_AUTH_OP, required_argument, 0, 0 }, 662 663 { CPERF_AUTH_KEY_SZ, required_argument, 0, 0 }, 664 { CPERF_AUTH_IV_SZ, required_argument, 0, 0 }, 665 666 { CPERF_AEAD_ALGO, required_argument, 0, 0 }, 667 { CPERF_AEAD_OP, required_argument, 0, 0 }, 668 669 { CPERF_AEAD_KEY_SZ, required_argument, 0, 0 }, 670 { CPERF_AEAD_AAD_SZ, required_argument, 0, 0 }, 671 { CPERF_AEAD_IV_SZ, required_argument, 0, 0 }, 672 673 { CPERF_DIGEST_SZ, required_argument, 0, 0 }, 674 675 { CPERF_CSV, no_argument, 0, 0}, 676 677 { NULL, 0, 0, 0 } 678 }; 679 680 void 681 cperf_options_default(struct cperf_options *opts) 682 { 683 opts->test = CPERF_TEST_TYPE_THROUGHPUT; 684 685 opts->pool_sz = 8192; 686 opts->total_ops = 10000000; 687 688 opts->buffer_size_list[0] = 64; 689 opts->buffer_size_count = 1; 690 opts->max_buffer_size = 64; 691 opts->min_buffer_size = 64; 692 opts->inc_buffer_size = 0; 693 694 opts->burst_size_list[0] = 32; 695 opts->burst_size_count = 1; 696 opts->max_burst_size = 32; 697 opts->min_burst_size = 32; 698 opts->inc_burst_size = 0; 699 700 opts->segments_nb = 1; 701 702 strncpy(opts->device_type, "crypto_aesni_mb", 703 sizeof(opts->device_type)); 704 705 opts->op_type = CPERF_CIPHER_THEN_AUTH; 706 707 opts->silent = 0; 708 opts->test_file = NULL; 709 opts->test_name = NULL; 710 opts->sessionless = 0; 711 opts->out_of_place = 0; 712 opts->csv = 0; 713 714 opts->cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC; 715 opts->cipher_op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 716 opts->cipher_key_sz = 16; 717 opts->cipher_iv_sz = 16; 718 719 opts->auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC; 720 opts->auth_op = RTE_CRYPTO_AUTH_OP_GENERATE; 721 722 opts->auth_key_sz = 64; 723 opts->auth_iv_sz = 0; 724 725 opts->aead_key_sz = 0; 726 opts->aead_iv_sz = 0; 727 opts->aead_aad_sz = 0; 728 729 opts->digest_sz = 12; 730 } 731 732 static int 733 cperf_opts_parse_long(int opt_idx, struct cperf_options *opts) 734 { 735 struct long_opt_parser parsermap[] = { 736 { CPERF_PTEST_TYPE, parse_cperf_test_type }, 737 { CPERF_SILENT, parse_silent }, 738 { CPERF_POOL_SIZE, parse_pool_sz }, 739 { CPERF_TOTAL_OPS, parse_total_ops }, 740 { CPERF_BURST_SIZE, parse_burst_sz }, 741 { CPERF_BUFFER_SIZE, parse_buffer_sz }, 742 { CPERF_SEGMENTS_NB, parse_segments_nb }, 743 { CPERF_DEVTYPE, parse_device_type }, 744 { CPERF_OPTYPE, parse_op_type }, 745 { CPERF_SESSIONLESS, parse_sessionless }, 746 { CPERF_OUT_OF_PLACE, parse_out_of_place }, 747 { CPERF_TEST_FILE, parse_test_file }, 748 { CPERF_TEST_NAME, parse_test_name }, 749 { CPERF_CIPHER_ALGO, parse_cipher_algo }, 750 { CPERF_CIPHER_OP, parse_cipher_op }, 751 { CPERF_CIPHER_KEY_SZ, parse_cipher_key_sz }, 752 { CPERF_CIPHER_IV_SZ, parse_cipher_iv_sz }, 753 { CPERF_AUTH_ALGO, parse_auth_algo }, 754 { CPERF_AUTH_OP, parse_auth_op }, 755 { CPERF_AUTH_KEY_SZ, parse_auth_key_sz }, 756 { CPERF_AUTH_IV_SZ, parse_auth_iv_sz }, 757 { CPERF_AEAD_ALGO, parse_aead_algo }, 758 { CPERF_AEAD_OP, parse_aead_op }, 759 { CPERF_AEAD_KEY_SZ, parse_aead_key_sz }, 760 { CPERF_AEAD_IV_SZ, parse_aead_iv_sz }, 761 { CPERF_AEAD_AAD_SZ, parse_aead_aad_sz }, 762 { CPERF_DIGEST_SZ, parse_digest_sz }, 763 { CPERF_CSV, parse_csv_friendly}, 764 }; 765 unsigned int i; 766 767 for (i = 0; i < RTE_DIM(parsermap); i++) { 768 if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name, 769 strlen(lgopts[opt_idx].name)) == 0) 770 return parsermap[i].parser_fn(opts, optarg); 771 } 772 773 return -EINVAL; 774 } 775 776 int 777 cperf_options_parse(struct cperf_options *options, int argc, char **argv) 778 { 779 int opt, retval, opt_idx; 780 781 while ((opt = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) { 782 switch (opt) { 783 /* long options */ 784 case 0: 785 786 retval = cperf_opts_parse_long(opt_idx, options); 787 if (retval != 0) 788 return retval; 789 790 break; 791 792 default: 793 return -EINVAL; 794 } 795 } 796 797 return 0; 798 } 799 800 static int 801 check_cipher_buffer_length(struct cperf_options *options) 802 { 803 uint32_t buffer_size, buffer_size_idx = 0; 804 805 if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC || 806 options->cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) { 807 if (options->inc_buffer_size != 0) 808 buffer_size = options->min_buffer_size; 809 else 810 buffer_size = options->buffer_size_list[0]; 811 812 while (buffer_size <= options->max_buffer_size) { 813 if ((buffer_size % AES_BLOCK_SIZE) != 0) { 814 RTE_LOG(ERR, USER1, "Some of the buffer sizes are " 815 "not suitable for the algorithm selected\n"); 816 return -EINVAL; 817 } 818 819 if (options->inc_buffer_size != 0) 820 buffer_size += options->inc_buffer_size; 821 else { 822 if (++buffer_size_idx == options->buffer_size_count) 823 break; 824 buffer_size = options->buffer_size_list[buffer_size_idx]; 825 } 826 827 } 828 } 829 830 if (options->cipher_algo == RTE_CRYPTO_CIPHER_DES_CBC || 831 options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_CBC || 832 options->cipher_algo == RTE_CRYPTO_CIPHER_3DES_ECB) { 833 for (buffer_size = options->min_buffer_size; 834 buffer_size < options->max_buffer_size; 835 buffer_size += options->inc_buffer_size) { 836 if ((buffer_size % DES_BLOCK_SIZE) != 0) { 837 RTE_LOG(ERR, USER1, "Some of the buffer sizes are " 838 "not suitable for the algorithm selected\n"); 839 return -EINVAL; 840 } 841 } 842 } 843 844 return 0; 845 } 846 847 int 848 cperf_options_check(struct cperf_options *options) 849 { 850 if (options->segments_nb > options->min_buffer_size) { 851 RTE_LOG(ERR, USER1, 852 "Segments number greater than buffer size.\n"); 853 return -EINVAL; 854 } 855 856 if (options->test == CPERF_TEST_TYPE_VERIFY && 857 options->test_file == NULL) { 858 RTE_LOG(ERR, USER1, "Define path to the file with test" 859 " vectors.\n"); 860 return -EINVAL; 861 } 862 863 if (options->test == CPERF_TEST_TYPE_VERIFY && 864 options->op_type != CPERF_CIPHER_ONLY && 865 options->test_name == NULL) { 866 RTE_LOG(ERR, USER1, "Define test name to get the correct digest" 867 " from the test vectors.\n"); 868 return -EINVAL; 869 } 870 871 if (options->test_name != NULL && options->test_file == NULL) { 872 RTE_LOG(ERR, USER1, "Define path to the file with test" 873 " vectors.\n"); 874 return -EINVAL; 875 } 876 877 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY && 878 options->test_file == NULL) { 879 RTE_LOG(ERR, USER1, "Define path to the file with test" 880 " vectors.\n"); 881 return -EINVAL; 882 } 883 884 if (options->test == CPERF_TEST_TYPE_VERIFY && 885 options->total_ops > options->pool_sz) { 886 RTE_LOG(ERR, USER1, "Total number of ops must be less than or" 887 " equal to the pool size.\n"); 888 return -EINVAL; 889 } 890 891 if (options->test == CPERF_TEST_TYPE_VERIFY && 892 (options->inc_buffer_size != 0 || 893 options->buffer_size_count > 1)) { 894 RTE_LOG(ERR, USER1, "Only one buffer size is allowed when " 895 "using the verify test.\n"); 896 return -EINVAL; 897 } 898 899 if (options->test == CPERF_TEST_TYPE_VERIFY && 900 (options->inc_burst_size != 0 || 901 options->burst_size_count > 1)) { 902 RTE_LOG(ERR, USER1, "Only one burst size is allowed when " 903 "using the verify test.\n"); 904 return -EINVAL; 905 } 906 907 if (options->op_type == CPERF_CIPHER_THEN_AUTH) { 908 if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT && 909 options->auth_op != 910 RTE_CRYPTO_AUTH_OP_GENERATE) { 911 RTE_LOG(ERR, USER1, "Option cipher then auth must use" 912 " options: encrypt and generate.\n"); 913 return -EINVAL; 914 } 915 } else if (options->op_type == CPERF_AUTH_THEN_CIPHER) { 916 if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_DECRYPT && 917 options->auth_op != 918 RTE_CRYPTO_AUTH_OP_VERIFY) { 919 RTE_LOG(ERR, USER1, "Option auth then cipher must use" 920 " options: decrypt and verify.\n"); 921 return -EINVAL; 922 } 923 } 924 925 if (options->op_type == CPERF_CIPHER_ONLY || 926 options->op_type == CPERF_CIPHER_THEN_AUTH || 927 options->op_type == CPERF_AUTH_THEN_CIPHER) { 928 if (check_cipher_buffer_length(options) < 0) 929 return -EINVAL; 930 } 931 932 return 0; 933 } 934 935 void 936 cperf_options_dump(struct cperf_options *opts) 937 { 938 uint8_t size_idx; 939 940 printf("# Crypto Performance Application Options:\n"); 941 printf("#\n"); 942 printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]); 943 printf("#\n"); 944 printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz); 945 printf("# total number of ops: %u\n", opts->total_ops); 946 if (opts->inc_buffer_size != 0) { 947 printf("# buffer size:\n"); 948 printf("#\t min: %u\n", opts->min_buffer_size); 949 printf("#\t max: %u\n", opts->max_buffer_size); 950 printf("#\t inc: %u\n", opts->inc_buffer_size); 951 } else { 952 printf("# buffer sizes: "); 953 for (size_idx = 0; size_idx < opts->buffer_size_count; size_idx++) 954 printf("%u ", opts->buffer_size_list[size_idx]); 955 printf("\n"); 956 } 957 if (opts->inc_burst_size != 0) { 958 printf("# burst size:\n"); 959 printf("#\t min: %u\n", opts->min_burst_size); 960 printf("#\t max: %u\n", opts->max_burst_size); 961 printf("#\t inc: %u\n", opts->inc_burst_size); 962 } else { 963 printf("# burst sizes: "); 964 for (size_idx = 0; size_idx < opts->burst_size_count; size_idx++) 965 printf("%u ", opts->burst_size_list[size_idx]); 966 printf("\n"); 967 } 968 printf("\n# segments per buffer: %u\n", opts->segments_nb); 969 printf("#\n"); 970 printf("# cryptodev type: %s\n", opts->device_type); 971 printf("#\n"); 972 printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]); 973 printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no"); 974 printf("# out of place: %s\n", opts->out_of_place ? "yes" : "no"); 975 976 printf("#\n"); 977 978 if (opts->op_type == CPERF_AUTH_ONLY || 979 opts->op_type == CPERF_CIPHER_THEN_AUTH || 980 opts->op_type == CPERF_AUTH_THEN_CIPHER) { 981 printf("# auth algorithm: %s\n", 982 rte_crypto_auth_algorithm_strings[opts->auth_algo]); 983 printf("# auth operation: %s\n", 984 rte_crypto_auth_operation_strings[opts->auth_op]); 985 printf("# auth key size: %u\n", opts->auth_key_sz); 986 printf("# auth iv size: %u\n", opts->auth_iv_sz); 987 printf("# auth digest size: %u\n", opts->digest_sz); 988 printf("#\n"); 989 } 990 991 if (opts->op_type == CPERF_CIPHER_ONLY || 992 opts->op_type == CPERF_CIPHER_THEN_AUTH || 993 opts->op_type == CPERF_AUTH_THEN_CIPHER) { 994 printf("# cipher algorithm: %s\n", 995 rte_crypto_cipher_algorithm_strings[opts->cipher_algo]); 996 printf("# cipher operation: %s\n", 997 rte_crypto_cipher_operation_strings[opts->cipher_op]); 998 printf("# cipher key size: %u\n", opts->cipher_key_sz); 999 printf("# cipher iv size: %u\n", opts->cipher_iv_sz); 1000 printf("#\n"); 1001 } 1002 1003 if (opts->op_type == CPERF_AEAD) { 1004 printf("# aead algorithm: %s\n", 1005 rte_crypto_aead_algorithm_strings[opts->aead_algo]); 1006 printf("# aead operation: %s\n", 1007 rte_crypto_aead_operation_strings[opts->aead_op]); 1008 printf("# aead key size: %u\n", opts->aead_key_sz); 1009 printf("# aead iv size: %u\n", opts->aead_iv_sz); 1010 printf("# aead digest size: %u\n", opts->digest_sz); 1011 printf("# aead aad size: %u\n", opts->aead_aad_sz); 1012 printf("#\n"); 1013 } 1014 } 1015