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