examples/l3fwd: add vector stubs for RISC-V
[dpdk.git] / examples / l3fwd / main.c
index 202ef78..a629198 100644 (file)
@@ -53,9 +53,8 @@
 
 #define MAX_LCORE_PARAMS 1024
 
-/* Static global variables used within this file. */
-static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
-static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
+uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
+uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
 
 /**< Ports set in promiscuous mode off by default. */
 static int promiscuous_on;
@@ -94,6 +93,8 @@ uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
 
 struct lcore_conf lcore_conf[RTE_MAX_LCORE];
 
+struct parm_cfg parm_config;
+
 struct lcore_params {
        uint16_t port_id;
        uint8_t queue_id;
@@ -119,67 +120,76 @@ static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) /
 
 static struct rte_eth_conf port_conf = {
        .rxmode = {
-               .mq_mode = ETH_MQ_RX_RSS,
+               .mq_mode = RTE_ETH_MQ_RX_RSS,
                .split_hdr_size = 0,
-               .offloads = DEV_RX_OFFLOAD_CHECKSUM,
+               .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
        },
        .rx_adv_conf = {
                .rss_conf = {
                        .rss_key = NULL,
-                       .rss_hf = ETH_RSS_IP,
+                       .rss_hf = RTE_ETH_RSS_IP,
                },
        },
        .txmode = {
-               .mq_mode = ETH_MQ_TX_NONE,
+               .mq_mode = RTE_ETH_MQ_TX_NONE,
        },
 };
 
 static uint32_t max_pkt_len;
 
 static struct rte_mempool *pktmbuf_pool[RTE_MAX_ETHPORTS][NB_SOCKETS];
+static struct rte_mempool *vector_pool[RTE_MAX_ETHPORTS];
 static uint8_t lkp_per_socket[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
+       void  (*read_config_files)(void);
        void  (*setup)(int);
        int   (*check_ptype)(int);
        rte_rx_callback_fn cb_parse_ptype;
        int   (*main_loop)(void *);
        void* (*get_ipv4_lookup_struct)(int);
        void* (*get_ipv6_lookup_struct)(int);
+       void  (*free_routes)(void);
 };
 
 static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
+       .read_config_files              = read_config_files_em,
        .setup                  = setup_hash,
        .check_ptype            = em_check_ptype,
        .cb_parse_ptype         = em_cb_parse_ptype,
        .main_loop              = em_main_loop,
        .get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
        .get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
+       .free_routes                    = em_free_routes,
 };
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
+       .read_config_files              = read_config_files_lpm,
        .setup                  = setup_lpm,
        .check_ptype            = lpm_check_ptype,
        .cb_parse_ptype         = lpm_cb_parse_ptype,
        .main_loop              = lpm_main_loop,
        .get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
        .get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
+       .free_routes                    = lpm_free_routes,
 };
 
 static struct l3fwd_lkp_mode l3fwd_fib_lkp = {
+       .read_config_files              = read_config_files_lpm,
        .setup                  = setup_fib,
        .check_ptype            = lpm_check_ptype,
        .cb_parse_ptype         = lpm_cb_parse_ptype,
        .main_loop              = fib_main_loop,
        .get_ipv4_lookup_struct = fib_get_ipv4_l3fwd_lookup_struct,
        .get_ipv6_lookup_struct = fib_get_ipv6_l3fwd_lookup_struct,
+       .free_routes                    = lpm_free_routes,
 };
 
 /*
  * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735).
- * 198.18.{0-7}.0/24 = Port {0-7}
+ * 198.18.{0-15}.0/24 = Port {0-15}
  */
 const struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {
        {RTE_IPV4(198, 18, 0, 0), 24, 0},
@@ -190,11 +200,19 @@ const struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = {
        {RTE_IPV4(198, 18, 5, 0), 24, 5},
        {RTE_IPV4(198, 18, 6, 0), 24, 6},
        {RTE_IPV4(198, 18, 7, 0), 24, 7},
+       {RTE_IPV4(198, 18, 8, 0), 24, 8},
+       {RTE_IPV4(198, 18, 9, 0), 24, 9},
+       {RTE_IPV4(198, 18, 10, 0), 24, 10},
+       {RTE_IPV4(198, 18, 11, 0), 24, 11},
+       {RTE_IPV4(198, 18, 12, 0), 24, 12},
+       {RTE_IPV4(198, 18, 13, 0), 24, 13},
+       {RTE_IPV4(198, 18, 14, 0), 24, 14},
+       {RTE_IPV4(198, 18, 15, 0), 24, 15},
 };
 
 /*
  * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180).
- * 2001:200:0:{0-7}::/64 = Port {0-7}
+ * 2001:200:0:{0-f}::/64 = Port {0-15}
  */
 const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = {
        {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 0},
@@ -205,8 +223,31 @@ const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = {
        {{32, 1, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 5},
        {{32, 1, 2, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 6},
        {{32, 1, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 7},
+       {{32, 1, 2, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 8},
+       {{32, 1, 2, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 9},
+       {{32, 1, 2, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 10},
+       {{32, 1, 2, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 11},
+       {{32, 1, 2, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 12},
+       {{32, 1, 2, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 13},
+       {{32, 1, 2, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 14},
+       {{32, 1, 2, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 15},
 };
 
+/*
+ * API's called during initialization to setup ACL/EM/LPM rules.
+ */
+static void
+l3fwd_set_rule_ipv4_name(const char *optarg)
+{
+       parm_config.rule_ipv4_name = optarg;
+}
+
+static void
+l3fwd_set_rule_ipv6_name(const char *optarg)
+{
+       parm_config.rule_ipv6_name = optarg;
+}
+
 /*
  * Setup lookup methods for forwarding.
  * Currently exact-match, longest-prefix-match and forwarding information
@@ -322,9 +363,13 @@ print_usage(const char *prgname)
 {
        fprintf(stderr, "%s [EAL options] --"
                " -p PORTMASK"
+               "  --rule_ipv4=FILE"
+               "  --rule_ipv6=FILE"
                " [-P]"
                " [--lookup]"
                " --config (port,queue,lcore)[,(port,queue,lcore)]"
+               " [--rx-queue-size NPKTS]"
+               " [--tx-queue-size NPKTS]"
                " [--eth-dest=X,MM:MM:MM:MM:MM:MM]"
                " [--max-pkt-len PKTLEN]"
                " [--no-numa]"
@@ -334,6 +379,7 @@ print_usage(const char *prgname)
                " [--per-port-pool]"
                " [--mode]"
                " [--eventq-sched]"
+               " [--event-vector [--event-vector-size SIZE] [--event-vector-tmo NS]]"
                " [-E]"
                " [-L]\n\n"
 
@@ -343,6 +389,10 @@ print_usage(const char *prgname)
                "            Default: lpm\n"
                "            Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base)\n"
                "  --config (port,queue,lcore): Rx queue configuration\n"
+               "  --rx-queue-size NPKTS: Rx queue size in decimal\n"
+               "            Default: %d\n"
+               "  --tx-queue-size NPKTS: Tx queue size in decimal\n"
+               "            Default: %d\n"
                "  --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for port X\n"
                "  --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n"
                "  --no-numa: Disable numa awareness\n"
@@ -359,9 +409,15 @@ print_usage(const char *prgname)
                "  --event-eth-rxqs: Number of ethernet RX queues per device.\n"
                "                    Default: 1\n"
                "                    Valid only if --mode=eventdev\n"
+               "  --event-vector:  Enable event vectorization.\n"
+               "  --event-vector-size: Max vector size if event vectorization is enabled.\n"
+               "  --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\n"
                "  -E : Enable exact match, legacy flag please use --lookup=em instead\n"
-               "  -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n\n",
-               prgname);
+               "  -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n"
+               "  --rule_ipv4=FILE: Specify the ipv4 rules entries file.\n"
+               "                    Each rule occupies one line.\n"
+               "  --rule_ipv6=FILE: Specify the ipv6 rules entries file.\n\n",
+               prgname, RTE_TEST_RX_DESC_DEFAULT, RTE_TEST_TX_DESC_DEFAULT);
 }
 
 static int
@@ -504,6 +560,38 @@ parse_mode(const char *optarg)
                evt_rsrc->enabled = true;
 }
 
+static void
+parse_queue_size(const char *queue_size_arg, uint16_t *queue_size, int rx)
+{
+       char *end = NULL;
+       unsigned long value;
+
+       /* parse decimal string */
+       value = strtoul(queue_size_arg, &end, 10);
+       if ((queue_size_arg[0] == '\0') || (end == NULL) ||
+               (*end != '\0') || (value == 0)) {
+               if (rx == 1)
+                       rte_exit(EXIT_FAILURE, "Invalid rx-queue-size\n");
+               else
+                       rte_exit(EXIT_FAILURE, "Invalid tx-queue-size\n");
+
+               return;
+       }
+
+       if (value > UINT16_MAX) {
+               if (rx == 1)
+                       rte_exit(EXIT_FAILURE, "rx-queue-size %lu > %d\n",
+                               value, UINT16_MAX);
+               else
+                       rte_exit(EXIT_FAILURE, "tx-queue-size %lu > %d\n",
+                               value, UINT16_MAX);
+
+               return;
+       }
+
+       *queue_size = value;
+}
+
 static void
 parse_eventq_sched(const char *optarg)
 {
@@ -561,6 +649,8 @@ static const char short_options[] =
        ;
 
 #define CMD_LINE_OPT_CONFIG "config"
+#define CMD_LINE_OPT_RX_QUEUE_SIZE "rx-queue-size"
+#define CMD_LINE_OPT_TX_QUEUE_SIZE "tx-queue-size"
 #define CMD_LINE_OPT_ETH_DEST "eth-dest"
 #define CMD_LINE_OPT_NO_NUMA "no-numa"
 #define CMD_LINE_OPT_IPV6 "ipv6"
@@ -572,6 +662,12 @@ static const char short_options[] =
 #define CMD_LINE_OPT_EVENTQ_SYNC "eventq-sched"
 #define CMD_LINE_OPT_EVENT_ETH_RX_QUEUES "event-eth-rxqs"
 #define CMD_LINE_OPT_LOOKUP "lookup"
+#define CMD_LINE_OPT_ENABLE_VECTOR "event-vector"
+#define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size"
+#define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo"
+#define CMD_LINE_OPT_RULE_IPV4 "rule_ipv4"
+#define CMD_LINE_OPT_RULE_IPV6 "rule_ipv6"
+
 enum {
        /* long options mapped to a short option */
 
@@ -579,21 +675,30 @@ enum {
         * conflict with short options */
        CMD_LINE_OPT_MIN_NUM = 256,
        CMD_LINE_OPT_CONFIG_NUM,
+       CMD_LINE_OPT_RX_QUEUE_SIZE_NUM,
+       CMD_LINE_OPT_TX_QUEUE_SIZE_NUM,
        CMD_LINE_OPT_ETH_DEST_NUM,
        CMD_LINE_OPT_NO_NUMA_NUM,
        CMD_LINE_OPT_IPV6_NUM,
        CMD_LINE_OPT_MAX_PKT_LEN_NUM,
        CMD_LINE_OPT_HASH_ENTRY_NUM_NUM,
        CMD_LINE_OPT_PARSE_PTYPE_NUM,
+       CMD_LINE_OPT_RULE_IPV4_NUM,
+       CMD_LINE_OPT_RULE_IPV6_NUM,
        CMD_LINE_OPT_PARSE_PER_PORT_POOL,
        CMD_LINE_OPT_MODE_NUM,
        CMD_LINE_OPT_EVENTQ_SYNC_NUM,
        CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM,
        CMD_LINE_OPT_LOOKUP_NUM,
+       CMD_LINE_OPT_ENABLE_VECTOR_NUM,
+       CMD_LINE_OPT_VECTOR_SIZE_NUM,
+       CMD_LINE_OPT_VECTOR_TMO_NS_NUM
 };
 
 static const struct option lgopts[] = {
        {CMD_LINE_OPT_CONFIG, 1, 0, CMD_LINE_OPT_CONFIG_NUM},
+       {CMD_LINE_OPT_RX_QUEUE_SIZE, 1, 0, CMD_LINE_OPT_RX_QUEUE_SIZE_NUM},
+       {CMD_LINE_OPT_TX_QUEUE_SIZE, 1, 0, CMD_LINE_OPT_TX_QUEUE_SIZE_NUM},
        {CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM},
        {CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM},
        {CMD_LINE_OPT_IPV6, 0, 0, CMD_LINE_OPT_IPV6_NUM},
@@ -606,6 +711,11 @@ static const struct option lgopts[] = {
        {CMD_LINE_OPT_EVENT_ETH_RX_QUEUES, 1, 0,
                                        CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM},
        {CMD_LINE_OPT_LOOKUP, 1, 0, CMD_LINE_OPT_LOOKUP_NUM},
+       {CMD_LINE_OPT_ENABLE_VECTOR, 0, 0, CMD_LINE_OPT_ENABLE_VECTOR_NUM},
+       {CMD_LINE_OPT_VECTOR_SIZE, 1, 0, CMD_LINE_OPT_VECTOR_SIZE_NUM},
+       {CMD_LINE_OPT_VECTOR_TMO_NS, 1, 0, CMD_LINE_OPT_VECTOR_TMO_NS_NUM},
+       {CMD_LINE_OPT_RULE_IPV4,   1, 0, CMD_LINE_OPT_RULE_IPV4_NUM},
+       {CMD_LINE_OPT_RULE_IPV6,   1, 0, CMD_LINE_OPT_RULE_IPV6_NUM},
        {NULL, 0, 0, 0}
 };
 
@@ -684,6 +794,14 @@ parse_args(int argc, char **argv)
                        lcore_params = 1;
                        break;
 
+               case CMD_LINE_OPT_RX_QUEUE_SIZE_NUM:
+                       parse_queue_size(optarg, &nb_rxd, 1);
+                       break;
+
+               case CMD_LINE_OPT_TX_QUEUE_SIZE_NUM:
+                       parse_queue_size(optarg, &nb_txd, 0);
+                       break;
+
                case CMD_LINE_OPT_ETH_DEST_NUM:
                        parse_eth_dest(optarg);
                        break;
@@ -750,6 +868,22 @@ parse_args(int argc, char **argv)
                                return -1;
                        break;
 
+               case CMD_LINE_OPT_ENABLE_VECTOR_NUM:
+                       printf("event vectorization is enabled\n");
+                       evt_rsrc->vector_enabled = 1;
+                       break;
+               case CMD_LINE_OPT_VECTOR_SIZE_NUM:
+                       evt_rsrc->vector_size = strtol(optarg, NULL, 10);
+                       break;
+               case CMD_LINE_OPT_VECTOR_TMO_NS_NUM:
+                       evt_rsrc->vector_tmo_ns = strtoull(optarg, NULL, 10);
+                       break;
+               case CMD_LINE_OPT_RULE_IPV4_NUM:
+                       l3fwd_set_rule_ipv4_name(optarg);
+                       break;
+               case CMD_LINE_OPT_RULE_IPV6_NUM:
+                       l3fwd_set_rule_ipv6_name(optarg);
+                       break;
                default:
                        print_usage(prgname);
                        return -1;
@@ -771,6 +905,19 @@ parse_args(int argc, char **argv)
                return -1;
        }
 
+       if (evt_rsrc->vector_enabled && !evt_rsrc->vector_size) {
+               evt_rsrc->vector_size = VECTOR_SIZE_DEFAULT;
+               fprintf(stderr, "vector size set to default (%" PRIu16 ")\n",
+                       evt_rsrc->vector_size);
+       }
+
+       if (evt_rsrc->vector_enabled && !evt_rsrc->vector_tmo_ns) {
+               evt_rsrc->vector_tmo_ns = VECTOR_TMO_NS_DEFAULT;
+               fprintf(stderr,
+                       "vector timeout set to default (%" PRIu64 " ns)\n",
+                       evt_rsrc->vector_tmo_ns);
+       }
+
        /*
         * Nothing is selected, pick longest-prefix match
         * as default match.
@@ -809,6 +956,7 @@ print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)
 int
 init_mem(uint16_t portid, unsigned int nb_mbuf)
 {
+       struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc();
        struct lcore_conf *qconf;
        int socketid;
        unsigned lcore_id;
@@ -852,6 +1000,24 @@ init_mem(uint16_t portid, unsigned int nb_mbuf)
                                lkp_per_socket[socketid] = 1;
                        }
                }
+
+               if (evt_rsrc->vector_enabled && vector_pool[portid] == NULL) {
+                       unsigned int nb_vec;
+
+                       nb_vec = (nb_mbuf + evt_rsrc->vector_size - 1) /
+                                evt_rsrc->vector_size;
+                       snprintf(s, sizeof(s), "vector_pool_%d", portid);
+                       vector_pool[portid] = rte_event_vector_pool_create(
+                               s, nb_vec, 0, evt_rsrc->vector_size, socketid);
+                       if (vector_pool[portid] == NULL)
+                               rte_exit(EXIT_FAILURE,
+                                        "Failed to create vector pool for port %d\n",
+                                        portid);
+                       else
+                               printf("Allocated vector pool for port %d\n",
+                                      portid);
+               }
+
                qconf = &lcore_conf[lcore_id];
                qconf->ipv4_lookup_struct =
                        l3fwd_lkp.get_ipv4_lookup_struct(socketid);
@@ -902,7 +1068,7 @@ check_all_ports_link_status(uint32_t port_mask)
                                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;
                        }
@@ -987,7 +1153,7 @@ config_port_max_pkt_len(struct rte_eth_conf *conf,
        conf->rxmode.mtu = max_pkt_len - overhead_len;
 
        if (conf->rxmode.mtu > RTE_ETHER_MTU)
-               conf->txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
+               conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
 
        return 0;
 }
@@ -1052,15 +1218,15 @@ l3fwd_poll_resource_setup(void)
                                "Invalid max packet length: %u (port %u)\n",
                                max_pkt_len, portid);
 
-               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;
 
                local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
                        dev_info.flow_type_rss_offloads;
 
                if (dev_info.max_rx_queues == 1)
-                       local_port_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
+                       local_port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE;
 
                if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
                                port_conf.rx_adv_conf.rss_conf.rss_hf) {
@@ -1322,8 +1488,12 @@ main(int argc, char **argv)
        /* Setup function pointers for lookup method. */
        setup_l3fwd_lookup_tables();
 
+       /* Add the config file rules */
+       l3fwd_lkp.read_config_files();
+
        evt_rsrc->per_port_pool = per_port_pool;
        evt_rsrc->pkt_pool = pktmbuf_pool;
+       evt_rsrc->vec_pool = vector_pool;
        evt_rsrc->port_mask = enabled_port_mask;
        /* Configure eventdev parameters if user has requested */
        if (evt_rsrc->enabled) {
@@ -1427,6 +1597,9 @@ main(int argc, char **argv)
                }
        }
 
+       /* clean up config file routes */
+       l3fwd_lkp.free_routes();
+
        /* clean up the EAL */
        rte_eal_cleanup();