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