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