-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2016-2017 Intel Corporation
*/
#include <getopt.h>
#include <rte_cryptodev.h>
#include <rte_malloc.h>
+#include <rte_ether.h>
#include "cperf_options.h"
+#include "cperf_test_vectors.h"
#define AES_BLOCK_SIZE 16
#define DES_BLOCK_SIZE 8
{
printf("%s [EAL options] --\n"
" --silent: disable options dump\n"
- " --ptest throughput / latency / verify / pmd-cycleount :"
+ " --ptest throughput / latency / verify / pmd-cyclecount :"
" set test type\n"
" --pool_sz N: set the number of crypto ops/mbufs allocated\n"
" --total-ops N: set the number of total operations performed\n"
" --burst-sz N: set the number of packets per burst\n"
" --buffer-sz N: set the size of a single packet\n"
+ " --imix N: set the distribution of packet sizes\n"
" --segment-sz N: set the size of the segment to use\n"
" --desc-nb N: set number of descriptors for each crypto device\n"
" --devtype TYPE: set crypto device type to use\n"
" --pmd-cyclecount-delay-ms N: set delay between enqueue\n"
" and dequeue in pmd-cyclecount benchmarking mode\n"
" --csv-friendly: enable test result output CSV friendly\n"
+ " --modex-len N: modex length, supported lengths are "
+ "60, 128, 255, 448. Default: 128\n"
+#ifdef RTE_LIB_SECURITY
+ " --pdcp-sn-sz N: set PDCP SN size N <5/7/12/15/18>\n"
+ " --pdcp-domain DOMAIN: set PDCP domain <control/user>\n"
+ " --pdcp-ses-hfn-en: enable session based fixed HFN\n"
+ " --docsis-hdr-sz: set DOCSIS header size\n"
+#endif
" -h: prints this help\n",
progname);
}
char *token;
uint32_t number;
uint8_t count = 0;
+ uint32_t temp_min;
+ uint32_t temp_max;
char *copy_arg = strdup(arg);
goto err_list;
list[count++] = number;
- *min = number;
- *max = number;
+ temp_min = number;
+ temp_max = number;
} else
goto err_list;
list[count++] = number;
- if (number < *min)
- *min = number;
- if (number > *max)
- *max = number;
+ if (number < temp_min)
+ temp_min = number;
+ if (number > temp_max)
+ temp_max = number;
token = strtok(NULL, ",");
}
+ if (min)
+ *min = temp_min;
+ if (max)
+ *max = temp_max;
+
free(copy_arg);
return count;
return ret;
}
+static int
+parse_modex_len(struct cperf_options *opts, const char *arg)
+{
+ int ret = parse_uint16_t(&opts->modex_len, arg);
+
+ if (ret)
+ RTE_LOG(ERR, USER1, "failed to parse modex len");
+ return ret;
+}
+
static int
parse_burst_sz(struct cperf_options *opts, const char *arg)
{
return 0;
}
+static int
+parse_imix(struct cperf_options *opts, const char *arg)
+{
+ int ret;
+
+ ret = parse_list(arg, opts->imix_distribution_list,
+ NULL, NULL);
+ if (ret < 0) {
+ RTE_LOG(ERR, USER1, "failed to parse imix distribution\n");
+ return -1;
+ }
+
+ opts->imix_distribution_count = ret;
+
+ if (opts->imix_distribution_count <= 1) {
+ RTE_LOG(ERR, USER1, "imix distribution should have "
+ "at least two entries\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int
parse_desc_nb(struct cperf_options *opts, const char *arg)
{
{
cperf_op_type_strs[CPERF_AEAD],
CPERF_AEAD
+ },
+ {
+ cperf_op_type_strs[CPERF_PDCP],
+ CPERF_PDCP
+ },
+ {
+ cperf_op_type_strs[CPERF_DOCSIS],
+ CPERF_DOCSIS
+ },
+ {
+ cperf_op_type_strs[CPERF_IPSEC],
+ CPERF_IPSEC
+ },
+ {
+ cperf_op_type_strs[CPERF_ASYM_MODEX],
+ CPERF_ASYM_MODEX
}
};
{
char *test_name = (char *) rte_zmalloc(NULL,
sizeof(char) * (strlen(arg) + 3), 0);
+ if (test_name == NULL) {
+ RTE_LOG(ERR, USER1, "Failed to rte zmalloc with size: %zu\n",
+ strlen(arg) + 3);
+ return -1;
+ }
+
snprintf(test_name, strlen(arg) + 3, "[%s]", arg);
opts->test_name = test_name;
return parse_uint16_t(&opts->digest_sz, arg);
}
+#ifdef RTE_LIB_SECURITY
+static int
+parse_pdcp_sn_sz(struct cperf_options *opts, const char *arg)
+{
+ uint32_t val = 0;
+ int ret = parse_uint32_t(&val, arg);
+
+ if (ret < 0)
+ return ret;
+
+ if (val != RTE_SECURITY_PDCP_SN_SIZE_5 &&
+ val != RTE_SECURITY_PDCP_SN_SIZE_7 &&
+ val != RTE_SECURITY_PDCP_SN_SIZE_12 &&
+ val != RTE_SECURITY_PDCP_SN_SIZE_15 &&
+ val != RTE_SECURITY_PDCP_SN_SIZE_18) {
+ printf("\nInvalid pdcp SN size: %u\n", val);
+ return -ERANGE;
+ }
+ opts->pdcp_sn_sz = val;
+
+ return 0;
+}
+
+const char *cperf_pdcp_domain_strs[] = {
+ [RTE_SECURITY_PDCP_MODE_CONTROL] = "control",
+ [RTE_SECURITY_PDCP_MODE_DATA] = "data",
+ [RTE_SECURITY_PDCP_MODE_SHORT_MAC] = "short_mac"
+};
+
+static int
+parse_pdcp_domain(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map pdcp_domain_namemap[] = {
+ {
+ cperf_pdcp_domain_strs
+ [RTE_SECURITY_PDCP_MODE_CONTROL],
+ RTE_SECURITY_PDCP_MODE_CONTROL },
+ {
+ cperf_pdcp_domain_strs
+ [RTE_SECURITY_PDCP_MODE_DATA],
+ RTE_SECURITY_PDCP_MODE_DATA
+ },
+ {
+ cperf_pdcp_domain_strs
+ [RTE_SECURITY_PDCP_MODE_SHORT_MAC],
+ RTE_SECURITY_PDCP_MODE_SHORT_MAC
+ }
+ };
+
+ int id = get_str_key_id_mapping(pdcp_domain_namemap,
+ RTE_DIM(pdcp_domain_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "invalid pdcp domain specified"
+ "\n");
+ return -1;
+ }
+
+ opts->pdcp_domain = (enum rte_security_pdcp_domain)id;
+
+ return 0;
+}
+
+static int
+parse_pdcp_ses_hfn_en(struct cperf_options *opts, const char *arg __rte_unused)
+{
+ opts->pdcp_ses_hfn_en = 1;
+ return 0;
+}
+
+static int
+parse_docsis_hdr_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->docsis_hdr_sz, arg);
+}
+#endif
+
static int
parse_auth_iv_sz(struct cperf_options *opts, const char *arg)
{
static struct option lgopts[] = {
{ CPERF_PTEST_TYPE, required_argument, 0, 0 },
+ { CPERF_MODEX_LEN, required_argument, 0, 0 },
{ CPERF_POOL_SIZE, required_argument, 0, 0 },
{ CPERF_TOTAL_OPS, required_argument, 0, 0 },
{ CPERF_SEGMENT_SIZE, required_argument, 0, 0 },
{ CPERF_DESC_NB, required_argument, 0, 0 },
+ { CPERF_IMIX, required_argument, 0, 0 },
{ CPERF_DEVTYPE, required_argument, 0, 0 },
{ CPERF_OPTYPE, required_argument, 0, 0 },
{ CPERF_DIGEST_SZ, required_argument, 0, 0 },
+#ifdef RTE_LIB_SECURITY
+ { CPERF_PDCP_SN_SZ, required_argument, 0, 0 },
+ { CPERF_PDCP_DOMAIN, required_argument, 0, 0 },
+ { CPERF_PDCP_SES_HFN_EN, no_argument, 0, 0 },
+ { CPERF_DOCSIS_HDR_SZ, required_argument, 0, 0 },
+#endif
{ CPERF_CSV, no_argument, 0, 0},
{ CPERF_PMDCC_DELAY_MS, required_argument, 0, 0 },
*/
opts->segment_sz = 0;
+ opts->imix_distribution_count = 0;
strncpy(opts->device_type, "crypto_aesni_mb",
sizeof(opts->device_type));
opts->nb_qps = 1;
opts->digest_sz = 12;
opts->pmdcc_delay = 0;
+#ifdef RTE_LIB_SECURITY
+ opts->pdcp_sn_sz = 12;
+ opts->pdcp_domain = RTE_SECURITY_PDCP_MODE_CONTROL;
+ opts->pdcp_ses_hfn_en = 0;
+ opts->docsis_hdr_sz = 17;
+#endif
+ opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
}
static int
{
struct long_opt_parser parsermap[] = {
{ CPERF_PTEST_TYPE, parse_cperf_test_type },
+ { CPERF_MODEX_LEN, parse_modex_len },
{ CPERF_SILENT, parse_silent },
{ CPERF_POOL_SIZE, parse_pool_sz },
{ CPERF_TOTAL_OPS, parse_total_ops },
{ CPERF_OPTYPE, parse_op_type },
{ CPERF_SESSIONLESS, parse_sessionless },
{ CPERF_OUT_OF_PLACE, parse_out_of_place },
+ { CPERF_IMIX, parse_imix },
{ CPERF_TEST_FILE, parse_test_file },
{ CPERF_TEST_NAME, parse_test_name },
{ CPERF_CIPHER_ALGO, parse_cipher_algo },
{ CPERF_AEAD_IV_SZ, parse_aead_iv_sz },
{ CPERF_AEAD_AAD_SZ, parse_aead_aad_sz },
{ CPERF_DIGEST_SZ, parse_digest_sz },
+#ifdef RTE_LIB_SECURITY
+ { CPERF_PDCP_SN_SZ, parse_pdcp_sn_sz },
+ { CPERF_PDCP_DOMAIN, parse_pdcp_domain },
+ { CPERF_PDCP_SES_HFN_EN, parse_pdcp_ses_hfn_en },
+ { CPERF_DOCSIS_HDR_SZ, parse_docsis_hdr_sz },
+#endif
{ CPERF_CSV, parse_csv_friendly},
{ CPERF_PMDCC_DELAY_MS, parse_pmd_cyclecount_delay_ms},
};
switch (opt) {
case 'h':
usage(argv[0]);
- rte_exit(EXIT_SUCCESS, "Displayed help\n");
+ exit(EXIT_SUCCESS);
break;
/* long options */
case 0:
return 0;
}
+#ifdef RTE_LIB_SECURITY
+static int
+check_docsis_buffer_length(struct cperf_options *options)
+{
+ uint32_t buffer_size, buffer_size_idx = 0;
+
+ if (options->inc_buffer_size != 0)
+ buffer_size = options->min_buffer_size;
+ else
+ buffer_size = options->buffer_size_list[0];
+
+ while (buffer_size <= options->max_buffer_size) {
+ if (buffer_size < (uint32_t)(options->docsis_hdr_sz +
+ RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN)) {
+ RTE_LOG(ERR, USER1, "Some of the buffer sizes are not "
+ "valid for DOCSIS\n");
+ return -EINVAL;
+ }
+
+ if (options->inc_buffer_size != 0)
+ buffer_size += options->inc_buffer_size;
+ else {
+ if (++buffer_size_idx == options->buffer_size_count)
+ break;
+ buffer_size =
+ options->buffer_size_list[buffer_size_idx];
+ }
+ }
+
+ return 0;
+}
+#endif
+
int
cperf_options_check(struct cperf_options *options)
{
- if (options->op_type == CPERF_CIPHER_ONLY)
+ int i;
+
+ if (options->op_type == CPERF_CIPHER_ONLY ||
+ options->op_type == CPERF_DOCSIS)
options->digest_sz = 0;
+ if (options->out_of_place &&
+ options->segment_sz <= options->max_buffer_size) {
+ RTE_LOG(ERR, USER1, "Out of place mode can only work "
+ "with non segmented buffers\n");
+ return -EINVAL;
+ }
+
/*
* If segment size is not set, assume only one segment,
* big enough to contain the largest buffer and the digest
*/
- if (options->segment_sz == 0)
+ if (options->segment_sz == 0) {
options->segment_sz = options->max_buffer_size +
options->digest_sz;
+ /* In IPsec operation, packet length will be increased
+ * by some bytes depend upon the algorithm, so increasing
+ * the segment size by headroom to cover most of
+ * the scenarios.
+ */
+ if (options->op_type == CPERF_IPSEC)
+ options->segment_sz += RTE_PKTMBUF_HEADROOM;
+ }
if (options->segment_sz < options->digest_sz) {
RTE_LOG(ERR, USER1,
return -EINVAL;
}
+ if ((options->imix_distribution_count != 0) &&
+ (options->imix_distribution_count !=
+ options->buffer_size_count)) {
+ RTE_LOG(ERR, USER1, "IMIX distribution must have the same "
+ "number of buffer sizes\n");
+ return -EINVAL;
+ }
+
if (options->test == CPERF_TEST_TYPE_VERIFY &&
options->test_file == NULL) {
RTE_LOG(ERR, USER1, "Define path to the file with test"
return -EINVAL;
}
+ if (options->test == CPERF_TEST_TYPE_VERIFY &&
+ options->imix_distribution_count > 0) {
+ RTE_LOG(ERR, USER1, "IMIX is not allowed when "
+ "using the verify test.\n");
+ return -EINVAL;
+ }
+
if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
options->auth_op !=
return -EINVAL;
}
+ if (options->modex_len) {
+ if (options->op_type != CPERF_ASYM_MODEX) {
+ RTE_LOG(ERR, USER1, "Option modex len should be used only with "
+ " optype: modex.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < (int)RTE_DIM(modex_perf_data); i++) {
+ if (modex_perf_data[i].modulus.len ==
+ options->modex_len) {
+ options->modex_data =
+ (struct cperf_modex_test_data
+ *)&modex_perf_data[i];
+ break;
+ }
+ }
+ if (i == (int)RTE_DIM(modex_perf_data)) {
+ RTE_LOG(ERR, USER1,
+ "Option modex len: %d is not supported\n",
+ options->modex_len);
+ return -EINVAL;
+ }
+ }
+
+#ifdef RTE_LIB_SECURITY
+ if (options->op_type == CPERF_DOCSIS) {
+ if (check_docsis_buffer_length(options) < 0)
+ return -EINVAL;
+ }
+#endif
+
return 0;
}
printf("# aead aad size: %u\n", opts->aead_aad_sz);
printf("#\n");
}
+
+#ifdef RTE_LIB_SECURITY
+ if (opts->op_type == CPERF_DOCSIS) {
+ printf("# docsis header size: %u\n", opts->docsis_hdr_sz);
+ printf("#\n");
+ }
+#endif
}