1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015-2016 Intel Corporation 3 */ 4 5 #include <time.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <stdint.h> 10 #include <inttypes.h> 11 #include <sys/types.h> 12 #include <sys/queue.h> 13 #include <netinet/in.h> 14 #include <setjmp.h> 15 #include <stdarg.h> 16 #include <ctype.h> 17 #include <errno.h> 18 #include <getopt.h> 19 #include <fcntl.h> 20 #include <unistd.h> 21 22 #include <rte_atomic.h> 23 #include <rte_branch_prediction.h> 24 #include <rte_common.h> 25 #include <rte_cryptodev.h> 26 #include <rte_cycles.h> 27 #include <rte_debug.h> 28 #include <rte_eal.h> 29 #include <rte_ether.h> 30 #include <rte_ethdev.h> 31 #include <rte_interrupts.h> 32 #include <rte_ip.h> 33 #include <rte_launch.h> 34 #include <rte_lcore.h> 35 #include <rte_log.h> 36 #include <rte_malloc.h> 37 #include <rte_mbuf.h> 38 #include <rte_memcpy.h> 39 #include <rte_memory.h> 40 #include <rte_mempool.h> 41 #include <rte_per_lcore.h> 42 #include <rte_prefetch.h> 43 #include <rte_random.h> 44 #include <rte_hexdump.h> 45 46 enum cdev_type { 47 CDEV_TYPE_ANY, 48 CDEV_TYPE_HW, 49 CDEV_TYPE_SW 50 }; 51 52 #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 53 54 #define NB_MBUF 8192 55 56 #define MAX_STR_LEN 32 57 #define MAX_KEY_SIZE 128 58 #define MAX_IV_SIZE 16 59 #define MAX_AAD_SIZE 65535 60 #define MAX_PKT_BURST 32 61 #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ 62 #define MAX_SESSIONS 32 63 #define SESSION_POOL_CACHE_SIZE 0 64 65 #define MAXIMUM_IV_LENGTH 16 66 #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ 67 sizeof(struct rte_crypto_sym_op)) 68 69 /* 70 * Configurable number of RX/TX ring descriptors 71 */ 72 #define RTE_TEST_RX_DESC_DEFAULT 128 73 #define RTE_TEST_TX_DESC_DEFAULT 512 74 75 static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 76 static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; 77 78 /* ethernet addresses of ports */ 79 static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; 80 81 /* mask of enabled ports */ 82 static uint64_t l2fwd_enabled_port_mask; 83 static uint64_t l2fwd_enabled_crypto_mask; 84 85 /* list of enabled ports */ 86 static uint16_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; 87 88 89 struct pkt_buffer { 90 unsigned len; 91 struct rte_mbuf *buffer[MAX_PKT_BURST]; 92 }; 93 94 struct op_buffer { 95 unsigned len; 96 struct rte_crypto_op *buffer[MAX_PKT_BURST]; 97 }; 98 99 #define MAX_RX_QUEUE_PER_LCORE 16 100 #define MAX_TX_QUEUE_PER_PORT 16 101 102 enum l2fwd_crypto_xform_chain { 103 L2FWD_CRYPTO_CIPHER_HASH, 104 L2FWD_CRYPTO_HASH_CIPHER, 105 L2FWD_CRYPTO_CIPHER_ONLY, 106 L2FWD_CRYPTO_HASH_ONLY, 107 L2FWD_CRYPTO_AEAD 108 }; 109 110 struct l2fwd_key { 111 uint8_t *data; 112 uint32_t length; 113 rte_iova_t phys_addr; 114 }; 115 116 struct l2fwd_iv { 117 uint8_t *data; 118 uint16_t length; 119 }; 120 121 /** l2fwd crypto application command line options */ 122 struct l2fwd_crypto_options { 123 unsigned portmask; 124 unsigned nb_ports_per_lcore; 125 unsigned refresh_period; 126 unsigned single_lcore:1; 127 128 enum cdev_type type; 129 unsigned sessionless:1; 130 131 enum l2fwd_crypto_xform_chain xform_chain; 132 133 struct rte_crypto_sym_xform cipher_xform; 134 unsigned ckey_param; 135 int ckey_random_size; 136 137 struct l2fwd_iv cipher_iv; 138 unsigned int cipher_iv_param; 139 int cipher_iv_random_size; 140 141 struct rte_crypto_sym_xform auth_xform; 142 uint8_t akey_param; 143 int akey_random_size; 144 145 struct l2fwd_iv auth_iv; 146 unsigned int auth_iv_param; 147 int auth_iv_random_size; 148 149 struct rte_crypto_sym_xform aead_xform; 150 unsigned int aead_key_param; 151 int aead_key_random_size; 152 153 struct l2fwd_iv aead_iv; 154 unsigned int aead_iv_param; 155 int aead_iv_random_size; 156 157 struct l2fwd_key aad; 158 unsigned aad_param; 159 int aad_random_size; 160 161 int digest_size; 162 163 uint16_t block_size; 164 char string_type[MAX_STR_LEN]; 165 166 uint64_t cryptodev_mask; 167 168 unsigned int mac_updating; 169 }; 170 171 /** l2fwd crypto lcore params */ 172 struct l2fwd_crypto_params { 173 uint8_t dev_id; 174 uint8_t qp_id; 175 176 unsigned digest_length; 177 unsigned block_size; 178 179 struct l2fwd_iv cipher_iv; 180 struct l2fwd_iv auth_iv; 181 struct l2fwd_iv aead_iv; 182 struct l2fwd_key aad; 183 struct rte_cryptodev_sym_session *session; 184 185 uint8_t do_cipher; 186 uint8_t do_hash; 187 uint8_t do_aead; 188 uint8_t hash_verify; 189 190 enum rte_crypto_cipher_algorithm cipher_algo; 191 enum rte_crypto_auth_algorithm auth_algo; 192 enum rte_crypto_aead_algorithm aead_algo; 193 }; 194 195 /** lcore configuration */ 196 struct lcore_queue_conf { 197 unsigned nb_rx_ports; 198 uint16_t rx_port_list[MAX_RX_QUEUE_PER_LCORE]; 199 200 unsigned nb_crypto_devs; 201 unsigned cryptodev_list[MAX_RX_QUEUE_PER_LCORE]; 202 203 struct op_buffer op_buf[RTE_CRYPTO_MAX_DEVS]; 204 struct pkt_buffer pkt_buf[RTE_MAX_ETHPORTS]; 205 } __rte_cache_aligned; 206 207 struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; 208 209 static struct rte_eth_conf port_conf = { 210 .rxmode = { 211 .mq_mode = ETH_MQ_RX_NONE, 212 .max_rx_pkt_len = ETHER_MAX_LEN, 213 .split_hdr_size = 0, 214 .ignore_offload_bitfield = 1, 215 .offloads = DEV_RX_OFFLOAD_CRC_STRIP, 216 }, 217 .txmode = { 218 .mq_mode = ETH_MQ_TX_NONE, 219 }, 220 }; 221 222 struct rte_mempool *l2fwd_pktmbuf_pool; 223 struct rte_mempool *l2fwd_crypto_op_pool; 224 struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 }; 225 226 /* Per-port statistics struct */ 227 struct l2fwd_port_statistics { 228 uint64_t tx; 229 uint64_t rx; 230 231 uint64_t crypto_enqueued; 232 uint64_t crypto_dequeued; 233 234 uint64_t dropped; 235 } __rte_cache_aligned; 236 237 struct l2fwd_crypto_statistics { 238 uint64_t enqueued; 239 uint64_t dequeued; 240 241 uint64_t errors; 242 } __rte_cache_aligned; 243 244 struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; 245 struct l2fwd_crypto_statistics crypto_statistics[RTE_CRYPTO_MAX_DEVS]; 246 247 /* A tsc-based timer responsible for triggering statistics printout */ 248 #define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ 249 #define MAX_TIMER_PERIOD 86400UL /* 1 day max */ 250 251 /* default period is 10 seconds */ 252 static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; 253 254 /* Print out statistics on packets dropped */ 255 static void 256 print_stats(void) 257 { 258 uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; 259 uint64_t total_packets_enqueued, total_packets_dequeued, 260 total_packets_errors; 261 uint16_t portid; 262 uint64_t cdevid; 263 264 total_packets_dropped = 0; 265 total_packets_tx = 0; 266 total_packets_rx = 0; 267 total_packets_enqueued = 0; 268 total_packets_dequeued = 0; 269 total_packets_errors = 0; 270 271 const char clr[] = { 27, '[', '2', 'J', '\0' }; 272 const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 273 274 /* Clear screen and move to top left */ 275 printf("%s%s", clr, topLeft); 276 277 printf("\nPort statistics ===================================="); 278 279 for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 280 /* skip disabled ports */ 281 if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) 282 continue; 283 printf("\nStatistics for port %u ------------------------------" 284 "\nPackets sent: %32"PRIu64 285 "\nPackets received: %28"PRIu64 286 "\nPackets dropped: %29"PRIu64, 287 portid, 288 port_statistics[portid].tx, 289 port_statistics[portid].rx, 290 port_statistics[portid].dropped); 291 292 total_packets_dropped += port_statistics[portid].dropped; 293 total_packets_tx += port_statistics[portid].tx; 294 total_packets_rx += port_statistics[portid].rx; 295 } 296 printf("\nCrypto statistics =================================="); 297 298 for (cdevid = 0; cdevid < RTE_CRYPTO_MAX_DEVS; cdevid++) { 299 /* skip disabled ports */ 300 if ((l2fwd_enabled_crypto_mask & (((uint64_t)1) << cdevid)) == 0) 301 continue; 302 printf("\nStatistics for cryptodev %"PRIu64 303 " -------------------------" 304 "\nPackets enqueued: %28"PRIu64 305 "\nPackets dequeued: %28"PRIu64 306 "\nPackets errors: %30"PRIu64, 307 cdevid, 308 crypto_statistics[cdevid].enqueued, 309 crypto_statistics[cdevid].dequeued, 310 crypto_statistics[cdevid].errors); 311 312 total_packets_enqueued += crypto_statistics[cdevid].enqueued; 313 total_packets_dequeued += crypto_statistics[cdevid].dequeued; 314 total_packets_errors += crypto_statistics[cdevid].errors; 315 } 316 printf("\nAggregate statistics ===============================" 317 "\nTotal packets received: %22"PRIu64 318 "\nTotal packets enqueued: %22"PRIu64 319 "\nTotal packets dequeued: %22"PRIu64 320 "\nTotal packets sent: %26"PRIu64 321 "\nTotal packets dropped: %23"PRIu64 322 "\nTotal packets crypto errors: %17"PRIu64, 323 total_packets_rx, 324 total_packets_enqueued, 325 total_packets_dequeued, 326 total_packets_tx, 327 total_packets_dropped, 328 total_packets_errors); 329 printf("\n====================================================\n"); 330 } 331 332 static int 333 l2fwd_crypto_send_burst(struct lcore_queue_conf *qconf, unsigned n, 334 struct l2fwd_crypto_params *cparams) 335 { 336 struct rte_crypto_op **op_buffer; 337 unsigned ret; 338 339 op_buffer = (struct rte_crypto_op **) 340 qconf->op_buf[cparams->dev_id].buffer; 341 342 ret = rte_cryptodev_enqueue_burst(cparams->dev_id, 343 cparams->qp_id, op_buffer, (uint16_t) n); 344 345 crypto_statistics[cparams->dev_id].enqueued += ret; 346 if (unlikely(ret < n)) { 347 crypto_statistics[cparams->dev_id].errors += (n - ret); 348 do { 349 rte_pktmbuf_free(op_buffer[ret]->sym->m_src); 350 rte_crypto_op_free(op_buffer[ret]); 351 } while (++ret < n); 352 } 353 354 return 0; 355 } 356 357 static int 358 l2fwd_crypto_enqueue(struct rte_crypto_op *op, 359 struct l2fwd_crypto_params *cparams) 360 { 361 unsigned lcore_id, len; 362 struct lcore_queue_conf *qconf; 363 364 lcore_id = rte_lcore_id(); 365 366 qconf = &lcore_queue_conf[lcore_id]; 367 len = qconf->op_buf[cparams->dev_id].len; 368 qconf->op_buf[cparams->dev_id].buffer[len] = op; 369 len++; 370 371 /* enough ops to be sent */ 372 if (len == MAX_PKT_BURST) { 373 l2fwd_crypto_send_burst(qconf, MAX_PKT_BURST, cparams); 374 len = 0; 375 } 376 377 qconf->op_buf[cparams->dev_id].len = len; 378 return 0; 379 } 380 381 static int 382 l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, 383 struct rte_crypto_op *op, 384 struct l2fwd_crypto_params *cparams) 385 { 386 struct ether_hdr *eth_hdr; 387 struct ipv4_hdr *ip_hdr; 388 389 uint32_t ipdata_offset, data_len; 390 uint32_t pad_len = 0; 391 char *padding; 392 393 eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); 394 395 if (eth_hdr->ether_type != rte_cpu_to_be_16(ETHER_TYPE_IPv4)) 396 return -1; 397 398 ipdata_offset = sizeof(struct ether_hdr); 399 400 ip_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, char *) + 401 ipdata_offset); 402 403 ipdata_offset += (ip_hdr->version_ihl & IPV4_HDR_IHL_MASK) 404 * IPV4_IHL_MULTIPLIER; 405 406 407 /* Zero pad data to be crypto'd so it is block aligned */ 408 data_len = rte_pktmbuf_data_len(m) - ipdata_offset; 409 410 if (cparams->do_hash && cparams->hash_verify) 411 data_len -= cparams->digest_length; 412 413 if (cparams->do_cipher) { 414 /* 415 * Following algorithms are block cipher algorithms, 416 * and might need padding 417 */ 418 switch (cparams->cipher_algo) { 419 case RTE_CRYPTO_CIPHER_AES_CBC: 420 case RTE_CRYPTO_CIPHER_AES_ECB: 421 case RTE_CRYPTO_CIPHER_DES_CBC: 422 case RTE_CRYPTO_CIPHER_3DES_CBC: 423 case RTE_CRYPTO_CIPHER_3DES_ECB: 424 if (data_len % cparams->block_size) 425 pad_len = cparams->block_size - 426 (data_len % cparams->block_size); 427 break; 428 default: 429 pad_len = 0; 430 } 431 432 if (pad_len) { 433 padding = rte_pktmbuf_append(m, pad_len); 434 if (unlikely(!padding)) 435 return -1; 436 437 data_len += pad_len; 438 memset(padding, 0, pad_len); 439 } 440 } 441 442 /* Set crypto operation data parameters */ 443 rte_crypto_op_attach_sym_session(op, cparams->session); 444 445 if (cparams->do_hash) { 446 if (cparams->auth_iv.length) { 447 uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, 448 uint8_t *, 449 IV_OFFSET + 450 cparams->cipher_iv.length); 451 /* 452 * Copy IV at the end of the crypto operation, 453 * after the cipher IV, if added 454 */ 455 rte_memcpy(iv_ptr, cparams->auth_iv.data, 456 cparams->auth_iv.length); 457 } 458 if (!cparams->hash_verify) { 459 /* Append space for digest to end of packet */ 460 op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, 461 cparams->digest_length); 462 } else { 463 op->sym->auth.digest.data = rte_pktmbuf_mtod(m, 464 uint8_t *) + ipdata_offset + data_len; 465 } 466 467 op->sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(m, 468 rte_pktmbuf_pkt_len(m) - cparams->digest_length); 469 470 /* For wireless algorithms, offset/length must be in bits */ 471 if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 || 472 cparams->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 || 473 cparams->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3) { 474 op->sym->auth.data.offset = ipdata_offset << 3; 475 op->sym->auth.data.length = data_len << 3; 476 } else { 477 op->sym->auth.data.offset = ipdata_offset; 478 op->sym->auth.data.length = data_len; 479 } 480 } 481 482 if (cparams->do_cipher) { 483 uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 484 IV_OFFSET); 485 /* Copy IV at the end of the crypto operation */ 486 rte_memcpy(iv_ptr, cparams->cipher_iv.data, 487 cparams->cipher_iv.length); 488 489 /* For wireless algorithms, offset/length must be in bits */ 490 if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 || 491 cparams->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 || 492 cparams->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3) { 493 op->sym->cipher.data.offset = ipdata_offset << 3; 494 op->sym->cipher.data.length = data_len << 3; 495 } else { 496 op->sym->cipher.data.offset = ipdata_offset; 497 op->sym->cipher.data.length = data_len; 498 } 499 } 500 501 if (cparams->do_aead) { 502 uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 503 IV_OFFSET); 504 /* Copy IV at the end of the crypto operation */ 505 /* 506 * If doing AES-CCM, nonce is copied one byte 507 * after the start of IV field 508 */ 509 if (cparams->aead_algo == RTE_CRYPTO_AEAD_AES_CCM) 510 rte_memcpy(iv_ptr + 1, cparams->aead_iv.data, 511 cparams->aead_iv.length); 512 else 513 rte_memcpy(iv_ptr, cparams->aead_iv.data, 514 cparams->aead_iv.length); 515 516 op->sym->aead.data.offset = ipdata_offset; 517 op->sym->aead.data.length = data_len; 518 519 if (!cparams->hash_verify) { 520 /* Append space for digest to end of packet */ 521 op->sym->aead.digest.data = (uint8_t *)rte_pktmbuf_append(m, 522 cparams->digest_length); 523 } else { 524 op->sym->aead.digest.data = rte_pktmbuf_mtod(m, 525 uint8_t *) + ipdata_offset + data_len; 526 } 527 528 op->sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(m, 529 rte_pktmbuf_pkt_len(m) - cparams->digest_length); 530 531 if (cparams->aad.length) { 532 op->sym->aead.aad.data = cparams->aad.data; 533 op->sym->aead.aad.phys_addr = cparams->aad.phys_addr; 534 } 535 } 536 537 op->sym->m_src = m; 538 539 return l2fwd_crypto_enqueue(op, cparams); 540 } 541 542 543 /* Send the burst of packets on an output interface */ 544 static int 545 l2fwd_send_burst(struct lcore_queue_conf *qconf, unsigned n, 546 uint16_t port) 547 { 548 struct rte_mbuf **pkt_buffer; 549 unsigned ret; 550 551 pkt_buffer = (struct rte_mbuf **)qconf->pkt_buf[port].buffer; 552 553 ret = rte_eth_tx_burst(port, 0, pkt_buffer, (uint16_t)n); 554 port_statistics[port].tx += ret; 555 if (unlikely(ret < n)) { 556 port_statistics[port].dropped += (n - ret); 557 do { 558 rte_pktmbuf_free(pkt_buffer[ret]); 559 } while (++ret < n); 560 } 561 562 return 0; 563 } 564 565 /* Enqueue packets for TX and prepare them to be sent */ 566 static int 567 l2fwd_send_packet(struct rte_mbuf *m, uint16_t port) 568 { 569 unsigned lcore_id, len; 570 struct lcore_queue_conf *qconf; 571 572 lcore_id = rte_lcore_id(); 573 574 qconf = &lcore_queue_conf[lcore_id]; 575 len = qconf->pkt_buf[port].len; 576 qconf->pkt_buf[port].buffer[len] = m; 577 len++; 578 579 /* enough pkts to be sent */ 580 if (unlikely(len == MAX_PKT_BURST)) { 581 l2fwd_send_burst(qconf, MAX_PKT_BURST, port); 582 len = 0; 583 } 584 585 qconf->pkt_buf[port].len = len; 586 return 0; 587 } 588 589 static void 590 l2fwd_mac_updating(struct rte_mbuf *m, uint16_t dest_portid) 591 { 592 struct ether_hdr *eth; 593 void *tmp; 594 595 eth = rte_pktmbuf_mtod(m, struct ether_hdr *); 596 597 /* 02:00:00:00:00:xx */ 598 tmp = ð->d_addr.addr_bytes[0]; 599 *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40); 600 601 /* src addr */ 602 ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], ð->s_addr); 603 } 604 605 static void 606 l2fwd_simple_forward(struct rte_mbuf *m, uint16_t portid, 607 struct l2fwd_crypto_options *options) 608 { 609 uint16_t dst_port; 610 611 dst_port = l2fwd_dst_ports[portid]; 612 613 if (options->mac_updating) 614 l2fwd_mac_updating(m, dst_port); 615 616 l2fwd_send_packet(m, dst_port); 617 } 618 619 /** Generate random key */ 620 static void 621 generate_random_key(uint8_t *key, unsigned length) 622 { 623 int fd; 624 int ret; 625 626 fd = open("/dev/urandom", O_RDONLY); 627 if (fd < 0) 628 rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); 629 630 ret = read(fd, key, length); 631 close(fd); 632 633 if (ret != (signed)length) 634 rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); 635 } 636 637 static struct rte_cryptodev_sym_session * 638 initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id) 639 { 640 struct rte_crypto_sym_xform *first_xform; 641 struct rte_cryptodev_sym_session *session; 642 int retval = rte_cryptodev_socket_id(cdev_id); 643 644 if (retval < 0) 645 return NULL; 646 647 uint8_t socket_id = (uint8_t) retval; 648 struct rte_mempool *sess_mp = session_pool_socket[socket_id]; 649 650 if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 651 first_xform = &options->aead_xform; 652 } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { 653 first_xform = &options->cipher_xform; 654 first_xform->next = &options->auth_xform; 655 } else if (options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER) { 656 first_xform = &options->auth_xform; 657 first_xform->next = &options->cipher_xform; 658 } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 659 first_xform = &options->cipher_xform; 660 } else { 661 first_xform = &options->auth_xform; 662 } 663 664 session = rte_cryptodev_sym_session_create(sess_mp); 665 666 if (session == NULL) 667 return NULL; 668 669 if (rte_cryptodev_sym_session_init(cdev_id, session, 670 first_xform, sess_mp) < 0) 671 return NULL; 672 673 return session; 674 } 675 676 static void 677 l2fwd_crypto_options_print(struct l2fwd_crypto_options *options); 678 679 /* main processing loop */ 680 static void 681 l2fwd_main_loop(struct l2fwd_crypto_options *options) 682 { 683 struct rte_mbuf *m, *pkts_burst[MAX_PKT_BURST]; 684 struct rte_crypto_op *ops_burst[MAX_PKT_BURST]; 685 686 unsigned lcore_id = rte_lcore_id(); 687 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 688 unsigned int i, j, nb_rx, len; 689 uint16_t portid; 690 struct lcore_queue_conf *qconf = &lcore_queue_conf[lcore_id]; 691 const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / 692 US_PER_S * BURST_TX_DRAIN_US; 693 struct l2fwd_crypto_params *cparams; 694 struct l2fwd_crypto_params port_cparams[qconf->nb_crypto_devs]; 695 struct rte_cryptodev_sym_session *session; 696 697 if (qconf->nb_rx_ports == 0) { 698 RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); 699 return; 700 } 701 702 RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); 703 704 for (i = 0; i < qconf->nb_rx_ports; i++) { 705 706 portid = qconf->rx_port_list[i]; 707 RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, 708 portid); 709 } 710 711 for (i = 0; i < qconf->nb_crypto_devs; i++) { 712 port_cparams[i].do_cipher = 0; 713 port_cparams[i].do_hash = 0; 714 port_cparams[i].do_aead = 0; 715 716 switch (options->xform_chain) { 717 case L2FWD_CRYPTO_AEAD: 718 port_cparams[i].do_aead = 1; 719 break; 720 case L2FWD_CRYPTO_CIPHER_HASH: 721 case L2FWD_CRYPTO_HASH_CIPHER: 722 port_cparams[i].do_cipher = 1; 723 port_cparams[i].do_hash = 1; 724 break; 725 case L2FWD_CRYPTO_HASH_ONLY: 726 port_cparams[i].do_hash = 1; 727 break; 728 case L2FWD_CRYPTO_CIPHER_ONLY: 729 port_cparams[i].do_cipher = 1; 730 break; 731 } 732 733 port_cparams[i].dev_id = qconf->cryptodev_list[i]; 734 port_cparams[i].qp_id = 0; 735 736 port_cparams[i].block_size = options->block_size; 737 738 if (port_cparams[i].do_hash) { 739 port_cparams[i].auth_iv.data = options->auth_iv.data; 740 port_cparams[i].auth_iv.length = options->auth_iv.length; 741 if (!options->auth_iv_param) 742 generate_random_key(port_cparams[i].auth_iv.data, 743 port_cparams[i].auth_iv.length); 744 if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) 745 port_cparams[i].hash_verify = 1; 746 else 747 port_cparams[i].hash_verify = 0; 748 749 port_cparams[i].auth_algo = options->auth_xform.auth.algo; 750 port_cparams[i].digest_length = 751 options->auth_xform.auth.digest_length; 752 /* Set IV parameters */ 753 if (options->auth_iv.length) { 754 options->auth_xform.auth.iv.offset = 755 IV_OFFSET + options->cipher_iv.length; 756 options->auth_xform.auth.iv.length = 757 options->auth_iv.length; 758 } 759 } 760 761 if (port_cparams[i].do_aead) { 762 port_cparams[i].aead_iv.data = options->aead_iv.data; 763 port_cparams[i].aead_iv.length = options->aead_iv.length; 764 if (!options->aead_iv_param) 765 generate_random_key(port_cparams[i].aead_iv.data, 766 port_cparams[i].aead_iv.length); 767 port_cparams[i].aead_algo = options->aead_xform.aead.algo; 768 port_cparams[i].digest_length = 769 options->aead_xform.aead.digest_length; 770 if (options->aead_xform.aead.aad_length) { 771 port_cparams[i].aad.data = options->aad.data; 772 port_cparams[i].aad.phys_addr = options->aad.phys_addr; 773 port_cparams[i].aad.length = options->aad.length; 774 if (!options->aad_param) 775 generate_random_key(port_cparams[i].aad.data, 776 port_cparams[i].aad.length); 777 /* 778 * If doing AES-CCM, first 18 bytes has to be reserved, 779 * and actual AAD should start from byte 18 780 */ 781 if (port_cparams[i].aead_algo == RTE_CRYPTO_AEAD_AES_CCM) 782 memmove(port_cparams[i].aad.data + 18, 783 port_cparams[i].aad.data, 784 port_cparams[i].aad.length); 785 786 } else 787 port_cparams[i].aad.length = 0; 788 789 if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) 790 port_cparams[i].hash_verify = 1; 791 else 792 port_cparams[i].hash_verify = 0; 793 794 /* Set IV parameters */ 795 options->aead_xform.aead.iv.offset = IV_OFFSET; 796 options->aead_xform.aead.iv.length = options->aead_iv.length; 797 } 798 799 if (port_cparams[i].do_cipher) { 800 port_cparams[i].cipher_iv.data = options->cipher_iv.data; 801 port_cparams[i].cipher_iv.length = options->cipher_iv.length; 802 if (!options->cipher_iv_param) 803 generate_random_key(port_cparams[i].cipher_iv.data, 804 port_cparams[i].cipher_iv.length); 805 806 port_cparams[i].cipher_algo = options->cipher_xform.cipher.algo; 807 /* Set IV parameters */ 808 options->cipher_xform.cipher.iv.offset = IV_OFFSET; 809 options->cipher_xform.cipher.iv.length = 810 options->cipher_iv.length; 811 } 812 813 session = initialize_crypto_session(options, 814 port_cparams[i].dev_id); 815 if (session == NULL) 816 rte_exit(EXIT_FAILURE, "Failed to initialize crypto session\n"); 817 818 port_cparams[i].session = session; 819 820 RTE_LOG(INFO, L2FWD, " -- lcoreid=%u cryptoid=%u\n", lcore_id, 821 port_cparams[i].dev_id); 822 } 823 824 l2fwd_crypto_options_print(options); 825 826 /* 827 * Initialize previous tsc timestamp before the loop, 828 * to avoid showing the port statistics immediately, 829 * so user can see the crypto information. 830 */ 831 prev_tsc = rte_rdtsc(); 832 while (1) { 833 834 cur_tsc = rte_rdtsc(); 835 836 /* 837 * Crypto device/TX burst queue drain 838 */ 839 diff_tsc = cur_tsc - prev_tsc; 840 if (unlikely(diff_tsc > drain_tsc)) { 841 /* Enqueue all crypto ops remaining in buffers */ 842 for (i = 0; i < qconf->nb_crypto_devs; i++) { 843 cparams = &port_cparams[i]; 844 len = qconf->op_buf[cparams->dev_id].len; 845 l2fwd_crypto_send_burst(qconf, len, cparams); 846 qconf->op_buf[cparams->dev_id].len = 0; 847 } 848 /* Transmit all packets remaining in buffers */ 849 for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 850 if (qconf->pkt_buf[portid].len == 0) 851 continue; 852 l2fwd_send_burst(&lcore_queue_conf[lcore_id], 853 qconf->pkt_buf[portid].len, 854 portid); 855 qconf->pkt_buf[portid].len = 0; 856 } 857 858 /* if timer is enabled */ 859 if (timer_period > 0) { 860 861 /* advance the timer */ 862 timer_tsc += diff_tsc; 863 864 /* if timer has reached its timeout */ 865 if (unlikely(timer_tsc >= 866 (uint64_t)timer_period)) { 867 868 /* do this only on master core */ 869 if (lcore_id == rte_get_master_lcore() 870 && options->refresh_period) { 871 print_stats(); 872 timer_tsc = 0; 873 } 874 } 875 } 876 877 prev_tsc = cur_tsc; 878 } 879 880 /* 881 * Read packet from RX queues 882 */ 883 for (i = 0; i < qconf->nb_rx_ports; i++) { 884 portid = qconf->rx_port_list[i]; 885 886 cparams = &port_cparams[i]; 887 888 nb_rx = rte_eth_rx_burst(portid, 0, 889 pkts_burst, MAX_PKT_BURST); 890 891 port_statistics[portid].rx += nb_rx; 892 893 if (nb_rx) { 894 /* 895 * If we can't allocate a crypto_ops, then drop 896 * the rest of the burst and dequeue and 897 * process the packets to free offload structs 898 */ 899 if (rte_crypto_op_bulk_alloc( 900 l2fwd_crypto_op_pool, 901 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 902 ops_burst, nb_rx) != 903 nb_rx) { 904 for (j = 0; j < nb_rx; j++) 905 rte_pktmbuf_free(pkts_burst[j]); 906 907 nb_rx = 0; 908 } 909 910 /* Enqueue packets from Crypto device*/ 911 for (j = 0; j < nb_rx; j++) { 912 m = pkts_burst[j]; 913 914 l2fwd_simple_crypto_enqueue(m, 915 ops_burst[j], cparams); 916 } 917 } 918 919 /* Dequeue packets from Crypto device */ 920 do { 921 nb_rx = rte_cryptodev_dequeue_burst( 922 cparams->dev_id, cparams->qp_id, 923 ops_burst, MAX_PKT_BURST); 924 925 crypto_statistics[cparams->dev_id].dequeued += 926 nb_rx; 927 928 /* Forward crypto'd packets */ 929 for (j = 0; j < nb_rx; j++) { 930 m = ops_burst[j]->sym->m_src; 931 932 rte_crypto_op_free(ops_burst[j]); 933 l2fwd_simple_forward(m, portid, 934 options); 935 } 936 } while (nb_rx == MAX_PKT_BURST); 937 } 938 } 939 } 940 941 static int 942 l2fwd_launch_one_lcore(void *arg) 943 { 944 l2fwd_main_loop((struct l2fwd_crypto_options *)arg); 945 return 0; 946 } 947 948 /* Display command line arguments usage */ 949 static void 950 l2fwd_crypto_usage(const char *prgname) 951 { 952 printf("%s [EAL options] --\n" 953 " -p PORTMASK: hexadecimal bitmask of ports to configure\n" 954 " -q NQ: number of queue (=ports) per lcore (default is 1)\n" 955 " -s manage all ports from single lcore\n" 956 " -T PERIOD: statistics will be refreshed each PERIOD seconds" 957 " (0 to disable, 10 default, 86400 maximum)\n" 958 959 " --cdev_type HW / SW / ANY\n" 960 " --chain HASH_CIPHER / CIPHER_HASH / CIPHER_ONLY /" 961 " HASH_ONLY / AEAD\n" 962 963 " --cipher_algo ALGO\n" 964 " --cipher_op ENCRYPT / DECRYPT\n" 965 " --cipher_key KEY (bytes separated with \":\")\n" 966 " --cipher_key_random_size SIZE: size of cipher key when generated randomly\n" 967 " --cipher_iv IV (bytes separated with \":\")\n" 968 " --cipher_iv_random_size SIZE: size of cipher IV when generated randomly\n" 969 970 " --auth_algo ALGO\n" 971 " --auth_op GENERATE / VERIFY\n" 972 " --auth_key KEY (bytes separated with \":\")\n" 973 " --auth_key_random_size SIZE: size of auth key when generated randomly\n" 974 " --auth_iv IV (bytes separated with \":\")\n" 975 " --auth_iv_random_size SIZE: size of auth IV when generated randomly\n" 976 977 " --aead_algo ALGO\n" 978 " --aead_op ENCRYPT / DECRYPT\n" 979 " --aead_key KEY (bytes separated with \":\")\n" 980 " --aead_key_random_size SIZE: size of AEAD key when generated randomly\n" 981 " --aead_iv IV (bytes separated with \":\")\n" 982 " --aead_iv_random_size SIZE: size of AEAD IV when generated randomly\n" 983 " --aad AAD (bytes separated with \":\")\n" 984 " --aad_random_size SIZE: size of AAD when generated randomly\n" 985 986 " --digest_size SIZE: size of digest to be generated/verified\n" 987 988 " --sessionless\n" 989 " --cryptodev_mask MASK: hexadecimal bitmask of crypto devices to configure\n" 990 991 " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n" 992 " When enabled:\n" 993 " - The source MAC address is replaced by the TX port MAC address\n" 994 " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n", 995 prgname); 996 } 997 998 /** Parse crypto device type command line argument */ 999 static int 1000 parse_cryptodev_type(enum cdev_type *type, char *optarg) 1001 { 1002 if (strcmp("HW", optarg) == 0) { 1003 *type = CDEV_TYPE_HW; 1004 return 0; 1005 } else if (strcmp("SW", optarg) == 0) { 1006 *type = CDEV_TYPE_SW; 1007 return 0; 1008 } else if (strcmp("ANY", optarg) == 0) { 1009 *type = CDEV_TYPE_ANY; 1010 return 0; 1011 } 1012 1013 return -1; 1014 } 1015 1016 /** Parse crypto chain xform command line argument */ 1017 static int 1018 parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) 1019 { 1020 if (strcmp("CIPHER_HASH", optarg) == 0) { 1021 options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 1022 return 0; 1023 } else if (strcmp("HASH_CIPHER", optarg) == 0) { 1024 options->xform_chain = L2FWD_CRYPTO_HASH_CIPHER; 1025 return 0; 1026 } else if (strcmp("CIPHER_ONLY", optarg) == 0) { 1027 options->xform_chain = L2FWD_CRYPTO_CIPHER_ONLY; 1028 return 0; 1029 } else if (strcmp("HASH_ONLY", optarg) == 0) { 1030 options->xform_chain = L2FWD_CRYPTO_HASH_ONLY; 1031 return 0; 1032 } else if (strcmp("AEAD", optarg) == 0) { 1033 options->xform_chain = L2FWD_CRYPTO_AEAD; 1034 return 0; 1035 } 1036 1037 return -1; 1038 } 1039 1040 /** Parse crypto cipher algo option command line argument */ 1041 static int 1042 parse_cipher_algo(enum rte_crypto_cipher_algorithm *algo, char *optarg) 1043 { 1044 1045 if (rte_cryptodev_get_cipher_algo_enum(algo, optarg) < 0) { 1046 RTE_LOG(ERR, USER1, "Cipher algorithm specified " 1047 "not supported!\n"); 1048 return -1; 1049 } 1050 1051 return 0; 1052 } 1053 1054 /** Parse crypto cipher operation command line argument */ 1055 static int 1056 parse_cipher_op(enum rte_crypto_cipher_operation *op, char *optarg) 1057 { 1058 if (strcmp("ENCRYPT", optarg) == 0) { 1059 *op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1060 return 0; 1061 } else if (strcmp("DECRYPT", optarg) == 0) { 1062 *op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 1063 return 0; 1064 } 1065 1066 printf("Cipher operation not supported!\n"); 1067 return -1; 1068 } 1069 1070 /** Parse bytes from command line argument */ 1071 static int 1072 parse_bytes(uint8_t *data, char *input_arg, uint16_t max_size) 1073 { 1074 unsigned byte_count; 1075 char *token; 1076 1077 errno = 0; 1078 for (byte_count = 0, token = strtok(input_arg, ":"); 1079 (byte_count < max_size) && (token != NULL); 1080 token = strtok(NULL, ":")) { 1081 1082 int number = (int)strtol(token, NULL, 16); 1083 1084 if (errno == EINVAL || errno == ERANGE || number > 0xFF) 1085 return -1; 1086 1087 data[byte_count++] = (uint8_t)number; 1088 } 1089 1090 return byte_count; 1091 } 1092 1093 /** Parse size param*/ 1094 static int 1095 parse_size(int *size, const char *q_arg) 1096 { 1097 char *end = NULL; 1098 unsigned long n; 1099 1100 /* parse hexadecimal string */ 1101 n = strtoul(q_arg, &end, 10); 1102 if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1103 n = 0; 1104 1105 if (n == 0) { 1106 printf("invalid size\n"); 1107 return -1; 1108 } 1109 1110 *size = n; 1111 return 0; 1112 } 1113 1114 /** Parse crypto cipher operation command line argument */ 1115 static int 1116 parse_auth_algo(enum rte_crypto_auth_algorithm *algo, char *optarg) 1117 { 1118 if (rte_cryptodev_get_auth_algo_enum(algo, optarg) < 0) { 1119 RTE_LOG(ERR, USER1, "Authentication algorithm specified " 1120 "not supported!\n"); 1121 return -1; 1122 } 1123 1124 return 0; 1125 } 1126 1127 static int 1128 parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg) 1129 { 1130 if (strcmp("VERIFY", optarg) == 0) { 1131 *op = RTE_CRYPTO_AUTH_OP_VERIFY; 1132 return 0; 1133 } else if (strcmp("GENERATE", optarg) == 0) { 1134 *op = RTE_CRYPTO_AUTH_OP_GENERATE; 1135 return 0; 1136 } 1137 1138 printf("Authentication operation specified not supported!\n"); 1139 return -1; 1140 } 1141 1142 static int 1143 parse_aead_algo(enum rte_crypto_aead_algorithm *algo, char *optarg) 1144 { 1145 if (rte_cryptodev_get_aead_algo_enum(algo, optarg) < 0) { 1146 RTE_LOG(ERR, USER1, "AEAD algorithm specified " 1147 "not supported!\n"); 1148 return -1; 1149 } 1150 1151 return 0; 1152 } 1153 1154 static int 1155 parse_aead_op(enum rte_crypto_aead_operation *op, char *optarg) 1156 { 1157 if (strcmp("ENCRYPT", optarg) == 0) { 1158 *op = RTE_CRYPTO_AEAD_OP_ENCRYPT; 1159 return 0; 1160 } else if (strcmp("DECRYPT", optarg) == 0) { 1161 *op = RTE_CRYPTO_AEAD_OP_DECRYPT; 1162 return 0; 1163 } 1164 1165 printf("AEAD operation specified not supported!\n"); 1166 return -1; 1167 } 1168 static int 1169 parse_cryptodev_mask(struct l2fwd_crypto_options *options, 1170 const char *q_arg) 1171 { 1172 char *end = NULL; 1173 uint64_t pm; 1174 1175 /* parse hexadecimal string */ 1176 pm = strtoul(q_arg, &end, 16); 1177 if ((pm == '\0') || (end == NULL) || (*end != '\0')) 1178 pm = 0; 1179 1180 options->cryptodev_mask = pm; 1181 if (options->cryptodev_mask == 0) { 1182 printf("invalid cryptodev_mask specified\n"); 1183 return -1; 1184 } 1185 1186 return 0; 1187 } 1188 1189 /** Parse long options */ 1190 static int 1191 l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, 1192 struct option *lgopts, int option_index) 1193 { 1194 int retval; 1195 1196 if (strcmp(lgopts[option_index].name, "cdev_type") == 0) { 1197 retval = parse_cryptodev_type(&options->type, optarg); 1198 if (retval == 0) 1199 snprintf(options->string_type, MAX_STR_LEN, 1200 "%s", optarg); 1201 return retval; 1202 } 1203 1204 else if (strcmp(lgopts[option_index].name, "chain") == 0) 1205 return parse_crypto_opt_chain(options, optarg); 1206 1207 /* Cipher options */ 1208 else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0) 1209 return parse_cipher_algo(&options->cipher_xform.cipher.algo, 1210 optarg); 1211 1212 else if (strcmp(lgopts[option_index].name, "cipher_op") == 0) 1213 return parse_cipher_op(&options->cipher_xform.cipher.op, 1214 optarg); 1215 1216 else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) { 1217 options->ckey_param = 1; 1218 options->cipher_xform.cipher.key.length = 1219 parse_bytes(options->cipher_xform.cipher.key.data, optarg, 1220 MAX_KEY_SIZE); 1221 if (options->cipher_xform.cipher.key.length > 0) 1222 return 0; 1223 else 1224 return -1; 1225 } 1226 1227 else if (strcmp(lgopts[option_index].name, "cipher_key_random_size") == 0) 1228 return parse_size(&options->ckey_random_size, optarg); 1229 1230 else if (strcmp(lgopts[option_index].name, "cipher_iv") == 0) { 1231 options->cipher_iv_param = 1; 1232 options->cipher_iv.length = 1233 parse_bytes(options->cipher_iv.data, optarg, MAX_IV_SIZE); 1234 if (options->cipher_iv.length > 0) 1235 return 0; 1236 else 1237 return -1; 1238 } 1239 1240 else if (strcmp(lgopts[option_index].name, "cipher_iv_random_size") == 0) 1241 return parse_size(&options->cipher_iv_random_size, optarg); 1242 1243 /* Authentication options */ 1244 else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) { 1245 return parse_auth_algo(&options->auth_xform.auth.algo, 1246 optarg); 1247 } 1248 1249 else if (strcmp(lgopts[option_index].name, "auth_op") == 0) 1250 return parse_auth_op(&options->auth_xform.auth.op, 1251 optarg); 1252 1253 else if (strcmp(lgopts[option_index].name, "auth_key") == 0) { 1254 options->akey_param = 1; 1255 options->auth_xform.auth.key.length = 1256 parse_bytes(options->auth_xform.auth.key.data, optarg, 1257 MAX_KEY_SIZE); 1258 if (options->auth_xform.auth.key.length > 0) 1259 return 0; 1260 else 1261 return -1; 1262 } 1263 1264 else if (strcmp(lgopts[option_index].name, "auth_key_random_size") == 0) { 1265 return parse_size(&options->akey_random_size, optarg); 1266 } 1267 1268 else if (strcmp(lgopts[option_index].name, "auth_iv") == 0) { 1269 options->auth_iv_param = 1; 1270 options->auth_iv.length = 1271 parse_bytes(options->auth_iv.data, optarg, MAX_IV_SIZE); 1272 if (options->auth_iv.length > 0) 1273 return 0; 1274 else 1275 return -1; 1276 } 1277 1278 else if (strcmp(lgopts[option_index].name, "auth_iv_random_size") == 0) 1279 return parse_size(&options->auth_iv_random_size, optarg); 1280 1281 /* AEAD options */ 1282 else if (strcmp(lgopts[option_index].name, "aead_algo") == 0) { 1283 return parse_aead_algo(&options->aead_xform.aead.algo, 1284 optarg); 1285 } 1286 1287 else if (strcmp(lgopts[option_index].name, "aead_op") == 0) 1288 return parse_aead_op(&options->aead_xform.aead.op, 1289 optarg); 1290 1291 else if (strcmp(lgopts[option_index].name, "aead_key") == 0) { 1292 options->aead_key_param = 1; 1293 options->aead_xform.aead.key.length = 1294 parse_bytes(options->aead_xform.aead.key.data, optarg, 1295 MAX_KEY_SIZE); 1296 if (options->aead_xform.aead.key.length > 0) 1297 return 0; 1298 else 1299 return -1; 1300 } 1301 1302 else if (strcmp(lgopts[option_index].name, "aead_key_random_size") == 0) 1303 return parse_size(&options->aead_key_random_size, optarg); 1304 1305 1306 else if (strcmp(lgopts[option_index].name, "aead_iv") == 0) { 1307 options->aead_iv_param = 1; 1308 options->aead_iv.length = 1309 parse_bytes(options->aead_iv.data, optarg, MAX_IV_SIZE); 1310 if (options->aead_iv.length > 0) 1311 return 0; 1312 else 1313 return -1; 1314 } 1315 1316 else if (strcmp(lgopts[option_index].name, "aead_iv_random_size") == 0) 1317 return parse_size(&options->aead_iv_random_size, optarg); 1318 1319 else if (strcmp(lgopts[option_index].name, "aad") == 0) { 1320 options->aad_param = 1; 1321 options->aad.length = 1322 parse_bytes(options->aad.data, optarg, MAX_AAD_SIZE); 1323 if (options->aad.length > 0) 1324 return 0; 1325 else 1326 return -1; 1327 } 1328 1329 else if (strcmp(lgopts[option_index].name, "aad_random_size") == 0) { 1330 return parse_size(&options->aad_random_size, optarg); 1331 } 1332 1333 else if (strcmp(lgopts[option_index].name, "digest_size") == 0) { 1334 return parse_size(&options->digest_size, optarg); 1335 } 1336 1337 else if (strcmp(lgopts[option_index].name, "sessionless") == 0) { 1338 options->sessionless = 1; 1339 return 0; 1340 } 1341 1342 else if (strcmp(lgopts[option_index].name, "cryptodev_mask") == 0) 1343 return parse_cryptodev_mask(options, optarg); 1344 1345 else if (strcmp(lgopts[option_index].name, "mac-updating") == 0) { 1346 options->mac_updating = 1; 1347 return 0; 1348 } 1349 1350 else if (strcmp(lgopts[option_index].name, "no-mac-updating") == 0) { 1351 options->mac_updating = 0; 1352 return 0; 1353 } 1354 1355 return -1; 1356 } 1357 1358 /** Parse port mask */ 1359 static int 1360 l2fwd_crypto_parse_portmask(struct l2fwd_crypto_options *options, 1361 const char *q_arg) 1362 { 1363 char *end = NULL; 1364 unsigned long pm; 1365 1366 /* parse hexadecimal string */ 1367 pm = strtoul(q_arg, &end, 16); 1368 if ((pm == '\0') || (end == NULL) || (*end != '\0')) 1369 pm = 0; 1370 1371 options->portmask = pm; 1372 if (options->portmask == 0) { 1373 printf("invalid portmask specified\n"); 1374 return -1; 1375 } 1376 1377 return pm; 1378 } 1379 1380 /** Parse number of queues */ 1381 static int 1382 l2fwd_crypto_parse_nqueue(struct l2fwd_crypto_options *options, 1383 const char *q_arg) 1384 { 1385 char *end = NULL; 1386 unsigned long n; 1387 1388 /* parse hexadecimal string */ 1389 n = strtoul(q_arg, &end, 10); 1390 if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1391 n = 0; 1392 else if (n >= MAX_RX_QUEUE_PER_LCORE) 1393 n = 0; 1394 1395 options->nb_ports_per_lcore = n; 1396 if (options->nb_ports_per_lcore == 0) { 1397 printf("invalid number of ports selected\n"); 1398 return -1; 1399 } 1400 1401 return 0; 1402 } 1403 1404 /** Parse timer period */ 1405 static int 1406 l2fwd_crypto_parse_timer_period(struct l2fwd_crypto_options *options, 1407 const char *q_arg) 1408 { 1409 char *end = NULL; 1410 unsigned long n; 1411 1412 /* parse number string */ 1413 n = (unsigned)strtol(q_arg, &end, 10); 1414 if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1415 n = 0; 1416 1417 if (n >= MAX_TIMER_PERIOD) { 1418 printf("Warning refresh period specified %lu is greater than " 1419 "max value %lu! using max value", 1420 n, MAX_TIMER_PERIOD); 1421 n = MAX_TIMER_PERIOD; 1422 } 1423 1424 options->refresh_period = n * 1000 * TIMER_MILLISECOND; 1425 1426 return 0; 1427 } 1428 1429 /** Generate default options for application */ 1430 static void 1431 l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) 1432 { 1433 options->portmask = 0xffffffff; 1434 options->nb_ports_per_lcore = 1; 1435 options->refresh_period = 10000; 1436 options->single_lcore = 0; 1437 options->sessionless = 0; 1438 1439 options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 1440 1441 /* Cipher Data */ 1442 options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1443 options->cipher_xform.next = NULL; 1444 options->ckey_param = 0; 1445 options->ckey_random_size = -1; 1446 options->cipher_xform.cipher.key.length = 0; 1447 options->cipher_iv_param = 0; 1448 options->cipher_iv_random_size = -1; 1449 options->cipher_iv.length = 0; 1450 1451 options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; 1452 options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1453 1454 /* Authentication Data */ 1455 options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1456 options->auth_xform.next = NULL; 1457 options->akey_param = 0; 1458 options->akey_random_size = -1; 1459 options->auth_xform.auth.key.length = 0; 1460 options->auth_iv_param = 0; 1461 options->auth_iv_random_size = -1; 1462 options->auth_iv.length = 0; 1463 1464 options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; 1465 options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; 1466 1467 /* AEAD Data */ 1468 options->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1469 options->aead_xform.next = NULL; 1470 options->aead_key_param = 0; 1471 options->aead_key_random_size = -1; 1472 options->aead_xform.aead.key.length = 0; 1473 options->aead_iv_param = 0; 1474 options->aead_iv_random_size = -1; 1475 options->aead_iv.length = 0; 1476 1477 options->auth_xform.aead.algo = RTE_CRYPTO_AEAD_AES_GCM; 1478 options->auth_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT; 1479 1480 options->aad_param = 0; 1481 options->aad_random_size = -1; 1482 options->aad.length = 0; 1483 1484 options->digest_size = -1; 1485 1486 options->type = CDEV_TYPE_ANY; 1487 options->cryptodev_mask = UINT64_MAX; 1488 1489 options->mac_updating = 1; 1490 } 1491 1492 static void 1493 display_cipher_info(struct l2fwd_crypto_options *options) 1494 { 1495 printf("\n---- Cipher information ---\n"); 1496 printf("Algorithm: %s\n", 1497 rte_crypto_cipher_algorithm_strings[options->cipher_xform.cipher.algo]); 1498 rte_hexdump(stdout, "Cipher key:", 1499 options->cipher_xform.cipher.key.data, 1500 options->cipher_xform.cipher.key.length); 1501 rte_hexdump(stdout, "IV:", options->cipher_iv.data, options->cipher_iv.length); 1502 } 1503 1504 static void 1505 display_auth_info(struct l2fwd_crypto_options *options) 1506 { 1507 printf("\n---- Authentication information ---\n"); 1508 printf("Algorithm: %s\n", 1509 rte_crypto_auth_algorithm_strings[options->auth_xform.auth.algo]); 1510 rte_hexdump(stdout, "Auth key:", 1511 options->auth_xform.auth.key.data, 1512 options->auth_xform.auth.key.length); 1513 rte_hexdump(stdout, "IV:", options->auth_iv.data, options->auth_iv.length); 1514 } 1515 1516 static void 1517 display_aead_info(struct l2fwd_crypto_options *options) 1518 { 1519 printf("\n---- AEAD information ---\n"); 1520 printf("Algorithm: %s\n", 1521 rte_crypto_aead_algorithm_strings[options->aead_xform.aead.algo]); 1522 rte_hexdump(stdout, "AEAD key:", 1523 options->aead_xform.aead.key.data, 1524 options->aead_xform.aead.key.length); 1525 rte_hexdump(stdout, "IV:", options->aead_iv.data, options->aead_iv.length); 1526 rte_hexdump(stdout, "AAD:", options->aad.data, options->aad.length); 1527 } 1528 1529 static void 1530 l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) 1531 { 1532 char string_cipher_op[MAX_STR_LEN]; 1533 char string_auth_op[MAX_STR_LEN]; 1534 char string_aead_op[MAX_STR_LEN]; 1535 1536 if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 1537 strcpy(string_cipher_op, "Encrypt"); 1538 else 1539 strcpy(string_cipher_op, "Decrypt"); 1540 1541 if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) 1542 strcpy(string_auth_op, "Auth generate"); 1543 else 1544 strcpy(string_auth_op, "Auth verify"); 1545 1546 if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) 1547 strcpy(string_aead_op, "Authenticated encryption"); 1548 else 1549 strcpy(string_aead_op, "Authenticated decryption"); 1550 1551 1552 printf("Options:-\nn"); 1553 printf("portmask: %x\n", options->portmask); 1554 printf("ports per lcore: %u\n", options->nb_ports_per_lcore); 1555 printf("refresh period : %u\n", options->refresh_period); 1556 printf("single lcore mode: %s\n", 1557 options->single_lcore ? "enabled" : "disabled"); 1558 printf("stats_printing: %s\n", 1559 options->refresh_period == 0 ? "disabled" : "enabled"); 1560 1561 printf("sessionless crypto: %s\n", 1562 options->sessionless ? "enabled" : "disabled"); 1563 1564 if (options->ckey_param && (options->ckey_random_size != -1)) 1565 printf("Cipher key already parsed, ignoring size of random key\n"); 1566 1567 if (options->akey_param && (options->akey_random_size != -1)) 1568 printf("Auth key already parsed, ignoring size of random key\n"); 1569 1570 if (options->cipher_iv_param && (options->cipher_iv_random_size != -1)) 1571 printf("Cipher IV already parsed, ignoring size of random IV\n"); 1572 1573 if (options->auth_iv_param && (options->auth_iv_random_size != -1)) 1574 printf("Auth IV already parsed, ignoring size of random IV\n"); 1575 1576 if (options->aad_param && (options->aad_random_size != -1)) 1577 printf("AAD already parsed, ignoring size of random AAD\n"); 1578 1579 printf("\nCrypto chain: "); 1580 switch (options->xform_chain) { 1581 case L2FWD_CRYPTO_AEAD: 1582 printf("Input --> %s --> Output\n", string_aead_op); 1583 display_aead_info(options); 1584 break; 1585 case L2FWD_CRYPTO_CIPHER_HASH: 1586 printf("Input --> %s --> %s --> Output\n", 1587 string_cipher_op, string_auth_op); 1588 display_cipher_info(options); 1589 display_auth_info(options); 1590 break; 1591 case L2FWD_CRYPTO_HASH_CIPHER: 1592 printf("Input --> %s --> %s --> Output\n", 1593 string_auth_op, string_cipher_op); 1594 display_cipher_info(options); 1595 display_auth_info(options); 1596 break; 1597 case L2FWD_CRYPTO_HASH_ONLY: 1598 printf("Input --> %s --> Output\n", string_auth_op); 1599 display_auth_info(options); 1600 break; 1601 case L2FWD_CRYPTO_CIPHER_ONLY: 1602 printf("Input --> %s --> Output\n", string_cipher_op); 1603 display_cipher_info(options); 1604 break; 1605 } 1606 } 1607 1608 /* Parse the argument given in the command line of the application */ 1609 static int 1610 l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options, 1611 int argc, char **argv) 1612 { 1613 int opt, retval, option_index; 1614 char **argvopt = argv, *prgname = argv[0]; 1615 1616 static struct option lgopts[] = { 1617 { "sessionless", no_argument, 0, 0 }, 1618 1619 { "cdev_type", required_argument, 0, 0 }, 1620 { "chain", required_argument, 0, 0 }, 1621 1622 { "cipher_algo", required_argument, 0, 0 }, 1623 { "cipher_op", required_argument, 0, 0 }, 1624 { "cipher_key", required_argument, 0, 0 }, 1625 { "cipher_key_random_size", required_argument, 0, 0 }, 1626 { "cipher_iv", required_argument, 0, 0 }, 1627 { "cipher_iv_random_size", required_argument, 0, 0 }, 1628 1629 { "auth_algo", required_argument, 0, 0 }, 1630 { "auth_op", required_argument, 0, 0 }, 1631 { "auth_key", required_argument, 0, 0 }, 1632 { "auth_key_random_size", required_argument, 0, 0 }, 1633 { "auth_iv", required_argument, 0, 0 }, 1634 { "auth_iv_random_size", required_argument, 0, 0 }, 1635 1636 { "aead_algo", required_argument, 0, 0 }, 1637 { "aead_op", required_argument, 0, 0 }, 1638 { "aead_key", required_argument, 0, 0 }, 1639 { "aead_key_random_size", required_argument, 0, 0 }, 1640 { "aead_iv", required_argument, 0, 0 }, 1641 { "aead_iv_random_size", required_argument, 0, 0 }, 1642 1643 { "aad", required_argument, 0, 0 }, 1644 { "aad_random_size", required_argument, 0, 0 }, 1645 1646 { "digest_size", required_argument, 0, 0 }, 1647 1648 { "sessionless", no_argument, 0, 0 }, 1649 { "cryptodev_mask", required_argument, 0, 0}, 1650 1651 { "mac-updating", no_argument, 0, 0}, 1652 { "no-mac-updating", no_argument, 0, 0}, 1653 1654 { NULL, 0, 0, 0 } 1655 }; 1656 1657 l2fwd_crypto_default_options(options); 1658 1659 while ((opt = getopt_long(argc, argvopt, "p:q:sT:", lgopts, 1660 &option_index)) != EOF) { 1661 switch (opt) { 1662 /* long options */ 1663 case 0: 1664 retval = l2fwd_crypto_parse_args_long_options(options, 1665 lgopts, option_index); 1666 if (retval < 0) { 1667 l2fwd_crypto_usage(prgname); 1668 return -1; 1669 } 1670 break; 1671 1672 /* portmask */ 1673 case 'p': 1674 retval = l2fwd_crypto_parse_portmask(options, optarg); 1675 if (retval < 0) { 1676 l2fwd_crypto_usage(prgname); 1677 return -1; 1678 } 1679 break; 1680 1681 /* nqueue */ 1682 case 'q': 1683 retval = l2fwd_crypto_parse_nqueue(options, optarg); 1684 if (retval < 0) { 1685 l2fwd_crypto_usage(prgname); 1686 return -1; 1687 } 1688 break; 1689 1690 /* single */ 1691 case 's': 1692 options->single_lcore = 1; 1693 1694 break; 1695 1696 /* timer period */ 1697 case 'T': 1698 retval = l2fwd_crypto_parse_timer_period(options, 1699 optarg); 1700 if (retval < 0) { 1701 l2fwd_crypto_usage(prgname); 1702 return -1; 1703 } 1704 break; 1705 1706 default: 1707 l2fwd_crypto_usage(prgname); 1708 return -1; 1709 } 1710 } 1711 1712 1713 if (optind >= 0) 1714 argv[optind-1] = prgname; 1715 1716 retval = optind-1; 1717 optind = 1; /* reset getopt lib */ 1718 1719 return retval; 1720 } 1721 1722 /* Check the link status of all ports in up to 9s, and print them finally */ 1723 static void 1724 check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) 1725 { 1726 #define CHECK_INTERVAL 100 /* 100ms */ 1727 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1728 uint16_t portid; 1729 uint8_t count, all_ports_up, print_flag = 0; 1730 struct rte_eth_link link; 1731 1732 printf("\nChecking link status"); 1733 fflush(stdout); 1734 for (count = 0; count <= MAX_CHECK_TIME; count++) { 1735 all_ports_up = 1; 1736 for (portid = 0; portid < port_num; portid++) { 1737 if ((port_mask & (1 << portid)) == 0) 1738 continue; 1739 memset(&link, 0, sizeof(link)); 1740 rte_eth_link_get_nowait(portid, &link); 1741 /* print link status if flag set */ 1742 if (print_flag == 1) { 1743 if (link.link_status) 1744 printf( 1745 "Port%d Link Up. Speed %u Mbps - %s\n", 1746 portid, link.link_speed, 1747 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1748 ("full-duplex") : ("half-duplex\n")); 1749 else 1750 printf("Port %d Link Down\n", portid); 1751 continue; 1752 } 1753 /* clear all_ports_up flag if any link down */ 1754 if (link.link_status == ETH_LINK_DOWN) { 1755 all_ports_up = 0; 1756 break; 1757 } 1758 } 1759 /* after finally printing all link status, get out */ 1760 if (print_flag == 1) 1761 break; 1762 1763 if (all_ports_up == 0) { 1764 printf("."); 1765 fflush(stdout); 1766 rte_delay_ms(CHECK_INTERVAL); 1767 } 1768 1769 /* set the print_flag if all ports up or timeout */ 1770 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1771 print_flag = 1; 1772 printf("done\n"); 1773 } 1774 } 1775 } 1776 1777 /* Check if device has to be HW/SW or any */ 1778 static int 1779 check_type(const struct l2fwd_crypto_options *options, 1780 const struct rte_cryptodev_info *dev_info) 1781 { 1782 if (options->type == CDEV_TYPE_HW && 1783 (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 1784 return 0; 1785 if (options->type == CDEV_TYPE_SW && 1786 !(dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 1787 return 0; 1788 if (options->type == CDEV_TYPE_ANY) 1789 return 0; 1790 1791 return -1; 1792 } 1793 1794 static const struct rte_cryptodev_capabilities * 1795 check_device_support_cipher_algo(const struct l2fwd_crypto_options *options, 1796 const struct rte_cryptodev_info *dev_info, 1797 uint8_t cdev_id) 1798 { 1799 unsigned int i = 0; 1800 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1801 enum rte_crypto_cipher_algorithm cap_cipher_algo; 1802 enum rte_crypto_cipher_algorithm opt_cipher_algo = 1803 options->cipher_xform.cipher.algo; 1804 1805 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1806 cap_cipher_algo = cap->sym.cipher.algo; 1807 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 1808 if (cap_cipher_algo == opt_cipher_algo) { 1809 if (check_type(options, dev_info) == 0) 1810 break; 1811 } 1812 } 1813 cap = &dev_info->capabilities[++i]; 1814 } 1815 1816 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1817 printf("Algorithm %s not supported by cryptodev %u" 1818 " or device not of preferred type (%s)\n", 1819 rte_crypto_cipher_algorithm_strings[opt_cipher_algo], 1820 cdev_id, 1821 options->string_type); 1822 return NULL; 1823 } 1824 1825 return cap; 1826 } 1827 1828 static const struct rte_cryptodev_capabilities * 1829 check_device_support_auth_algo(const struct l2fwd_crypto_options *options, 1830 const struct rte_cryptodev_info *dev_info, 1831 uint8_t cdev_id) 1832 { 1833 unsigned int i = 0; 1834 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1835 enum rte_crypto_auth_algorithm cap_auth_algo; 1836 enum rte_crypto_auth_algorithm opt_auth_algo = 1837 options->auth_xform.auth.algo; 1838 1839 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1840 cap_auth_algo = cap->sym.auth.algo; 1841 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) { 1842 if (cap_auth_algo == opt_auth_algo) { 1843 if (check_type(options, dev_info) == 0) 1844 break; 1845 } 1846 } 1847 cap = &dev_info->capabilities[++i]; 1848 } 1849 1850 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1851 printf("Algorithm %s not supported by cryptodev %u" 1852 " or device not of preferred type (%s)\n", 1853 rte_crypto_auth_algorithm_strings[opt_auth_algo], 1854 cdev_id, 1855 options->string_type); 1856 return NULL; 1857 } 1858 1859 return cap; 1860 } 1861 1862 static const struct rte_cryptodev_capabilities * 1863 check_device_support_aead_algo(const struct l2fwd_crypto_options *options, 1864 const struct rte_cryptodev_info *dev_info, 1865 uint8_t cdev_id) 1866 { 1867 unsigned int i = 0; 1868 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1869 enum rte_crypto_aead_algorithm cap_aead_algo; 1870 enum rte_crypto_aead_algorithm opt_aead_algo = 1871 options->aead_xform.aead.algo; 1872 1873 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1874 cap_aead_algo = cap->sym.aead.algo; 1875 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) { 1876 if (cap_aead_algo == opt_aead_algo) { 1877 if (check_type(options, dev_info) == 0) 1878 break; 1879 } 1880 } 1881 cap = &dev_info->capabilities[++i]; 1882 } 1883 1884 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1885 printf("Algorithm %s not supported by cryptodev %u" 1886 " or device not of preferred type (%s)\n", 1887 rte_crypto_aead_algorithm_strings[opt_aead_algo], 1888 cdev_id, 1889 options->string_type); 1890 return NULL; 1891 } 1892 1893 return cap; 1894 } 1895 1896 /* Check if the device is enabled by cryptodev_mask */ 1897 static int 1898 check_cryptodev_mask(struct l2fwd_crypto_options *options, 1899 uint8_t cdev_id) 1900 { 1901 if (options->cryptodev_mask & (1 << cdev_id)) 1902 return 0; 1903 1904 return -1; 1905 } 1906 1907 static inline int 1908 check_supported_size(uint16_t length, uint16_t min, uint16_t max, 1909 uint16_t increment) 1910 { 1911 uint16_t supp_size; 1912 1913 /* Single value */ 1914 if (increment == 0) { 1915 if (length == min) 1916 return 0; 1917 else 1918 return -1; 1919 } 1920 1921 /* Range of values */ 1922 for (supp_size = min; supp_size <= max; supp_size += increment) { 1923 if (length == supp_size) 1924 return 0; 1925 } 1926 1927 return -1; 1928 } 1929 1930 static int 1931 check_iv_param(const struct rte_crypto_param_range *iv_range_size, 1932 unsigned int iv_param, int iv_random_size, 1933 uint16_t *iv_length) 1934 { 1935 /* 1936 * Check if length of provided IV is supported 1937 * by the algorithm chosen. 1938 */ 1939 if (iv_param) { 1940 if (check_supported_size(*iv_length, 1941 iv_range_size->min, 1942 iv_range_size->max, 1943 iv_range_size->increment) 1944 != 0) { 1945 printf("Unsupported IV length\n"); 1946 return -1; 1947 } 1948 /* 1949 * Check if length of IV to be randomly generated 1950 * is supported by the algorithm chosen. 1951 */ 1952 } else if (iv_random_size != -1) { 1953 if (check_supported_size(iv_random_size, 1954 iv_range_size->min, 1955 iv_range_size->max, 1956 iv_range_size->increment) 1957 != 0) { 1958 printf("Unsupported IV length\n"); 1959 return -1; 1960 } 1961 *iv_length = iv_random_size; 1962 /* No size provided, use minimum size. */ 1963 } else 1964 *iv_length = iv_range_size->min; 1965 1966 return 0; 1967 } 1968 1969 static int 1970 initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, 1971 uint8_t *enabled_cdevs) 1972 { 1973 unsigned int cdev_id, cdev_count, enabled_cdev_count = 0; 1974 const struct rte_cryptodev_capabilities *cap; 1975 unsigned int sess_sz, max_sess_sz = 0; 1976 int retval; 1977 1978 cdev_count = rte_cryptodev_count(); 1979 if (cdev_count == 0) { 1980 printf("No crypto devices available\n"); 1981 return -1; 1982 } 1983 1984 for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) { 1985 sess_sz = rte_cryptodev_get_private_session_size(cdev_id); 1986 if (sess_sz > max_sess_sz) 1987 max_sess_sz = sess_sz; 1988 } 1989 1990 for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports; 1991 cdev_id++) { 1992 struct rte_cryptodev_qp_conf qp_conf; 1993 struct rte_cryptodev_info dev_info; 1994 retval = rte_cryptodev_socket_id(cdev_id); 1995 1996 if (retval < 0) { 1997 printf("Invalid crypto device id used\n"); 1998 return -1; 1999 } 2000 2001 uint8_t socket_id = (uint8_t) retval; 2002 2003 struct rte_cryptodev_config conf = { 2004 .nb_queue_pairs = 1, 2005 .socket_id = socket_id, 2006 }; 2007 2008 if (check_cryptodev_mask(options, (uint8_t)cdev_id)) 2009 continue; 2010 2011 rte_cryptodev_info_get(cdev_id, &dev_info); 2012 2013 if (session_pool_socket[socket_id] == NULL) { 2014 char mp_name[RTE_MEMPOOL_NAMESIZE]; 2015 struct rte_mempool *sess_mp; 2016 2017 snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, 2018 "sess_mp_%u", socket_id); 2019 2020 /* 2021 * Create enough objects for session headers and 2022 * device private data 2023 */ 2024 sess_mp = rte_mempool_create(mp_name, 2025 MAX_SESSIONS * 2, 2026 max_sess_sz, 2027 SESSION_POOL_CACHE_SIZE, 2028 0, NULL, NULL, NULL, 2029 NULL, socket_id, 2030 0); 2031 2032 if (sess_mp == NULL) { 2033 printf("Cannot create session pool on socket %d\n", 2034 socket_id); 2035 return -ENOMEM; 2036 } 2037 2038 printf("Allocated session pool on socket %d\n", socket_id); 2039 session_pool_socket[socket_id] = sess_mp; 2040 } 2041 2042 /* Set AEAD parameters */ 2043 if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 2044 /* Check if device supports AEAD algo */ 2045 cap = check_device_support_aead_algo(options, &dev_info, 2046 cdev_id); 2047 if (cap == NULL) 2048 continue; 2049 2050 options->block_size = cap->sym.aead.block_size; 2051 2052 check_iv_param(&cap->sym.aead.iv_size, 2053 options->aead_iv_param, 2054 options->aead_iv_random_size, 2055 &options->aead_iv.length); 2056 2057 /* 2058 * Check if length of provided AEAD key is supported 2059 * by the algorithm chosen. 2060 */ 2061 if (options->aead_key_param) { 2062 if (check_supported_size( 2063 options->aead_xform.aead.key.length, 2064 cap->sym.aead.key_size.min, 2065 cap->sym.aead.key_size.max, 2066 cap->sym.aead.key_size.increment) 2067 != 0) { 2068 printf("Unsupported aead key length\n"); 2069 return -1; 2070 } 2071 /* 2072 * Check if length of the aead key to be randomly generated 2073 * is supported by the algorithm chosen. 2074 */ 2075 } else if (options->aead_key_random_size != -1) { 2076 if (check_supported_size(options->aead_key_random_size, 2077 cap->sym.aead.key_size.min, 2078 cap->sym.aead.key_size.max, 2079 cap->sym.aead.key_size.increment) 2080 != 0) { 2081 printf("Unsupported aead key length\n"); 2082 return -1; 2083 } 2084 options->aead_xform.aead.key.length = 2085 options->aead_key_random_size; 2086 /* No size provided, use minimum size. */ 2087 } else 2088 options->aead_xform.aead.key.length = 2089 cap->sym.aead.key_size.min; 2090 2091 if (!options->aead_key_param) 2092 generate_random_key( 2093 options->aead_xform.aead.key.data, 2094 options->aead_xform.aead.key.length); 2095 2096 /* 2097 * Check if length of provided AAD is supported 2098 * by the algorithm chosen. 2099 */ 2100 if (options->aad_param) { 2101 if (check_supported_size(options->aad.length, 2102 cap->sym.aead.aad_size.min, 2103 cap->sym.aead.aad_size.max, 2104 cap->sym.aead.aad_size.increment) 2105 != 0) { 2106 printf("Unsupported AAD length\n"); 2107 return -1; 2108 } 2109 /* 2110 * Check if length of AAD to be randomly generated 2111 * is supported by the algorithm chosen. 2112 */ 2113 } else if (options->aad_random_size != -1) { 2114 if (check_supported_size(options->aad_random_size, 2115 cap->sym.aead.aad_size.min, 2116 cap->sym.aead.aad_size.max, 2117 cap->sym.aead.aad_size.increment) 2118 != 0) { 2119 printf("Unsupported AAD length\n"); 2120 return -1; 2121 } 2122 options->aad.length = options->aad_random_size; 2123 /* No size provided, use minimum size. */ 2124 } else 2125 options->aad.length = cap->sym.auth.aad_size.min; 2126 2127 options->aead_xform.aead.aad_length = 2128 options->aad.length; 2129 2130 /* Check if digest size is supported by the algorithm. */ 2131 if (options->digest_size != -1) { 2132 if (check_supported_size(options->digest_size, 2133 cap->sym.aead.digest_size.min, 2134 cap->sym.aead.digest_size.max, 2135 cap->sym.aead.digest_size.increment) 2136 != 0) { 2137 printf("Unsupported digest length\n"); 2138 return -1; 2139 } 2140 options->aead_xform.aead.digest_length = 2141 options->digest_size; 2142 /* No size provided, use minimum size. */ 2143 } else 2144 options->aead_xform.aead.digest_length = 2145 cap->sym.aead.digest_size.min; 2146 } 2147 2148 /* Set cipher parameters */ 2149 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2150 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2151 options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 2152 /* Check if device supports cipher algo */ 2153 cap = check_device_support_cipher_algo(options, &dev_info, 2154 cdev_id); 2155 if (cap == NULL) 2156 continue; 2157 2158 options->block_size = cap->sym.cipher.block_size; 2159 2160 check_iv_param(&cap->sym.cipher.iv_size, 2161 options->cipher_iv_param, 2162 options->cipher_iv_random_size, 2163 &options->cipher_iv.length); 2164 2165 /* 2166 * Check if length of provided cipher key is supported 2167 * by the algorithm chosen. 2168 */ 2169 if (options->ckey_param) { 2170 if (check_supported_size( 2171 options->cipher_xform.cipher.key.length, 2172 cap->sym.cipher.key_size.min, 2173 cap->sym.cipher.key_size.max, 2174 cap->sym.cipher.key_size.increment) 2175 != 0) { 2176 printf("Unsupported cipher key length\n"); 2177 return -1; 2178 } 2179 /* 2180 * Check if length of the cipher key to be randomly generated 2181 * is supported by the algorithm chosen. 2182 */ 2183 } else if (options->ckey_random_size != -1) { 2184 if (check_supported_size(options->ckey_random_size, 2185 cap->sym.cipher.key_size.min, 2186 cap->sym.cipher.key_size.max, 2187 cap->sym.cipher.key_size.increment) 2188 != 0) { 2189 printf("Unsupported cipher key length\n"); 2190 return -1; 2191 } 2192 options->cipher_xform.cipher.key.length = 2193 options->ckey_random_size; 2194 /* No size provided, use minimum size. */ 2195 } else 2196 options->cipher_xform.cipher.key.length = 2197 cap->sym.cipher.key_size.min; 2198 2199 if (!options->ckey_param) 2200 generate_random_key( 2201 options->cipher_xform.cipher.key.data, 2202 options->cipher_xform.cipher.key.length); 2203 2204 } 2205 2206 /* Set auth parameters */ 2207 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2208 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2209 options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { 2210 /* Check if device supports auth algo */ 2211 cap = check_device_support_auth_algo(options, &dev_info, 2212 cdev_id); 2213 if (cap == NULL) 2214 continue; 2215 2216 check_iv_param(&cap->sym.auth.iv_size, 2217 options->auth_iv_param, 2218 options->auth_iv_random_size, 2219 &options->auth_iv.length); 2220 /* 2221 * Check if length of provided auth key is supported 2222 * by the algorithm chosen. 2223 */ 2224 if (options->akey_param) { 2225 if (check_supported_size( 2226 options->auth_xform.auth.key.length, 2227 cap->sym.auth.key_size.min, 2228 cap->sym.auth.key_size.max, 2229 cap->sym.auth.key_size.increment) 2230 != 0) { 2231 printf("Unsupported auth key length\n"); 2232 return -1; 2233 } 2234 /* 2235 * Check if length of the auth key to be randomly generated 2236 * is supported by the algorithm chosen. 2237 */ 2238 } else if (options->akey_random_size != -1) { 2239 if (check_supported_size(options->akey_random_size, 2240 cap->sym.auth.key_size.min, 2241 cap->sym.auth.key_size.max, 2242 cap->sym.auth.key_size.increment) 2243 != 0) { 2244 printf("Unsupported auth key length\n"); 2245 return -1; 2246 } 2247 options->auth_xform.auth.key.length = 2248 options->akey_random_size; 2249 /* No size provided, use minimum size. */ 2250 } else 2251 options->auth_xform.auth.key.length = 2252 cap->sym.auth.key_size.min; 2253 2254 if (!options->akey_param) 2255 generate_random_key( 2256 options->auth_xform.auth.key.data, 2257 options->auth_xform.auth.key.length); 2258 2259 /* Check if digest size is supported by the algorithm. */ 2260 if (options->digest_size != -1) { 2261 if (check_supported_size(options->digest_size, 2262 cap->sym.auth.digest_size.min, 2263 cap->sym.auth.digest_size.max, 2264 cap->sym.auth.digest_size.increment) 2265 != 0) { 2266 printf("Unsupported digest length\n"); 2267 return -1; 2268 } 2269 options->auth_xform.auth.digest_length = 2270 options->digest_size; 2271 /* No size provided, use minimum size. */ 2272 } else 2273 options->auth_xform.auth.digest_length = 2274 cap->sym.auth.digest_size.min; 2275 } 2276 2277 retval = rte_cryptodev_configure(cdev_id, &conf); 2278 if (retval < 0) { 2279 printf("Failed to configure cryptodev %u", cdev_id); 2280 return -1; 2281 } 2282 2283 qp_conf.nb_descriptors = 2048; 2284 2285 retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, 2286 socket_id, session_pool_socket[socket_id]); 2287 if (retval < 0) { 2288 printf("Failed to setup queue pair %u on cryptodev %u", 2289 0, cdev_id); 2290 return -1; 2291 } 2292 2293 retval = rte_cryptodev_start(cdev_id); 2294 if (retval < 0) { 2295 printf("Failed to start device %u: error %d\n", 2296 cdev_id, retval); 2297 return -1; 2298 } 2299 2300 l2fwd_enabled_crypto_mask |= (((uint64_t)1) << cdev_id); 2301 2302 enabled_cdevs[cdev_id] = 1; 2303 enabled_cdev_count++; 2304 } 2305 2306 return enabled_cdev_count; 2307 } 2308 2309 static int 2310 initialize_ports(struct l2fwd_crypto_options *options) 2311 { 2312 uint16_t last_portid, portid; 2313 unsigned enabled_portcount = 0; 2314 unsigned nb_ports = rte_eth_dev_count(); 2315 2316 if (nb_ports == 0) { 2317 printf("No Ethernet ports - bye\n"); 2318 return -1; 2319 } 2320 2321 /* Reset l2fwd_dst_ports */ 2322 for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) 2323 l2fwd_dst_ports[portid] = 0; 2324 2325 for (last_portid = 0, portid = 0; portid < nb_ports; portid++) { 2326 int retval; 2327 struct rte_eth_dev_info dev_info; 2328 struct rte_eth_rxconf rxq_conf; 2329 struct rte_eth_txconf txq_conf; 2330 struct rte_eth_conf local_port_conf = port_conf; 2331 2332 /* Skip ports that are not enabled */ 2333 if ((options->portmask & (1 << portid)) == 0) 2334 continue; 2335 2336 /* init port */ 2337 printf("Initializing port %u... ", portid); 2338 fflush(stdout); 2339 rte_eth_dev_info_get(portid, &dev_info); 2340 if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) 2341 local_port_conf.txmode.offloads |= 2342 DEV_TX_OFFLOAD_MBUF_FAST_FREE; 2343 retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); 2344 if (retval < 0) { 2345 printf("Cannot configure device: err=%d, port=%u\n", 2346 retval, portid); 2347 return -1; 2348 } 2349 2350 retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, 2351 &nb_txd); 2352 if (retval < 0) { 2353 printf("Cannot adjust number of descriptors: err=%d, port=%u\n", 2354 retval, portid); 2355 return -1; 2356 } 2357 2358 /* init one RX queue */ 2359 fflush(stdout); 2360 rxq_conf = dev_info.default_rxconf; 2361 rxq_conf.offloads = local_port_conf.rxmode.offloads; 2362 retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, 2363 rte_eth_dev_socket_id(portid), 2364 &rxq_conf, l2fwd_pktmbuf_pool); 2365 if (retval < 0) { 2366 printf("rte_eth_rx_queue_setup:err=%d, port=%u\n", 2367 retval, portid); 2368 return -1; 2369 } 2370 2371 /* init one TX queue on each port */ 2372 fflush(stdout); 2373 txq_conf = dev_info.default_txconf; 2374 txq_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE; 2375 txq_conf.offloads = local_port_conf.txmode.offloads; 2376 retval = rte_eth_tx_queue_setup(portid, 0, nb_txd, 2377 rte_eth_dev_socket_id(portid), 2378 &txq_conf); 2379 if (retval < 0) { 2380 printf("rte_eth_tx_queue_setup:err=%d, port=%u\n", 2381 retval, portid); 2382 2383 return -1; 2384 } 2385 2386 /* Start device */ 2387 retval = rte_eth_dev_start(portid); 2388 if (retval < 0) { 2389 printf("rte_eth_dev_start:err=%d, port=%u\n", 2390 retval, portid); 2391 return -1; 2392 } 2393 2394 rte_eth_promiscuous_enable(portid); 2395 2396 rte_eth_macaddr_get(portid, &l2fwd_ports_eth_addr[portid]); 2397 2398 printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", 2399 portid, 2400 l2fwd_ports_eth_addr[portid].addr_bytes[0], 2401 l2fwd_ports_eth_addr[portid].addr_bytes[1], 2402 l2fwd_ports_eth_addr[portid].addr_bytes[2], 2403 l2fwd_ports_eth_addr[portid].addr_bytes[3], 2404 l2fwd_ports_eth_addr[portid].addr_bytes[4], 2405 l2fwd_ports_eth_addr[portid].addr_bytes[5]); 2406 2407 /* initialize port stats */ 2408 memset(&port_statistics, 0, sizeof(port_statistics)); 2409 2410 /* Setup port forwarding table */ 2411 if (enabled_portcount % 2) { 2412 l2fwd_dst_ports[portid] = last_portid; 2413 l2fwd_dst_ports[last_portid] = portid; 2414 } else { 2415 last_portid = portid; 2416 } 2417 2418 l2fwd_enabled_port_mask |= (1 << portid); 2419 enabled_portcount++; 2420 } 2421 2422 if (enabled_portcount == 1) { 2423 l2fwd_dst_ports[last_portid] = last_portid; 2424 } else if (enabled_portcount % 2) { 2425 printf("odd number of ports in portmask- bye\n"); 2426 return -1; 2427 } 2428 2429 check_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask); 2430 2431 return enabled_portcount; 2432 } 2433 2434 static void 2435 reserve_key_memory(struct l2fwd_crypto_options *options) 2436 { 2437 options->cipher_xform.cipher.key.data = rte_malloc("crypto key", 2438 MAX_KEY_SIZE, 0); 2439 if (options->cipher_xform.cipher.key.data == NULL) 2440 rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key"); 2441 2442 options->auth_xform.auth.key.data = rte_malloc("auth key", 2443 MAX_KEY_SIZE, 0); 2444 if (options->auth_xform.auth.key.data == NULL) 2445 rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key"); 2446 2447 options->aead_xform.aead.key.data = rte_malloc("aead key", 2448 MAX_KEY_SIZE, 0); 2449 if (options->aead_xform.aead.key.data == NULL) 2450 rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD key"); 2451 2452 options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0); 2453 if (options->cipher_iv.data == NULL) 2454 rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher IV"); 2455 2456 options->auth_iv.data = rte_malloc("auth iv", MAX_KEY_SIZE, 0); 2457 if (options->auth_iv.data == NULL) 2458 rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth IV"); 2459 2460 options->aead_iv.data = rte_malloc("aead_iv", MAX_KEY_SIZE, 0); 2461 if (options->aead_iv.data == NULL) 2462 rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv"); 2463 2464 options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); 2465 if (options->aad.data == NULL) 2466 rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD"); 2467 options->aad.phys_addr = rte_malloc_virt2iova(options->aad.data); 2468 } 2469 2470 int 2471 main(int argc, char **argv) 2472 { 2473 struct lcore_queue_conf *qconf; 2474 struct l2fwd_crypto_options options; 2475 2476 uint8_t nb_cryptodevs, cdev_id; 2477 uint16_t nb_ports, portid; 2478 unsigned lcore_id, rx_lcore_id; 2479 int ret, enabled_cdevcount, enabled_portcount; 2480 uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS] = {0}; 2481 2482 /* init EAL */ 2483 ret = rte_eal_init(argc, argv); 2484 if (ret < 0) 2485 rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); 2486 argc -= ret; 2487 argv += ret; 2488 2489 /* reserve memory for Cipher/Auth key and IV */ 2490 reserve_key_memory(&options); 2491 2492 /* parse application arguments (after the EAL ones) */ 2493 ret = l2fwd_crypto_parse_args(&options, argc, argv); 2494 if (ret < 0) 2495 rte_exit(EXIT_FAILURE, "Invalid L2FWD-CRYPTO arguments\n"); 2496 2497 printf("MAC updating %s\n", 2498 options.mac_updating ? "enabled" : "disabled"); 2499 2500 /* create the mbuf pool */ 2501 l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512, 2502 sizeof(struct rte_crypto_op), 2503 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 2504 if (l2fwd_pktmbuf_pool == NULL) 2505 rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); 2506 2507 /* create crypto op pool */ 2508 l2fwd_crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool", 2509 RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, MAXIMUM_IV_LENGTH, 2510 rte_socket_id()); 2511 if (l2fwd_crypto_op_pool == NULL) 2512 rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n"); 2513 2514 /* Enable Ethernet ports */ 2515 enabled_portcount = initialize_ports(&options); 2516 if (enabled_portcount < 1) 2517 rte_exit(EXIT_FAILURE, "Failed to initial Ethernet ports\n"); 2518 2519 nb_ports = rte_eth_dev_count(); 2520 /* Initialize the port/queue configuration of each logical core */ 2521 for (rx_lcore_id = 0, qconf = NULL, portid = 0; 2522 portid < nb_ports; portid++) { 2523 2524 /* skip ports that are not enabled */ 2525 if ((options.portmask & (1 << portid)) == 0) 2526 continue; 2527 2528 if (options.single_lcore && qconf == NULL) { 2529 while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2530 rx_lcore_id++; 2531 if (rx_lcore_id >= RTE_MAX_LCORE) 2532 rte_exit(EXIT_FAILURE, 2533 "Not enough cores\n"); 2534 } 2535 } else if (!options.single_lcore) { 2536 /* get the lcore_id for this port */ 2537 while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2538 lcore_queue_conf[rx_lcore_id].nb_rx_ports == 2539 options.nb_ports_per_lcore) { 2540 rx_lcore_id++; 2541 if (rx_lcore_id >= RTE_MAX_LCORE) 2542 rte_exit(EXIT_FAILURE, 2543 "Not enough cores\n"); 2544 } 2545 } 2546 2547 /* Assigned a new logical core in the loop above. */ 2548 if (qconf != &lcore_queue_conf[rx_lcore_id]) 2549 qconf = &lcore_queue_conf[rx_lcore_id]; 2550 2551 qconf->rx_port_list[qconf->nb_rx_ports] = portid; 2552 qconf->nb_rx_ports++; 2553 2554 printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); 2555 } 2556 2557 /* Enable Crypto devices */ 2558 enabled_cdevcount = initialize_cryptodevs(&options, enabled_portcount, 2559 enabled_cdevs); 2560 if (enabled_cdevcount < 0) 2561 rte_exit(EXIT_FAILURE, "Failed to initialize crypto devices\n"); 2562 2563 if (enabled_cdevcount < enabled_portcount) 2564 rte_exit(EXIT_FAILURE, "Number of capable crypto devices (%d) " 2565 "has to be more or equal to number of ports (%d)\n", 2566 enabled_cdevcount, enabled_portcount); 2567 2568 nb_cryptodevs = rte_cryptodev_count(); 2569 2570 /* Initialize the port/cryptodev configuration of each logical core */ 2571 for (rx_lcore_id = 0, qconf = NULL, cdev_id = 0; 2572 cdev_id < nb_cryptodevs && enabled_cdevcount; 2573 cdev_id++) { 2574 /* Crypto op not supported by crypto device */ 2575 if (!enabled_cdevs[cdev_id]) 2576 continue; 2577 2578 if (options.single_lcore && qconf == NULL) { 2579 while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2580 rx_lcore_id++; 2581 if (rx_lcore_id >= RTE_MAX_LCORE) 2582 rte_exit(EXIT_FAILURE, 2583 "Not enough cores\n"); 2584 } 2585 } else if (!options.single_lcore) { 2586 /* get the lcore_id for this port */ 2587 while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2588 lcore_queue_conf[rx_lcore_id].nb_crypto_devs == 2589 options.nb_ports_per_lcore) { 2590 rx_lcore_id++; 2591 if (rx_lcore_id >= RTE_MAX_LCORE) 2592 rte_exit(EXIT_FAILURE, 2593 "Not enough cores\n"); 2594 } 2595 } 2596 2597 /* Assigned a new logical core in the loop above. */ 2598 if (qconf != &lcore_queue_conf[rx_lcore_id]) 2599 qconf = &lcore_queue_conf[rx_lcore_id]; 2600 2601 qconf->cryptodev_list[qconf->nb_crypto_devs] = cdev_id; 2602 qconf->nb_crypto_devs++; 2603 2604 enabled_cdevcount--; 2605 2606 printf("Lcore %u: cryptodev %u\n", rx_lcore_id, 2607 (unsigned)cdev_id); 2608 } 2609 2610 /* launch per-lcore init on every lcore */ 2611 rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, (void *)&options, 2612 CALL_MASTER); 2613 RTE_LCORE_FOREACH_SLAVE(lcore_id) { 2614 if (rte_eal_wait_lcore(lcore_id) < 0) 2615 return -1; 2616 } 2617 2618 return 0; 2619 } 2620