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