]> git.droids-corp.org - dpdk.git/commitdiff
app/testpmd: fix use of indirect action after port close
authorDmitry Kozlyuk <dkozlyuk@nvidia.com>
Mon, 7 Mar 2022 16:48:21 +0000 (18:48 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 25 May 2022 10:50:57 +0000 (12:50 +0200)
When a port was closed, indirect actions could remain
with their handles no longer valid.
If a newly attached device was assigned the same ID as the closed port,
those indirect actions became accessible again.
Any attempt to use them resulted in an undefined behavior.
Automatically flush indirect actions when a port is closed.

Fixes: 4b61b8774be9 ("ethdev: introduce indirect flow action")
Cc: stable@dpdk.org
Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
Acked-by: Aman Singh <aman.deep.singh@intel.com>
app/test-pmd/config.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h

index 1b1e738f8360a7e9a95167f7d2511cd1fc79c069..dc9ef1e8682abdf4eb8cdd80804f3e6319867e4d 100644 (file)
@@ -1905,6 +1905,37 @@ port_action_handle_destroy(portid_t port_id,
        return ret;
 }
 
+int
+port_action_handle_flush(portid_t port_id)
+{
+       struct rte_port *port;
+       struct port_indirect_action **tmp;
+       int ret = 0;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+           port_id == (portid_t)RTE_PORT_ALL)
+               return -EINVAL;
+       port = &ports[port_id];
+       tmp = &port->actions_list;
+       while (*tmp != NULL) {
+               struct rte_flow_error error;
+               struct port_indirect_action *pia = *tmp;
+
+               /* Poisoning to make sure PMDs update it in case of error. */
+               memset(&error, 0x44, sizeof(error));
+               if (pia->handle != NULL &&
+                   rte_flow_action_handle_destroy
+                                       (port_id, pia->handle, &error) != 0) {
+                       printf("Indirect action #%u not destroyed\n", pia->id);
+                       ret = port_flow_complain(&error);
+                       tmp = &pia->next;
+               } else {
+                       *tmp = pia->next;
+                       free(pia);
+               }
+       }
+       return ret;
+}
 
 /** Get indirect action by port + id */
 struct rte_flow_action_handle *
index 777763f749a88065feda576357ecd524a9c3b293..5b742911a84cb11fb9757f0922673f3a0f3ed242 100644 (file)
@@ -3216,6 +3216,7 @@ close_port(portid_t pid)
                if (is_proc_primary()) {
                        port_flow_flush(pi);
                        port_flex_item_flush(pi);
+                       port_action_handle_flush(pi);
                        rte_eth_dev_close(pi);
                }
 
index f04a9a11b4e3286f531880cca61888085b9af587..8ee682b362e508f58b010194aeb4d9b1f4fa0868 100644 (file)
@@ -910,6 +910,7 @@ int port_action_handle_create(portid_t port_id, uint32_t id,
                              const struct rte_flow_action *action);
 int port_action_handle_destroy(portid_t port_id,
                               uint32_t n, const uint32_t *action);
+int port_action_handle_flush(portid_t port_id);
 struct rte_flow_action_handle *port_action_handle_get_by_id(portid_t port_id,
                                                            uint32_t id);
 int port_action_handle_update(portid_t port_id, uint32_t id,