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 int ret; 1735 1736 printf("\nChecking link status"); 1737 fflush(stdout); 1738 for (count = 0; count <= MAX_CHECK_TIME; count++) { 1739 all_ports_up = 1; 1740 RTE_ETH_FOREACH_DEV(portid) { 1741 if ((port_mask & (1 << portid)) == 0) 1742 continue; 1743 memset(&link, 0, sizeof(link)); 1744 ret = rte_eth_link_get_nowait(portid, &link); 1745 if (ret < 0) { 1746 all_ports_up = 0; 1747 if (print_flag == 1) 1748 printf("Port %u link get failed: %s\n", 1749 portid, rte_strerror(-ret)); 1750 continue; 1751 } 1752 /* print link status if flag set */ 1753 if (print_flag == 1) { 1754 if (link.link_status) 1755 printf( 1756 "Port%d Link Up. Speed %u Mbps - %s\n", 1757 portid, link.link_speed, 1758 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1759 ("full-duplex") : ("half-duplex\n")); 1760 else 1761 printf("Port %d Link Down\n", portid); 1762 continue; 1763 } 1764 /* clear all_ports_up flag if any link down */ 1765 if (link.link_status == ETH_LINK_DOWN) { 1766 all_ports_up = 0; 1767 break; 1768 } 1769 } 1770 /* after finally printing all link status, get out */ 1771 if (print_flag == 1) 1772 break; 1773 1774 if (all_ports_up == 0) { 1775 printf("."); 1776 fflush(stdout); 1777 rte_delay_ms(CHECK_INTERVAL); 1778 } 1779 1780 /* set the print_flag if all ports up or timeout */ 1781 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1782 print_flag = 1; 1783 printf("done\n"); 1784 } 1785 } 1786 } 1787 1788 /* Check if device has to be HW/SW or any */ 1789 static int 1790 check_type(const struct l2fwd_crypto_options *options, 1791 const struct rte_cryptodev_info *dev_info) 1792 { 1793 if (options->type == CDEV_TYPE_HW && 1794 (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 1795 return 0; 1796 if (options->type == CDEV_TYPE_SW && 1797 !(dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 1798 return 0; 1799 if (options->type == CDEV_TYPE_ANY) 1800 return 0; 1801 1802 return -1; 1803 } 1804 1805 static const struct rte_cryptodev_capabilities * 1806 check_device_support_cipher_algo(const struct l2fwd_crypto_options *options, 1807 const struct rte_cryptodev_info *dev_info, 1808 uint8_t cdev_id) 1809 { 1810 unsigned int i = 0; 1811 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1812 enum rte_crypto_cipher_algorithm cap_cipher_algo; 1813 enum rte_crypto_cipher_algorithm opt_cipher_algo = 1814 options->cipher_xform.cipher.algo; 1815 1816 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1817 cap_cipher_algo = cap->sym.cipher.algo; 1818 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 1819 if (cap_cipher_algo == opt_cipher_algo) { 1820 if (check_type(options, dev_info) == 0) 1821 break; 1822 } 1823 } 1824 cap = &dev_info->capabilities[++i]; 1825 } 1826 1827 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1828 printf("Algorithm %s not supported by cryptodev %u" 1829 " or device not of preferred type (%s)\n", 1830 rte_crypto_cipher_algorithm_strings[opt_cipher_algo], 1831 cdev_id, 1832 options->string_type); 1833 return NULL; 1834 } 1835 1836 return cap; 1837 } 1838 1839 static const struct rte_cryptodev_capabilities * 1840 check_device_support_auth_algo(const struct l2fwd_crypto_options *options, 1841 const struct rte_cryptodev_info *dev_info, 1842 uint8_t cdev_id) 1843 { 1844 unsigned int i = 0; 1845 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1846 enum rte_crypto_auth_algorithm cap_auth_algo; 1847 enum rte_crypto_auth_algorithm opt_auth_algo = 1848 options->auth_xform.auth.algo; 1849 1850 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1851 cap_auth_algo = cap->sym.auth.algo; 1852 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) { 1853 if (cap_auth_algo == opt_auth_algo) { 1854 if (check_type(options, dev_info) == 0) 1855 break; 1856 } 1857 } 1858 cap = &dev_info->capabilities[++i]; 1859 } 1860 1861 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1862 printf("Algorithm %s not supported by cryptodev %u" 1863 " or device not of preferred type (%s)\n", 1864 rte_crypto_auth_algorithm_strings[opt_auth_algo], 1865 cdev_id, 1866 options->string_type); 1867 return NULL; 1868 } 1869 1870 return cap; 1871 } 1872 1873 static const struct rte_cryptodev_capabilities * 1874 check_device_support_aead_algo(const struct l2fwd_crypto_options *options, 1875 const struct rte_cryptodev_info *dev_info, 1876 uint8_t cdev_id) 1877 { 1878 unsigned int i = 0; 1879 const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 1880 enum rte_crypto_aead_algorithm cap_aead_algo; 1881 enum rte_crypto_aead_algorithm opt_aead_algo = 1882 options->aead_xform.aead.algo; 1883 1884 while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1885 cap_aead_algo = cap->sym.aead.algo; 1886 if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) { 1887 if (cap_aead_algo == opt_aead_algo) { 1888 if (check_type(options, dev_info) == 0) 1889 break; 1890 } 1891 } 1892 cap = &dev_info->capabilities[++i]; 1893 } 1894 1895 if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 1896 printf("Algorithm %s not supported by cryptodev %u" 1897 " or device not of preferred type (%s)\n", 1898 rte_crypto_aead_algorithm_strings[opt_aead_algo], 1899 cdev_id, 1900 options->string_type); 1901 return NULL; 1902 } 1903 1904 return cap; 1905 } 1906 1907 /* Check if the device is enabled by cryptodev_mask */ 1908 static int 1909 check_cryptodev_mask(struct l2fwd_crypto_options *options, 1910 uint8_t cdev_id) 1911 { 1912 if (options->cryptodev_mask & (1 << cdev_id)) 1913 return 0; 1914 1915 return -1; 1916 } 1917 1918 static inline int 1919 check_supported_size(uint16_t length, uint16_t min, uint16_t max, 1920 uint16_t increment) 1921 { 1922 uint16_t supp_size; 1923 1924 /* Single value */ 1925 if (increment == 0) { 1926 if (length == min) 1927 return 0; 1928 else 1929 return -1; 1930 } 1931 1932 /* Range of values */ 1933 for (supp_size = min; supp_size <= max; supp_size += increment) { 1934 if (length == supp_size) 1935 return 0; 1936 } 1937 1938 return -1; 1939 } 1940 1941 static int 1942 check_iv_param(const struct rte_crypto_param_range *iv_range_size, 1943 unsigned int iv_param, int iv_random_size, 1944 uint16_t iv_length) 1945 { 1946 /* 1947 * Check if length of provided IV is supported 1948 * by the algorithm chosen. 1949 */ 1950 if (iv_param) { 1951 if (check_supported_size(iv_length, 1952 iv_range_size->min, 1953 iv_range_size->max, 1954 iv_range_size->increment) 1955 != 0) 1956 return -1; 1957 /* 1958 * Check if length of IV to be randomly generated 1959 * is supported by the algorithm chosen. 1960 */ 1961 } else if (iv_random_size != -1) { 1962 if (check_supported_size(iv_random_size, 1963 iv_range_size->min, 1964 iv_range_size->max, 1965 iv_range_size->increment) 1966 != 0) 1967 return -1; 1968 } 1969 1970 return 0; 1971 } 1972 1973 static int 1974 check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id) 1975 { 1976 struct rte_cryptodev_info dev_info; 1977 const struct rte_cryptodev_capabilities *cap; 1978 1979 rte_cryptodev_info_get(cdev_id, &dev_info); 1980 1981 /* Set AEAD parameters */ 1982 if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 1983 /* Check if device supports AEAD algo */ 1984 cap = check_device_support_aead_algo(options, &dev_info, 1985 cdev_id); 1986 if (cap == NULL) 1987 return -1; 1988 1989 if (check_iv_param(&cap->sym.aead.iv_size, 1990 options->aead_iv_param, 1991 options->aead_iv_random_size, 1992 options->aead_iv.length) != 0) { 1993 RTE_LOG(DEBUG, USER1, 1994 "Device %u does not support IV length\n", 1995 cdev_id); 1996 return -1; 1997 } 1998 1999 /* 2000 * Check if length of provided AEAD key is supported 2001 * by the algorithm chosen. 2002 */ 2003 if (options->aead_key_param) { 2004 if (check_supported_size( 2005 options->aead_xform.aead.key.length, 2006 cap->sym.aead.key_size.min, 2007 cap->sym.aead.key_size.max, 2008 cap->sym.aead.key_size.increment) 2009 != 0) { 2010 RTE_LOG(DEBUG, USER1, 2011 "Device %u does not support " 2012 "AEAD key length\n", 2013 cdev_id); 2014 return -1; 2015 } 2016 /* 2017 * Check if length of the aead key to be randomly generated 2018 * is supported by the algorithm chosen. 2019 */ 2020 } else if (options->aead_key_random_size != -1) { 2021 if (check_supported_size(options->aead_key_random_size, 2022 cap->sym.aead.key_size.min, 2023 cap->sym.aead.key_size.max, 2024 cap->sym.aead.key_size.increment) 2025 != 0) { 2026 RTE_LOG(DEBUG, USER1, 2027 "Device %u does not support " 2028 "AEAD key length\n", 2029 cdev_id); 2030 return -1; 2031 } 2032 } 2033 2034 2035 /* 2036 * Check if length of provided AAD is supported 2037 * by the algorithm chosen. 2038 */ 2039 if (options->aad_param) { 2040 if (check_supported_size(options->aad.length, 2041 cap->sym.aead.aad_size.min, 2042 cap->sym.aead.aad_size.max, 2043 cap->sym.aead.aad_size.increment) 2044 != 0) { 2045 RTE_LOG(DEBUG, USER1, 2046 "Device %u does not support " 2047 "AAD length\n", 2048 cdev_id); 2049 return -1; 2050 } 2051 /* 2052 * Check if length of AAD to be randomly generated 2053 * is supported by the algorithm chosen. 2054 */ 2055 } else if (options->aad_random_size != -1) { 2056 if (check_supported_size(options->aad_random_size, 2057 cap->sym.aead.aad_size.min, 2058 cap->sym.aead.aad_size.max, 2059 cap->sym.aead.aad_size.increment) 2060 != 0) { 2061 RTE_LOG(DEBUG, USER1, 2062 "Device %u does not support " 2063 "AAD length\n", 2064 cdev_id); 2065 return -1; 2066 } 2067 } 2068 2069 /* Check if digest size is supported by the algorithm. */ 2070 if (options->digest_size != -1) { 2071 if (check_supported_size(options->digest_size, 2072 cap->sym.aead.digest_size.min, 2073 cap->sym.aead.digest_size.max, 2074 cap->sym.aead.digest_size.increment) 2075 != 0) { 2076 RTE_LOG(DEBUG, USER1, 2077 "Device %u does not support " 2078 "digest length\n", 2079 cdev_id); 2080 return -1; 2081 } 2082 } 2083 } 2084 2085 /* Set cipher parameters */ 2086 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2087 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2088 options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 2089 /* Check if device supports cipher algo */ 2090 cap = check_device_support_cipher_algo(options, &dev_info, 2091 cdev_id); 2092 if (cap == NULL) 2093 return -1; 2094 2095 if (check_iv_param(&cap->sym.cipher.iv_size, 2096 options->cipher_iv_param, 2097 options->cipher_iv_random_size, 2098 options->cipher_iv.length) != 0) { 2099 RTE_LOG(DEBUG, USER1, 2100 "Device %u does not support IV length\n", 2101 cdev_id); 2102 return -1; 2103 } 2104 2105 /* 2106 * Check if length of provided cipher key is supported 2107 * by the algorithm chosen. 2108 */ 2109 if (options->ckey_param) { 2110 if (check_supported_size( 2111 options->cipher_xform.cipher.key.length, 2112 cap->sym.cipher.key_size.min, 2113 cap->sym.cipher.key_size.max, 2114 cap->sym.cipher.key_size.increment) 2115 != 0) { 2116 RTE_LOG(DEBUG, USER1, 2117 "Device %u does not support cipher " 2118 "key length\n", 2119 cdev_id); 2120 return -1; 2121 } 2122 /* 2123 * Check if length of the cipher key to be randomly generated 2124 * is supported by the algorithm chosen. 2125 */ 2126 } else if (options->ckey_random_size != -1) { 2127 if (check_supported_size(options->ckey_random_size, 2128 cap->sym.cipher.key_size.min, 2129 cap->sym.cipher.key_size.max, 2130 cap->sym.cipher.key_size.increment) 2131 != 0) { 2132 RTE_LOG(DEBUG, USER1, 2133 "Device %u does not support cipher " 2134 "key length\n", 2135 cdev_id); 2136 return -1; 2137 } 2138 } 2139 } 2140 2141 /* Set auth parameters */ 2142 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2143 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2144 options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { 2145 /* Check if device supports auth algo */ 2146 cap = check_device_support_auth_algo(options, &dev_info, 2147 cdev_id); 2148 if (cap == NULL) 2149 return -1; 2150 2151 if (check_iv_param(&cap->sym.auth.iv_size, 2152 options->auth_iv_param, 2153 options->auth_iv_random_size, 2154 options->auth_iv.length) != 0) { 2155 RTE_LOG(DEBUG, USER1, 2156 "Device %u does not support IV length\n", 2157 cdev_id); 2158 return -1; 2159 } 2160 /* 2161 * Check if length of provided auth key is supported 2162 * by the algorithm chosen. 2163 */ 2164 if (options->akey_param) { 2165 if (check_supported_size( 2166 options->auth_xform.auth.key.length, 2167 cap->sym.auth.key_size.min, 2168 cap->sym.auth.key_size.max, 2169 cap->sym.auth.key_size.increment) 2170 != 0) { 2171 RTE_LOG(DEBUG, USER1, 2172 "Device %u does not support auth " 2173 "key length\n", 2174 cdev_id); 2175 return -1; 2176 } 2177 /* 2178 * Check if length of the auth key to be randomly generated 2179 * is supported by the algorithm chosen. 2180 */ 2181 } else if (options->akey_random_size != -1) { 2182 if (check_supported_size(options->akey_random_size, 2183 cap->sym.auth.key_size.min, 2184 cap->sym.auth.key_size.max, 2185 cap->sym.auth.key_size.increment) 2186 != 0) { 2187 RTE_LOG(DEBUG, USER1, 2188 "Device %u does not support auth " 2189 "key length\n", 2190 cdev_id); 2191 return -1; 2192 } 2193 } 2194 2195 /* Check if digest size is supported by the algorithm. */ 2196 if (options->digest_size != -1) { 2197 if (check_supported_size(options->digest_size, 2198 cap->sym.auth.digest_size.min, 2199 cap->sym.auth.digest_size.max, 2200 cap->sym.auth.digest_size.increment) 2201 != 0) { 2202 RTE_LOG(DEBUG, USER1, 2203 "Device %u does not support " 2204 "digest length\n", 2205 cdev_id); 2206 return -1; 2207 } 2208 } 2209 } 2210 2211 return 0; 2212 } 2213 2214 static int 2215 initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, 2216 uint8_t *enabled_cdevs) 2217 { 2218 uint8_t cdev_id, cdev_count, enabled_cdev_count = 0; 2219 const struct rte_cryptodev_capabilities *cap; 2220 unsigned int sess_sz, max_sess_sz = 0; 2221 uint32_t sessions_needed = 0; 2222 int retval; 2223 2224 cdev_count = rte_cryptodev_count(); 2225 if (cdev_count == 0) { 2226 printf("No crypto devices available\n"); 2227 return -1; 2228 } 2229 2230 for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports; 2231 cdev_id++) { 2232 if (check_cryptodev_mask(options, cdev_id) < 0) 2233 continue; 2234 2235 if (check_capabilities(options, cdev_id) < 0) 2236 continue; 2237 2238 sess_sz = rte_cryptodev_sym_get_private_session_size(cdev_id); 2239 if (sess_sz > max_sess_sz) 2240 max_sess_sz = sess_sz; 2241 2242 l2fwd_enabled_crypto_mask |= (((uint64_t)1) << cdev_id); 2243 2244 enabled_cdevs[cdev_id] = 1; 2245 enabled_cdev_count++; 2246 } 2247 2248 for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) { 2249 struct rte_cryptodev_qp_conf qp_conf; 2250 struct rte_cryptodev_info dev_info; 2251 2252 if (enabled_cdevs[cdev_id] == 0) 2253 continue; 2254 2255 retval = rte_cryptodev_socket_id(cdev_id); 2256 2257 if (retval < 0) { 2258 printf("Invalid crypto device id used\n"); 2259 return -1; 2260 } 2261 2262 uint8_t socket_id = (uint8_t) retval; 2263 2264 struct rte_cryptodev_config conf = { 2265 .nb_queue_pairs = 1, 2266 .socket_id = socket_id, 2267 .ff_disable = RTE_CRYPTODEV_FF_SECURITY, 2268 }; 2269 2270 rte_cryptodev_info_get(cdev_id, &dev_info); 2271 2272 /* 2273 * Two sessions objects are required for each session 2274 * (one for the header, one for the private data) 2275 */ 2276 if (!strcmp(dev_info.driver_name, "crypto_scheduler")) { 2277 #ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER 2278 uint32_t nb_slaves = 2279 rte_cryptodev_scheduler_slaves_get(cdev_id, 2280 NULL); 2281 2282 sessions_needed = enabled_cdev_count * nb_slaves; 2283 #endif 2284 } else 2285 sessions_needed = enabled_cdev_count; 2286 2287 if (session_pool_socket[socket_id].priv_mp == NULL) { 2288 char mp_name[RTE_MEMPOOL_NAMESIZE]; 2289 2290 snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, 2291 "priv_sess_mp_%u", socket_id); 2292 2293 session_pool_socket[socket_id].priv_mp = 2294 rte_mempool_create(mp_name, 2295 sessions_needed, 2296 max_sess_sz, 2297 0, 0, NULL, NULL, NULL, 2298 NULL, socket_id, 2299 0); 2300 2301 if (session_pool_socket[socket_id].priv_mp == NULL) { 2302 printf("Cannot create pool on socket %d\n", 2303 socket_id); 2304 return -ENOMEM; 2305 } 2306 2307 printf("Allocated pool \"%s\" on socket %d\n", 2308 mp_name, socket_id); 2309 } 2310 2311 if (session_pool_socket[socket_id].sess_mp == NULL) { 2312 char mp_name[RTE_MEMPOOL_NAMESIZE]; 2313 snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, 2314 "sess_mp_%u", socket_id); 2315 2316 session_pool_socket[socket_id].sess_mp = 2317 rte_cryptodev_sym_session_pool_create( 2318 mp_name, 2319 sessions_needed, 2320 0, 0, 0, socket_id); 2321 2322 if (session_pool_socket[socket_id].sess_mp == NULL) { 2323 printf("Cannot create pool on socket %d\n", 2324 socket_id); 2325 return -ENOMEM; 2326 } 2327 2328 printf("Allocated pool \"%s\" on socket %d\n", 2329 mp_name, socket_id); 2330 } 2331 2332 /* Set AEAD parameters */ 2333 if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 2334 cap = check_device_support_aead_algo(options, &dev_info, 2335 cdev_id); 2336 2337 options->block_size = cap->sym.aead.block_size; 2338 2339 /* Set IV if not provided from command line */ 2340 if (options->aead_iv_param == 0) { 2341 if (options->aead_iv_random_size != -1) 2342 options->aead_iv.length = 2343 options->aead_iv_random_size; 2344 /* No size provided, use minimum size. */ 2345 else 2346 options->aead_iv.length = 2347 cap->sym.aead.iv_size.min; 2348 } 2349 2350 /* Set key if not provided from command line */ 2351 if (options->aead_key_param == 0) { 2352 if (options->aead_key_random_size != -1) 2353 options->aead_xform.aead.key.length = 2354 options->aead_key_random_size; 2355 /* No size provided, use minimum size. */ 2356 else 2357 options->aead_xform.aead.key.length = 2358 cap->sym.aead.key_size.min; 2359 2360 generate_random_key(options->aead_key, 2361 options->aead_xform.aead.key.length); 2362 } 2363 2364 /* Set AAD if not provided from command line */ 2365 if (options->aad_param == 0) { 2366 if (options->aad_random_size != -1) 2367 options->aad.length = 2368 options->aad_random_size; 2369 /* No size provided, use minimum size. */ 2370 else 2371 options->aad.length = 2372 cap->sym.auth.aad_size.min; 2373 } 2374 2375 options->aead_xform.aead.aad_length = 2376 options->aad.length; 2377 2378 /* Set digest size if not provided from command line */ 2379 if (options->digest_size != -1) 2380 options->aead_xform.aead.digest_length = 2381 options->digest_size; 2382 /* No size provided, use minimum size. */ 2383 else 2384 options->aead_xform.aead.digest_length = 2385 cap->sym.aead.digest_size.min; 2386 } 2387 2388 /* Set cipher parameters */ 2389 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2390 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2391 options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 2392 cap = check_device_support_cipher_algo(options, &dev_info, 2393 cdev_id); 2394 options->block_size = cap->sym.cipher.block_size; 2395 2396 /* Set IV if not provided from command line */ 2397 if (options->cipher_iv_param == 0) { 2398 if (options->cipher_iv_random_size != -1) 2399 options->cipher_iv.length = 2400 options->cipher_iv_random_size; 2401 /* No size provided, use minimum size. */ 2402 else 2403 options->cipher_iv.length = 2404 cap->sym.cipher.iv_size.min; 2405 } 2406 2407 /* Set key if not provided from command line */ 2408 if (options->ckey_param == 0) { 2409 if (options->ckey_random_size != -1) 2410 options->cipher_xform.cipher.key.length = 2411 options->ckey_random_size; 2412 /* No size provided, use minimum size. */ 2413 else 2414 options->cipher_xform.cipher.key.length = 2415 cap->sym.cipher.key_size.min; 2416 2417 generate_random_key(options->cipher_key, 2418 options->cipher_xform.cipher.key.length); 2419 } 2420 } 2421 2422 /* Set auth parameters */ 2423 if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 2424 options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 2425 options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { 2426 cap = check_device_support_auth_algo(options, &dev_info, 2427 cdev_id); 2428 2429 /* Set IV if not provided from command line */ 2430 if (options->auth_iv_param == 0) { 2431 if (options->auth_iv_random_size != -1) 2432 options->auth_iv.length = 2433 options->auth_iv_random_size; 2434 /* No size provided, use minimum size. */ 2435 else 2436 options->auth_iv.length = 2437 cap->sym.auth.iv_size.min; 2438 } 2439 2440 /* Set key if not provided from command line */ 2441 if (options->akey_param == 0) { 2442 if (options->akey_random_size != -1) 2443 options->auth_xform.auth.key.length = 2444 options->akey_random_size; 2445 /* No size provided, use minimum size. */ 2446 else 2447 options->auth_xform.auth.key.length = 2448 cap->sym.auth.key_size.min; 2449 2450 generate_random_key(options->auth_key, 2451 options->auth_xform.auth.key.length); 2452 } 2453 2454 /* Set digest size if not provided from command line */ 2455 if (options->digest_size != -1) 2456 options->auth_xform.auth.digest_length = 2457 options->digest_size; 2458 /* No size provided, use minimum size. */ 2459 else 2460 options->auth_xform.auth.digest_length = 2461 cap->sym.auth.digest_size.min; 2462 } 2463 2464 retval = rte_cryptodev_configure(cdev_id, &conf); 2465 if (retval < 0) { 2466 printf("Failed to configure cryptodev %u", cdev_id); 2467 return -1; 2468 } 2469 2470 qp_conf.nb_descriptors = 2048; 2471 qp_conf.mp_session = session_pool_socket[socket_id].sess_mp; 2472 qp_conf.mp_session_private = 2473 session_pool_socket[socket_id].priv_mp; 2474 2475 retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, 2476 socket_id); 2477 if (retval < 0) { 2478 printf("Failed to setup queue pair %u on cryptodev %u", 2479 0, cdev_id); 2480 return -1; 2481 } 2482 2483 retval = rte_cryptodev_start(cdev_id); 2484 if (retval < 0) { 2485 printf("Failed to start device %u: error %d\n", 2486 cdev_id, retval); 2487 return -1; 2488 } 2489 } 2490 2491 return enabled_cdev_count; 2492 } 2493 2494 static int 2495 initialize_ports(struct l2fwd_crypto_options *options) 2496 { 2497 uint16_t last_portid = 0, portid; 2498 unsigned enabled_portcount = 0; 2499 unsigned nb_ports = rte_eth_dev_count_avail(); 2500 2501 if (nb_ports == 0) { 2502 printf("No Ethernet ports - bye\n"); 2503 return -1; 2504 } 2505 2506 /* Reset l2fwd_dst_ports */ 2507 for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) 2508 l2fwd_dst_ports[portid] = 0; 2509 2510 RTE_ETH_FOREACH_DEV(portid) { 2511 int retval; 2512 struct rte_eth_dev_info dev_info; 2513 struct rte_eth_rxconf rxq_conf; 2514 struct rte_eth_txconf txq_conf; 2515 struct rte_eth_conf local_port_conf = port_conf; 2516 2517 /* Skip ports that are not enabled */ 2518 if ((options->portmask & (1 << portid)) == 0) 2519 continue; 2520 2521 /* init port */ 2522 printf("Initializing port %u... ", portid); 2523 fflush(stdout); 2524 2525 retval = rte_eth_dev_info_get(portid, &dev_info); 2526 if (retval != 0) { 2527 printf("Error during getting device (port %u) info: %s\n", 2528 portid, strerror(-retval)); 2529 return retval; 2530 } 2531 2532 if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) 2533 local_port_conf.txmode.offloads |= 2534 DEV_TX_OFFLOAD_MBUF_FAST_FREE; 2535 retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); 2536 if (retval < 0) { 2537 printf("Cannot configure device: err=%d, port=%u\n", 2538 retval, portid); 2539 return -1; 2540 } 2541 2542 retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, 2543 &nb_txd); 2544 if (retval < 0) { 2545 printf("Cannot adjust number of descriptors: err=%d, port=%u\n", 2546 retval, portid); 2547 return -1; 2548 } 2549 2550 /* init one RX queue */ 2551 fflush(stdout); 2552 rxq_conf = dev_info.default_rxconf; 2553 rxq_conf.offloads = local_port_conf.rxmode.offloads; 2554 retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, 2555 rte_eth_dev_socket_id(portid), 2556 &rxq_conf, l2fwd_pktmbuf_pool); 2557 if (retval < 0) { 2558 printf("rte_eth_rx_queue_setup:err=%d, port=%u\n", 2559 retval, portid); 2560 return -1; 2561 } 2562 2563 /* init one TX queue on each port */ 2564 fflush(stdout); 2565 txq_conf = dev_info.default_txconf; 2566 txq_conf.offloads = local_port_conf.txmode.offloads; 2567 retval = rte_eth_tx_queue_setup(portid, 0, nb_txd, 2568 rte_eth_dev_socket_id(portid), 2569 &txq_conf); 2570 if (retval < 0) { 2571 printf("rte_eth_tx_queue_setup:err=%d, port=%u\n", 2572 retval, portid); 2573 2574 return -1; 2575 } 2576 2577 /* Start device */ 2578 retval = rte_eth_dev_start(portid); 2579 if (retval < 0) { 2580 printf("rte_eth_dev_start:err=%d, port=%u\n", 2581 retval, portid); 2582 return -1; 2583 } 2584 2585 retval = rte_eth_promiscuous_enable(portid); 2586 if (retval != 0) { 2587 printf("rte_eth_promiscuous_enable:err=%s, port=%u\n", 2588 rte_strerror(-retval), portid); 2589 return -1; 2590 } 2591 2592 retval = rte_eth_macaddr_get(portid, 2593 &l2fwd_ports_eth_addr[portid]); 2594 if (retval < 0) { 2595 printf("rte_eth_macaddr_get :err=%d, port=%u\n", 2596 retval, portid); 2597 return -1; 2598 } 2599 2600 printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", 2601 portid, 2602 l2fwd_ports_eth_addr[portid].addr_bytes[0], 2603 l2fwd_ports_eth_addr[portid].addr_bytes[1], 2604 l2fwd_ports_eth_addr[portid].addr_bytes[2], 2605 l2fwd_ports_eth_addr[portid].addr_bytes[3], 2606 l2fwd_ports_eth_addr[portid].addr_bytes[4], 2607 l2fwd_ports_eth_addr[portid].addr_bytes[5]); 2608 2609 /* initialize port stats */ 2610 memset(&port_statistics, 0, sizeof(port_statistics)); 2611 2612 /* Setup port forwarding table */ 2613 if (enabled_portcount % 2) { 2614 l2fwd_dst_ports[portid] = last_portid; 2615 l2fwd_dst_ports[last_portid] = portid; 2616 } else { 2617 last_portid = portid; 2618 } 2619 2620 l2fwd_enabled_port_mask |= (1 << portid); 2621 enabled_portcount++; 2622 } 2623 2624 if (enabled_portcount == 1) { 2625 l2fwd_dst_ports[last_portid] = last_portid; 2626 } else if (enabled_portcount % 2) { 2627 printf("odd number of ports in portmask- bye\n"); 2628 return -1; 2629 } 2630 2631 check_all_ports_link_status(l2fwd_enabled_port_mask); 2632 2633 return enabled_portcount; 2634 } 2635 2636 static void 2637 reserve_key_memory(struct l2fwd_crypto_options *options) 2638 { 2639 options->cipher_xform.cipher.key.data = options->cipher_key; 2640 2641 options->auth_xform.auth.key.data = options->auth_key; 2642 2643 options->aead_xform.aead.key.data = options->aead_key; 2644 2645 options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0); 2646 if (options->cipher_iv.data == NULL) 2647 rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher IV"); 2648 2649 options->auth_iv.data = rte_malloc("auth iv", MAX_KEY_SIZE, 0); 2650 if (options->auth_iv.data == NULL) 2651 rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth IV"); 2652 2653 options->aead_iv.data = rte_malloc("aead_iv", MAX_KEY_SIZE, 0); 2654 if (options->aead_iv.data == NULL) 2655 rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv"); 2656 2657 options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); 2658 if (options->aad.data == NULL) 2659 rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD"); 2660 options->aad.phys_addr = rte_malloc_virt2iova(options->aad.data); 2661 } 2662 2663 int 2664 main(int argc, char **argv) 2665 { 2666 struct lcore_queue_conf *qconf = NULL; 2667 struct l2fwd_crypto_options options; 2668 2669 uint8_t nb_cryptodevs, cdev_id; 2670 uint16_t portid; 2671 unsigned lcore_id, rx_lcore_id = 0; 2672 int ret, enabled_cdevcount, enabled_portcount; 2673 uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS] = {0}; 2674 2675 /* init EAL */ 2676 ret = rte_eal_init(argc, argv); 2677 if (ret < 0) 2678 rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); 2679 argc -= ret; 2680 argv += ret; 2681 2682 /* reserve memory for Cipher/Auth key and IV */ 2683 reserve_key_memory(&options); 2684 2685 /* parse application arguments (after the EAL ones) */ 2686 ret = l2fwd_crypto_parse_args(&options, argc, argv); 2687 if (ret < 0) 2688 rte_exit(EXIT_FAILURE, "Invalid L2FWD-CRYPTO arguments\n"); 2689 2690 printf("MAC updating %s\n", 2691 options.mac_updating ? "enabled" : "disabled"); 2692 2693 /* create the mbuf pool */ 2694 l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512, 2695 sizeof(struct rte_crypto_op), 2696 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 2697 if (l2fwd_pktmbuf_pool == NULL) 2698 rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); 2699 2700 /* create crypto op pool */ 2701 l2fwd_crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool", 2702 RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, MAXIMUM_IV_LENGTH, 2703 rte_socket_id()); 2704 if (l2fwd_crypto_op_pool == NULL) 2705 rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n"); 2706 2707 /* Enable Ethernet ports */ 2708 enabled_portcount = initialize_ports(&options); 2709 if (enabled_portcount < 1) 2710 rte_exit(EXIT_FAILURE, "Failed to initial Ethernet ports\n"); 2711 2712 /* Initialize the port/queue configuration of each logical core */ 2713 RTE_ETH_FOREACH_DEV(portid) { 2714 2715 /* skip ports that are not enabled */ 2716 if ((options.portmask & (1 << portid)) == 0) 2717 continue; 2718 2719 if (options.single_lcore && qconf == NULL) { 2720 while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2721 rx_lcore_id++; 2722 if (rx_lcore_id >= RTE_MAX_LCORE) 2723 rte_exit(EXIT_FAILURE, 2724 "Not enough cores\n"); 2725 } 2726 } else if (!options.single_lcore) { 2727 /* get the lcore_id for this port */ 2728 while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2729 lcore_queue_conf[rx_lcore_id].nb_rx_ports == 2730 options.nb_ports_per_lcore) { 2731 rx_lcore_id++; 2732 if (rx_lcore_id >= RTE_MAX_LCORE) 2733 rte_exit(EXIT_FAILURE, 2734 "Not enough cores\n"); 2735 } 2736 } 2737 2738 /* Assigned a new logical core in the loop above. */ 2739 if (qconf != &lcore_queue_conf[rx_lcore_id]) 2740 qconf = &lcore_queue_conf[rx_lcore_id]; 2741 2742 qconf->rx_port_list[qconf->nb_rx_ports] = portid; 2743 qconf->nb_rx_ports++; 2744 2745 printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); 2746 } 2747 2748 /* Enable Crypto devices */ 2749 enabled_cdevcount = initialize_cryptodevs(&options, enabled_portcount, 2750 enabled_cdevs); 2751 if (enabled_cdevcount < 0) 2752 rte_exit(EXIT_FAILURE, "Failed to initialize crypto devices\n"); 2753 2754 if (enabled_cdevcount < enabled_portcount) 2755 rte_exit(EXIT_FAILURE, "Number of capable crypto devices (%d) " 2756 "has to be more or equal to number of ports (%d)\n", 2757 enabled_cdevcount, enabled_portcount); 2758 2759 nb_cryptodevs = rte_cryptodev_count(); 2760 2761 /* Initialize the port/cryptodev configuration of each logical core */ 2762 for (rx_lcore_id = 0, qconf = NULL, cdev_id = 0; 2763 cdev_id < nb_cryptodevs && enabled_cdevcount; 2764 cdev_id++) { 2765 /* Crypto op not supported by crypto device */ 2766 if (!enabled_cdevs[cdev_id]) 2767 continue; 2768 2769 if (options.single_lcore && qconf == NULL) { 2770 while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2771 rx_lcore_id++; 2772 if (rx_lcore_id >= RTE_MAX_LCORE) 2773 rte_exit(EXIT_FAILURE, 2774 "Not enough cores\n"); 2775 } 2776 } else if (!options.single_lcore) { 2777 /* get the lcore_id for this port */ 2778 while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2779 lcore_queue_conf[rx_lcore_id].nb_crypto_devs == 2780 options.nb_ports_per_lcore) { 2781 rx_lcore_id++; 2782 if (rx_lcore_id >= RTE_MAX_LCORE) 2783 rte_exit(EXIT_FAILURE, 2784 "Not enough cores\n"); 2785 } 2786 } 2787 2788 /* Assigned a new logical core in the loop above. */ 2789 if (qconf != &lcore_queue_conf[rx_lcore_id]) 2790 qconf = &lcore_queue_conf[rx_lcore_id]; 2791 2792 qconf->cryptodev_list[qconf->nb_crypto_devs] = cdev_id; 2793 qconf->nb_crypto_devs++; 2794 2795 enabled_cdevcount--; 2796 2797 printf("Lcore %u: cryptodev %u\n", rx_lcore_id, 2798 (unsigned)cdev_id); 2799 } 2800 2801 /* launch per-lcore init on every lcore */ 2802 rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, (void *)&options, 2803 CALL_MASTER); 2804 RTE_LCORE_FOREACH_SLAVE(lcore_id) { 2805 if (rte_eal_wait_lcore(lcore_id) < 0) 2806 return -1; 2807 } 2808 2809 return 0; 2810 } 2811