examples/l2fwd-crypto: fix stats refresh rate
[dpdk.git] / examples / l2fwd-crypto / main.c
index 827da9b..b1e2613 100644 (file)
@@ -20,7 +20,6 @@
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_common.h>
 #include <rte_cryptodev.h>
@@ -43,7 +42,7 @@
 #include <rte_prefetch.h>
 #include <rte_random.h>
 #include <rte_hexdump.h>
-#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#ifdef RTE_CRYPTO_SCHEDULER
 #include <rte_cryptodev_scheduler.h>
 #endif
 
@@ -182,6 +181,8 @@ struct l2fwd_crypto_params {
        unsigned digest_length;
        unsigned block_size;
 
+       uint32_t cipher_dataunit_len;
+
        struct l2fwd_iv cipher_iv;
        struct l2fwd_iv auth_iv;
        struct l2fwd_iv aead_iv;
@@ -214,12 +215,11 @@ struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
 
 static struct rte_eth_conf port_conf = {
        .rxmode = {
-               .mq_mode = ETH_MQ_RX_NONE,
-               .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
+               .mq_mode = RTE_ETH_MQ_RX_NONE,
                .split_hdr_size = 0,
        },
        .txmode = {
-               .mq_mode = ETH_MQ_TX_NONE,
+               .mq_mode = RTE_ETH_MQ_TX_NONE,
        },
 };
 
@@ -252,11 +252,9 @@ struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS];
 struct l2fwd_crypto_statistics crypto_statistics[RTE_CRYPTO_MAX_DEVS];
 
 /* A tsc-based timer responsible for triggering statistics printout */
-#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */
+#define TIMER_MILLISECOND (rte_get_tsc_hz() / 1000)
 #define MAX_TIMER_PERIOD 86400UL /* 1 day max */
-
-/* default period is 10 seconds */
-static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000;
+#define DEFAULT_TIMER_PERIOD 10UL
 
 /* Print out statistics on packets dropped */
 static void
@@ -338,6 +336,7 @@ print_stats(void)
        fflush(stdout);
 }
 
+/* l2fwd_crypto_send_burst 8< */
 static int
 l2fwd_crypto_send_burst(struct lcore_queue_conf *qconf, unsigned n,
                struct l2fwd_crypto_params *cparams)
@@ -362,7 +361,9 @@ l2fwd_crypto_send_burst(struct lcore_queue_conf *qconf, unsigned n,
 
        return 0;
 }
+/* >8 End of l2fwd_crypto_send_burst. */
 
+/* Crypto enqueue. 8< */
 static int
 l2fwd_crypto_enqueue(struct rte_crypto_op *op,
                struct l2fwd_crypto_params *cparams)
@@ -386,6 +387,7 @@ l2fwd_crypto_enqueue(struct rte_crypto_op *op,
        qconf->op_buf[cparams->dev_id].len = len;
        return 0;
 }
+/* >8 End of crypto enqueue. */
 
 static int
 l2fwd_simple_crypto_enqueue(struct rte_mbuf *m,
@@ -434,6 +436,12 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m,
                                pad_len = cparams->block_size -
                                        (data_len % cparams->block_size);
                        break;
+               case RTE_CRYPTO_CIPHER_AES_XTS:
+                       if (cparams->cipher_dataunit_len != 0 &&
+                           (data_len % cparams->cipher_dataunit_len))
+                               pad_len = cparams->cipher_dataunit_len -
+                                       (data_len % cparams->cipher_dataunit_len);
+                       break;
                default:
                        pad_len = 0;
                }
@@ -571,7 +579,7 @@ l2fwd_send_burst(struct lcore_queue_conf *qconf, unsigned n,
        return 0;
 }
 
-/* Enqueue packets for TX and prepare them to be sent */
+/* Enqueue packets for TX and prepare them to be sent. 8< */
 static int
 l2fwd_send_packet(struct rte_mbuf *m, uint16_t port)
 {
@@ -594,6 +602,7 @@ l2fwd_send_packet(struct rte_mbuf *m, uint16_t port)
        qconf->pkt_buf[port].len = len;
        return 0;
 }
+/* >8 End of Enqueuing packets for TX. */
 
 static void
 l2fwd_mac_updating(struct rte_mbuf *m, uint16_t dest_portid)
@@ -604,11 +613,11 @@ l2fwd_mac_updating(struct rte_mbuf *m, uint16_t dest_portid)
        eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
 
        /* 02:00:00:00:00:xx */
-       tmp = &eth->d_addr.addr_bytes[0];
+       tmp = &eth->dst_addr.addr_bytes[0];
        *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
 
        /* src addr */
-       rte_ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], &eth->s_addr);
+       rte_ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], &eth->src_addr);
 }
 
 static void
@@ -616,12 +625,26 @@ l2fwd_simple_forward(struct rte_mbuf *m, uint16_t portid,
                struct l2fwd_crypto_options *options)
 {
        uint16_t dst_port;
+       uint32_t pad_len;
+       struct rte_ipv4_hdr *ip_hdr;
+       uint32_t ipdata_offset = sizeof(struct rte_ether_hdr);
 
+       ip_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(m, char *) +
+                                        ipdata_offset);
        dst_port = l2fwd_dst_ports[portid];
 
        if (options->mac_updating)
                l2fwd_mac_updating(m, dst_port);
 
+       if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+               rte_pktmbuf_trim(m, options->auth_xform.auth.digest_length);
+
+       if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
+               pad_len = m->pkt_len - rte_be_to_cpu_16(ip_hdr->total_length) -
+                         ipdata_offset;
+               rte_pktmbuf_trim(m, pad_len);
+       }
+
        l2fwd_send_packet(m, dst_port);
 }
 
@@ -643,6 +666,7 @@ generate_random_key(uint8_t *key, unsigned length)
                rte_exit(EXIT_FAILURE, "Failed to generate random key\n");
 }
 
+/* Session is created and is later attached to the crypto operation. 8< */
 static struct rte_cryptodev_sym_session *
 initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id)
 {
@@ -681,6 +705,7 @@ initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id)
 
        return session;
 }
+/* >8 End of creation of session. */
 
 static void
 l2fwd_crypto_options_print(struct l2fwd_crypto_options *options);
@@ -813,6 +838,8 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
                                                port_cparams[i].cipher_iv.length);
 
                        port_cparams[i].cipher_algo = options->cipher_xform.cipher.algo;
+                       port_cparams[i].cipher_dataunit_len =
+                               options->cipher_xform.cipher.dataunit_len;
                        /* Set IV parameters */
                        options->cipher_xform.cipher.iv.offset = IV_OFFSET;
                        options->cipher_xform.cipher.iv.length =
@@ -865,18 +892,17 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
                        }
 
                        /* if timer is enabled */
-                       if (timer_period > 0) {
+                       if (options->refresh_period > 0) {
 
                                /* advance the timer */
                                timer_tsc += diff_tsc;
 
                                /* if timer has reached its timeout */
                                if (unlikely(timer_tsc >=
-                                               (uint64_t)timer_period)) {
+                                               options->refresh_period)) {
 
-                                       /* do this only on master core */
-                                       if (lcore_id == rte_get_master_lcore()
-                                               && options->refresh_period) {
+                                       /* do this only on main core */
+                                       if (lcore_id == rte_get_main_lcore()) {
                                                print_stats();
                                                timer_tsc = 0;
                                        }
@@ -899,6 +925,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
 
                        port_statistics[portid].rx += nb_rx;
 
+                       /* Allocate and fillcrypto operations. 8< */
                        if (nb_rx) {
                                /*
                                 * If we can't allocate a crypto_ops, then drop
@@ -915,6 +942,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
 
                                        nb_rx = 0;
                                }
+                               /* >8 End of crypto operation allocated and filled. */
 
                                /* Enqueue packets from Crypto device*/
                                for (j = 0; j < nb_rx; j++) {
@@ -925,7 +953,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
                                }
                        }
 
-                       /* Dequeue packets from Crypto device */
+                       /* Dequeue packets from Crypto device. 8< */
                        do {
                                nb_rx = rte_cryptodev_dequeue_burst(
                                                cparams->dev_id, cparams->qp_id,
@@ -943,6 +971,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options)
                                                        options);
                                }
                        } while (nb_rx == MAX_PKT_BURST);
+                       /* >8 End of dequeue packets from crypto device. */
                }
        }
 }
@@ -975,6 +1004,7 @@ l2fwd_crypto_usage(const char *prgname)
                "  --cipher_key_random_size SIZE: size of cipher key when generated randomly\n"
                "  --cipher_iv IV (bytes separated with \":\")\n"
                "  --cipher_iv_random_size SIZE: size of cipher IV when generated randomly\n"
+               "  --cipher_dataunit_len SIZE: length of the algorithm data-unit\n"
 
                "  --auth_algo ALGO\n"
                "  --auth_op GENERATE / VERIFY\n"
@@ -1201,6 +1231,7 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
                struct option *lgopts, int option_index)
 {
        int retval;
+       int val;
 
        if (strcmp(lgopts[option_index].name, "cdev_type") == 0) {
                retval = parse_cryptodev_type(&options->type, optarg);
@@ -1231,6 +1262,16 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
                        return -1;
        }
 
+       else if (strcmp(lgopts[option_index].name, "cipher_dataunit_len") == 0) {
+               retval = parse_size(&val, optarg);
+               if (retval == 0 && val >= 0) {
+                       options->cipher_xform.cipher.dataunit_len =
+                                                               (uint32_t)val;
+                       return 0;
+               } else
+                       return -1;
+       }
+
        else if (strcmp(lgopts[option_index].name, "cipher_key_random_size") == 0)
                return parse_size(&options->ckey_random_size, optarg);
 
@@ -1437,7 +1478,8 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options)
 {
        options->portmask = 0xffffffff;
        options->nb_ports_per_lcore = 1;
-       options->refresh_period = 10000;
+       options->refresh_period = DEFAULT_TIMER_PERIOD *
+                                       TIMER_MILLISECOND * 1000;
        options->single_lcore = 0;
        options->sessionless = 0;
 
@@ -1455,6 +1497,7 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options)
 
        options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
        options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+       options->cipher_xform.cipher.dataunit_len = 0;
 
        /* Authentication Data */
        options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
@@ -1630,6 +1673,7 @@ l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options,
                        { "cipher_key_random_size", required_argument, 0, 0 },
                        { "cipher_iv", required_argument, 0, 0 },
                        { "cipher_iv_random_size", required_argument, 0, 0 },
+                       { "cipher_dataunit_len", required_argument, 0, 0},
 
                        { "auth_algo", required_argument, 0, 0 },
                        { "auth_op", required_argument, 0, 0 },
@@ -1734,6 +1778,7 @@ check_all_ports_link_status(uint32_t port_mask)
        uint8_t count, all_ports_up, print_flag = 0;
        struct rte_eth_link link;
        int ret;
+       char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
 
        printf("\nChecking link status");
        fflush(stdout);
@@ -1753,18 +1798,14 @@ check_all_ports_link_status(uint32_t port_mask)
                        }
                        /* print link status if flag set */
                        if (print_flag == 1) {
-                               if (link.link_status)
-                                       printf(
-                                       "Port%d Link Up. Speed %u Mbps - %s\n",
-                                               portid, link.link_speed,
-                               (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-                                       ("full-duplex") : ("half-duplex"));
-                               else
-                                       printf("Port %d Link Down\n", portid);
+                               rte_eth_link_to_str(link_status_text,
+                                       sizeof(link_status_text), &link);
+                               printf("Port %d %s\n", portid,
+                                       link_status_text);
                                continue;
                        }
                        /* clear all_ports_up flag if any link down */
-                       if (link.link_status == ETH_LINK_DOWN) {
+                       if (link.link_status == RTE_ETH_LINK_DOWN) {
                                all_ports_up = 0;
                                break;
                        }
@@ -2088,7 +2129,8 @@ check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id)
        if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH ||
                        options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER ||
                        options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) {
-               /* Check if device supports cipher algo */
+
+               /* Check if device supports cipher algo. 8< */
                cap = check_device_support_cipher_algo(options, &dev_info,
                                                cdev_id);
                if (cap == NULL)
@@ -2103,6 +2145,9 @@ check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id)
                                cdev_id);
                        return -1;
                }
+               /* >8 End of check if device supports cipher algo. */
+
+               /* Check if capable cipher is supported. 8< */
 
                /*
                 * Check if length of provided cipher key is supported
@@ -2115,12 +2160,21 @@ check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id)
                                        cap->sym.cipher.key_size.max,
                                        cap->sym.cipher.key_size.increment)
                                                != 0) {
-                               RTE_LOG(DEBUG, USER1,
-                                       "Device %u does not support cipher "
-                                       "key length\n",
+                               if (dev_info.feature_flags &
+                                   RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY) {
+                                       RTE_LOG(DEBUG, USER1,
+                                       "Key length does not match the device "
+                                       "%u capability. Key may be wrapped\n",
                                        cdev_id);
-                               return -1;
+                               } else {
+                                       RTE_LOG(DEBUG, USER1,
+                                       "Key length does not match the device "
+                                       "%u capability\n",
+                                       cdev_id);
+                                       return -1;
+                               }
                        }
+
                /*
                 * Check if length of the cipher key to be randomly generated
                 * is supported by the algorithm chosen.
@@ -2138,6 +2192,49 @@ check_capabilities(struct l2fwd_crypto_options *options, uint8_t cdev_id)
                                return -1;
                        }
                }
+
+               if (options->cipher_xform.cipher.dataunit_len > 0) {
+                       if (!(dev_info.feature_flags &
+                               RTE_CRYPTODEV_FF_CIPHER_MULTIPLE_DATA_UNITS)) {
+                               RTE_LOG(DEBUG, USER1,
+                                       "Device %u does not support "
+                                       "cipher multiple data units\n",
+                                       cdev_id);
+                               return -1;
+                       }
+                       if (cap->sym.cipher.dataunit_set != 0) {
+                               int ret = 0;
+
+                               switch (options->cipher_xform.cipher.dataunit_len) {
+                               case 512:
+                                       if (!(cap->sym.cipher.dataunit_set &
+                                               RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES))
+                                               ret = -1;
+                                       break;
+                               case 4096:
+                                       if (!(cap->sym.cipher.dataunit_set &
+                                               RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4096_BYTES))
+                                               ret = -1;
+                                       break;
+                               case 1048576:
+                                       if (!(cap->sym.cipher.dataunit_set &
+                                               RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_1_MEGABYTES))
+                                               ret = -1;
+                                       break;
+                               default:
+                                       ret = -1;
+                               }
+                               if (ret == -1) {
+                                       RTE_LOG(DEBUG, USER1,
+                                               "Device %u does not support "
+                                               "data-unit length %u\n",
+                                               cdev_id,
+                                               options->cipher_xform.cipher.dataunit_len);
+                                       return -1;
+                               }
+                       }
+               }
+               /* >8 End of checking if cipher is supported. */
        }
 
        /* Set auth parameters */
@@ -2254,6 +2351,12 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                if (enabled_cdevs[cdev_id] == 0)
                        continue;
 
+               if (check_cryptodev_mask(options, cdev_id) < 0)
+                       continue;
+
+               if (check_capabilities(options, cdev_id) < 0)
+                       continue;
+
                retval = rte_cryptodev_socket_id(cdev_id);
 
                if (retval < 0) {
@@ -2276,12 +2379,12 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                 * (one for the header, one for the private data)
                 */
                if (!strcmp(dev_info.driver_name, "crypto_scheduler")) {
-#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
-                       uint32_t nb_slaves =
-                               rte_cryptodev_scheduler_slaves_get(cdev_id,
+#ifdef RTE_CRYPTO_SCHEDULER
+                       uint32_t nb_workers =
+                               rte_cryptodev_scheduler_workers_get(cdev_id,
                                                                NULL);
 
-                       sessions_needed = enabled_cdev_count * nb_slaves;
+                       sessions_needed = enabled_cdev_count * nb_workers;
 #endif
                } else
                        sessions_needed = enabled_cdev_count;
@@ -2531,9 +2634,9 @@ initialize_ports(struct l2fwd_crypto_options *options)
                        return retval;
                }
 
-               if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
+               if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
                        local_port_conf.txmode.offloads |=
-                               DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+                               RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
                retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
                if (retval < 0) {
                        printf("Cannot configure device: err=%d, port=%u\n",
@@ -2599,14 +2702,9 @@ initialize_ports(struct l2fwd_crypto_options *options)
                        return -1;
                }
 
-               printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
-                               portid,
-                               l2fwd_ports_eth_addr[portid].addr_bytes[0],
-                               l2fwd_ports_eth_addr[portid].addr_bytes[1],
-                               l2fwd_ports_eth_addr[portid].addr_bytes[2],
-                               l2fwd_ports_eth_addr[portid].addr_bytes[3],
-                               l2fwd_ports_eth_addr[portid].addr_bytes[4],
-                               l2fwd_ports_eth_addr[portid].addr_bytes[5]);
+               printf("Port %u, MAC address: " RTE_ETHER_ADDR_PRT_FMT "\n\n",
+                       portid,
+                       RTE_ETHER_ADDR_BYTES(&l2fwd_ports_eth_addr[portid]));
 
                /* initialize port stats */
                memset(&port_statistics, 0, sizeof(port_statistics));
@@ -2619,7 +2717,7 @@ initialize_ports(struct l2fwd_crypto_options *options)
                        last_portid = portid;
                }
 
-               l2fwd_enabled_port_mask |= (1 << portid);
+               l2fwd_enabled_port_mask |= (1ULL << portid);
                enabled_portcount++;
        }
 
@@ -2694,7 +2792,8 @@ main(int argc, char **argv)
 
        /* create the mbuf pool */
        l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512,
-                       sizeof(struct rte_crypto_op),
+                       RTE_ALIGN(sizeof(struct rte_crypto_op),
+                               RTE_CACHE_LINE_SIZE),
                        RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
        if (l2fwd_pktmbuf_pool == NULL)
                rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
@@ -2802,11 +2901,14 @@ main(int argc, char **argv)
 
        /* launch per-lcore init on every lcore */
        rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, (void *)&options,
-                       CALL_MASTER);
-       RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+                       CALL_MAIN);
+       RTE_LCORE_FOREACH_WORKER(lcore_id) {
                if (rte_eal_wait_lcore(lcore_id) < 0)
                        return -1;
        }
 
+       /* clean up the EAL */
+       rte_eal_cleanup();
+
        return 0;
 }