app/testpmd: fix potential out of bounds read
[dpdk.git] / app / test-pmd / testpmd.c
index 43329ed..3057791 100644 (file)
@@ -57,7 +57,6 @@
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
 #include <rte_launch.h>
-#include <rte_tailq.h>
 #include <rte_eal.h>
 #include <rte_per_lcore.h>
 #include <rte_lcore.h>
@@ -333,7 +332,7 @@ find_next_port(portid_t p, struct rte_port *ports, int size)
        if (ports == NULL)
                rte_exit(-EINVAL, "failed to find a next port id\n");
 
-       while ((ports[p].enabled == 0) && (p < size))
+       while ((p < size) && (ports[p].enabled == 0))
                p++;
        return p;
 }
@@ -579,20 +578,6 @@ init_config(void)
                                                 socket_num);
        }
 
-       /* Configuration of Ethernet ports. */
-       ports = rte_zmalloc("testpmd: ports",
-                           sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
-                           RTE_CACHE_LINE_SIZE);
-       if (ports == NULL) {
-               rte_exit(EXIT_FAILURE,
-                               "rte_zmalloc(%d struct rte_port) failed\n",
-                               RTE_MAX_ETHPORTS);
-       }
-
-       /* enabled allocated ports */
-       for (pid = 0; pid < nb_ports; pid++)
-               ports[pid].enabled = 1;
-
        FOREACH_PORT(pid, ports) {
                port = &ports[pid];
                rte_eth_dev_info_get(pid, &port->dev_info);
@@ -1329,7 +1314,7 @@ port_is_closed(portid_t port_id)
 int
 start_port(portid_t pid)
 {
-       int diag, need_check_link_status = 0;
+       int diag, need_check_link_status = -1;
        portid_t pi;
        queueid_t qi;
        struct rte_port *port;
@@ -1340,6 +1325,9 @@ start_port(portid_t pid)
                return -1;
        }
 
+       if (port_id_is_invalid(pid, ENABLED_WARN))
+               return 0;
+
        if (init_fwd_streams() < 0) {
                printf("Fail from init_fwd_streams()\n");
                return -1;
@@ -1351,6 +1339,7 @@ start_port(portid_t pid)
                if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
                        continue;
 
+               need_check_link_status = 0;
                port = &ports[pi];
                if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
                                                 RTE_PORT_HANDLING) == 0) {
@@ -1471,9 +1460,9 @@ start_port(portid_t pid)
                need_check_link_status = 1;
        }
 
-       if (need_check_link_status && !no_link_check)
+       if (need_check_link_status == 1 && !no_link_check)
                check_all_ports_link_status(RTE_PORT_ALL);
-       else
+       else if (need_check_link_status == 0)
                printf("Please stop the ports first\n");
 
        printf("Done\n");
@@ -1495,10 +1484,14 @@ stop_port(portid_t pid)
                dcb_test = 0;
                dcb_config = 0;
        }
+
+       if (port_id_is_invalid(pid, ENABLED_WARN))
+               return;
+
        printf("Stopping ports...\n");
 
        FOREACH_PORT(pi, ports) {
-               if (!port_id_is_invalid(pid, DISABLED_WARN) && pid != pi)
+               if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
                        continue;
 
                port = &ports[pi];
@@ -1530,10 +1523,13 @@ close_port(portid_t pid)
                return;
        }
 
+       if (port_id_is_invalid(pid, ENABLED_WARN))
+               return;
+
        printf("Closing ports...\n");
 
        FOREACH_PORT(pi, ports) {
-               if (!port_id_is_invalid(pid, DISABLED_WARN) && pid != pi)
+               if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
                        continue;
 
                port = &ports[pi];
@@ -1637,6 +1633,9 @@ pmd_test_exit(void)
 {
        portid_t pt_id;
 
+       if (test_done == 0)
+               stop_packet_forwarding();
+
        FOREACH_PORT(pt_id, ports) {
                printf("Stopping port %d...", pt_id);
                fflush(stdout);
@@ -1999,6 +1998,26 @@ init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
        return 0;
 }
 
+static void
+init_port(void)
+{
+       portid_t pid;
+
+       /* Configuration of Ethernet ports. */
+       ports = rte_zmalloc("testpmd: ports",
+                           sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
+                           RTE_CACHE_LINE_SIZE);
+       if (ports == NULL) {
+               rte_exit(EXIT_FAILURE,
+                               "rte_zmalloc(%d struct rte_port) failed\n",
+                               RTE_MAX_ETHPORTS);
+       }
+
+       /* enabled allocated ports */
+       for (pid = 0; pid < nb_ports; pid++)
+               ports[pid].enabled = 1;
+}
+
 int
 main(int argc, char** argv)
 {
@@ -2013,6 +2032,9 @@ main(int argc, char** argv)
        if (nb_ports == 0)
                RTE_LOG(WARNING, EAL, "No probed ethernet devices\n");
 
+       /* allocate port structures, and init them */
+       init_port();
+
        set_def_fwd_config();
        if (nb_lcores == 0)
                rte_panic("Empty set of forwarding logical cores - check the "