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