After a local TC filter rule is installed and the flow is inserted
into pmd->flows, failure during remote flow creation jumps to the
fail label which frees the flow without removing it from the list
and without deleting the kernel-side TC rule.

Send RTM_DELTFILTER to clean up the local rule and call
LIST_REMOVE before freeing.

Bugzilla ID: 1881
Fixes: 2bc06869cd94 ("net/tap: add remote netdevice traffic capture")
Cc: [email protected]

Signed-off-by: Stephen Hemminger <[email protected]>
---
 drivers/net/tap/tap_flow.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 9d4ef27a8a..427faf75d5 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1293,7 +1293,7 @@ tap_flow_create(struct rte_eth_dev *dev,
                        rte_flow_error_set(
                                error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                                "cannot allocate memory for rte_flow");
-                       goto fail;
+                       goto fail_remove;
                }
                msg = &remote_flow->msg;
                /* set the rule if_index for the remote netdevice */
@@ -1307,14 +1307,14 @@ tap_flow_create(struct rte_eth_dev *dev,
                        rte_flow_error_set(
                                error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
                                NULL, "rte flow rule validation failed");
-                       goto fail;
+                       goto fail_remove;
                }
                err = tap_nl_send(pmd->nlsk_fd, &msg->nh);
                if (err < 0) {
                        rte_flow_error_set(
                                error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
                                NULL, "Failure sending nl request");
-                       goto fail;
+                       goto fail_remove;
                }
                err = tap_nl_recv_ack(pmd->nlsk_fd);
                if (err < 0) {
@@ -1325,15 +1325,22 @@ tap_flow_create(struct rte_eth_dev *dev,
                                error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
                                NULL,
                                "overlapping rules or Kernel too old for flower 
support");
-                       goto fail;
+                       goto fail_remove;
                }
                flow->remote_flow = remote_flow;
        }
        return flow;
+
+fail_remove:
+       /* Delete the local TC rule that was already installed */
+       flow->msg.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+       flow->msg.nh.nlmsg_type = RTM_DELTFILTER;
+       if (tap_nl_send(pmd->nlsk_fd, &flow->msg.nh) >= 0)
+               tap_nl_recv_ack(pmd->nlsk_fd);
+       LIST_REMOVE(flow, next);
 fail:
        rte_free(remote_flow);
-       if (flow)
-               tap_flow_free(pmd, flow);
+       tap_flow_free(pmd, flow);
        return NULL;
 }
 
-- 
2.51.0

Reply via email to