]> git.proxmox.com Git - ovs.git/commitdiff
netdev-tc-offloads: Delete ufid tc mapping in the right place
authorChris Mi <chrism@mellanox.com>
Mon, 12 Nov 2018 02:08:38 +0000 (11:08 +0900)
committerSimon Horman <simon.horman@netronome.com>
Tue, 13 Nov 2018 13:23:35 +0000 (05:23 -0800)
Currently, the ufid tc mapping is deleted in add_ufid_tc_mapping().
But if tc_replace_flower() failed, the old ufid tc mapping will not
be deleted. If another thread adds the same tc mapping successfully,
then there will be multiple mappings for the same ifindex, handle
and prio.

Fixes: 9116730db ("netdev-tc-offloads: Add ufid to tc/netdev map")
Signed-off-by: Chris Mi <chrism@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
lib/netdev-tc-offloads.c

index 6f1fbe6678f94f395d2d55e16c4dde84c58dff94..606a4f4db45da00c0f46c8428f6e199bc138f104 100644 (file)
@@ -163,8 +163,20 @@ del_ufid_tc_mapping(const ovs_u128 *ufid)
     ovs_mutex_unlock(&ufid_lock);
 }
 
-/* Add ufid entry to ufid_tc hashmap.
- * If entry exists already it will be replaced. */
+/* Wrapper function to delete filter and ufid tc mapping */
+static int
+del_filter_and_ufid_mapping(int ifindex, int prio, int handle,
+                            uint32_t block_id, const ovs_u128 *ufid)
+{
+    int err;
+
+    err = tc_del_filter(ifindex, prio, handle, block_id);
+    del_ufid_tc_mapping(ufid);
+
+    return err;
+}
+
+/* Add ufid entry to ufid_tc hashmap. */
 static void
 add_ufid_tc_mapping(const ovs_u128 *ufid, int prio, int handle,
                     struct netdev *netdev, int ifindex)
@@ -173,8 +185,6 @@ add_ufid_tc_mapping(const ovs_u128 *ufid, int prio, int handle,
     size_t tc_hash = hash_int(hash_int(prio, handle), ifindex);
     struct ufid_tc_data *new_data = xzalloc(sizeof *new_data);
 
-    del_ufid_tc_mapping(ufid);
-
     new_data->ufid = *ufid;
     new_data->prio = prio;
     new_data->handle = handle;
@@ -1302,7 +1312,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
     handle = get_ufid_tc_mapping(ufid, &prio, NULL);
     if (handle && prio) {
         VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", handle, prio);
-        tc_del_filter(ifindex, prio, handle, block_id);
+        del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid);
     }
 
     if (!prio) {
@@ -1413,8 +1423,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
         }
     }
 
-    error = tc_del_filter(ifindex, prio, handle, block_id);
-    del_ufid_tc_mapping(ufid);
+    error = del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid);
 
     netdev_close(dev);