ethdev: use constants for link state
[dpdk.git] / examples / l3fwd / main.c
index 792894f..bf6d885 100644 (file)
@@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
 static int l3fwd_em_on;
 
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+                       /**< disabled by default */
 
 /* Global variables. */
 
@@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
        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);
@@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
        .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,
@@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
        .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,
@@ -263,9 +271,14 @@ get_port_n_rx_queues(const uint8_t port)
        uint16_t i;
 
        for (i = 0; i < nb_lcore_params; ++i) {
-               if (lcore_params[i].port_id == port &&
-                       lcore_params[i].queue_id > queue)
-                       queue = lcore_params[i].queue_id;
+               if (lcore_params[i].port_id == port) {
+                       if (lcore_params[i].queue_id == queue+1)
+                               queue = lcore_params[i].queue_id;
+                       else
+                               rte_exit(EXIT_FAILURE, "queue ids of the port %d must be"
+                                               " in sequence and must start with 0\n",
+                                               lcore_params[i].port_id);
+               }
        }
        return (uint8_t)(++queue);
 }
@@ -456,6 +469,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -486,6 +500,7 @@ parse_args(int argc, char **argv)
                {CMD_LINE_OPT_IPV6, 0, 0, 0},
                {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
                {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+               {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
                {NULL, 0, 0, 0}
        };
 
@@ -612,6 +627,14 @@ parse_args(int argc, char **argv)
                                        return -1;
                                }
                        }
+
+                       if (!strncmp(lgopts[option_index].name,
+                                    CMD_LINE_OPT_PARSE_PTYPE,
+                                    sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+                               printf("soft parse-ptype is enabled\n");
+                               parse_ptype = 1;
+                       }
+
                        break;
 
                default:
@@ -746,7 +769,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
                                continue;
                        }
                        /* clear all_ports_up flag if any link down */
-                       if (link.link_status == 0) {
+                       if (link.link_status == ETH_LINK_DOWN) {
                                all_ports_up = 0;
                                break;
                        }
@@ -779,6 +802,28 @@ signal_handler(int signum)
        }
 }
 
+static int
+prepare_ptype_parser(uint8_t portid, uint16_t queueid)
+{
+       if (parse_ptype) {
+               printf("Port %d: softly parse packet type info\n", portid);
+               if (rte_eth_add_rx_callback(portid, queueid,
+                                           l3fwd_lkp.cb_parse_ptype,
+                                           NULL))
+                       return 1;
+
+               printf("Failed to add rx callback: port=%d\n", portid);
+               return 0;
+       }
+
+       if (l3fwd_lkp.check_ptype(portid))
+               return 1;
+
+       printf("port %d cannot parse packet type, please add --%s\n",
+              portid, CMD_LINE_OPT_PARSE_PTYPE);
+       return 0;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -791,7 +836,6 @@ main(int argc, char **argv)
        unsigned lcore_id;
        uint32_t n_tx_queue, nb_lcores;
        uint8_t portid, nb_rx_queue, queue, socketid;
-       uint8_t nb_tx_port;
 
        /* init EAL */
        ret = rte_eal_init(argc, argv);
@@ -831,7 +875,6 @@ main(int argc, char **argv)
                rte_exit(EXIT_FAILURE, "check_port_config failed\n");
 
        nb_lcores = rte_lcore_count();
-       nb_tx_port = 0;
 
        /* Setup function pointers for lookup method. */
        setup_l3fwd_lookup_tables();
@@ -909,12 +952,10 @@ main(int argc, char **argv)
                        qconf->tx_queue_id[portid] = queueid;
                        queueid++;
 
-                       qconf->n_tx_port = nb_tx_port;
                        qconf->tx_port_id[qconf->n_tx_port] = portid;
+                       qconf->n_tx_port++;
                }
                printf("\n");
-
-               nb_tx_port++;
        }
 
        for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
@@ -972,6 +1013,21 @@ main(int argc, char **argv)
                        rte_eth_promiscuous_enable(portid);
        }
 
+       printf("\n");
+
+       for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+               if (rte_lcore_is_enabled(lcore_id) == 0)
+                       continue;
+               qconf = &lcore_conf[lcore_id];
+               for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
+                       portid = qconf->rx_queue_list[queue].port_id;
+                       queueid = qconf->rx_queue_list[queue].queue_id;
+                       if (prepare_ptype_parser(portid, queueid) == 0)
+                               rte_exit(EXIT_FAILURE, "ptype check fails\n");
+               }
+       }
+
+
        check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask);
 
        ret = 0;