diff mbox series

[ovs-dev,branch-2.11] dpif-netlink: avoid netlink modify flow put op failed after tc modify flow put op failed.

Message ID 1584773695-6933-1-git-send-email-wenxu@ucloud.cn
State Accepted
Commit af22bea5e86d602c28c7807cf3e900e9f5745da0
Headers show
Series [ovs-dev,branch-2.11] dpif-netlink: avoid netlink modify flow put op failed after tc modify flow put op failed. | expand

Commit Message

wenxu March 21, 2020, 6:54 a.m. UTC
From: wenxu <wenxu@ucloud.cn>

The tc modify flow put always delete the original flow first and
then add the new flow. If the modfiy flow put operation failed,
the flow put operation will change from modify to create if success
to delete the original flow in tc (which will be always failed with
ENOENT, the flow is already be deleted before add the new flow in tc).
Finally, the modify flow put will failed to add in kernel datapath.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 lib/dpif-netlink.c       | 7 ++++++-
 lib/netdev-tc-offloads.c | 6 +++++-
 lib/netdev.h             | 3 +++
 3 files changed, 14 insertions(+), 2 deletions(-)

Comments

Simon Horman March 25, 2020, 5:41 p.m. UTC | #1
On Sat, Mar 21, 2020 at 02:54:55PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> The tc modify flow put always delete the original flow first and
> then add the new flow. If the modfiy flow put operation failed,
> the flow put operation will change from modify to create if success
> to delete the original flow in tc (which will be always failed with
> ENOENT, the flow is already be deleted before add the new flow in tc).
> Finally, the modify flow put will failed to add in kernel datapath.
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>

Thanks, applied to branch 2.11.
diff mbox series

Patch

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 165b7a9..3bb951c 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2037,6 +2037,7 @@  parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
     info.dpif_class = dpif_class;
     info.tp_dst_port = dst_port;
     info.tunnel_csum_on = csum_on;
+    info.tc_modify_flow_deleted = false;
     err = netdev_flow_put(dev, &match,
                           CONST_CAST(struct nlattr *, put->actions),
                           put->actions_len,
@@ -2084,7 +2085,11 @@  parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
 out:
     if (err && err != EEXIST && (put->flags & DPIF_FP_MODIFY)) {
         /* Modified rule can't be offloaded, try and delete from HW */
-        int del_err = netdev_flow_del(dev, put->ufid, put->stats);
+        int del_err = 0;
+
+        if (!info.tc_modify_flow_deleted) {
+            del_err = netdev_flow_del(dev, put->ufid, put->stats);
+        }
 
         if (!del_err) {
             /* Delete from hw success, so old flow was offloaded.
diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c
index d309810..5a62e91 100644
--- a/lib/netdev-tc-offloads.c
+++ b/lib/netdev-tc-offloads.c
@@ -1317,8 +1317,12 @@  netdev_tc_flow_put(struct netdev *netdev, struct match *match,
     block_id = get_block_id_from_netdev(netdev);
     handle = get_ufid_tc_mapping(ufid, &prio, NULL);
     if (handle && prio) {
+        bool flow_deleted;
+
         VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", handle, prio);
-        del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid);
+        flow_deleted = !del_filter_and_ufid_mapping(ifindex, prio, handle,
+                                                   block_id, ufid);
+        info->tc_modify_flow_deleted = flow_deleted;
     }
 
     if (!prio) {
diff --git a/lib/netdev.h b/lib/netdev.h
index d94817f..2d2d6f3 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -208,6 +208,9 @@  struct offload_info {
      * it will be in the pkt meta data.
      */
     uint32_t flow_mark;
+
+    bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
+                                  * to delete the original flow. */
 };
 struct dpif_class;
 struct netdev_flow_dump;