diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index bb62398b6157..8fcc935dacde 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -43,7 +43,8 @@ VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);
 
 static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5);
 
-static struct hmap ufid_tc = HMAP_INITIALIZER(&ufid_tc);
+static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc);
+static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid);
 static bool multi_mask_per_prio = false;
 static bool block_support = false;
 
@@ -143,44 +144,49 @@ static struct netlink_field set_flower_map[][4] = {
 static struct ovs_mutex ufid_lock = OVS_MUTEX_INITIALIZER;
 
 /**
- * struct ufid_tc_data - data entry for ufid_tc hmap.
- * @ufid_node: Element in @ufid_tc hash table by ufid key.
- * @tc_node: Element in @ufid_tc hash table by tc_id key.
+ * struct ufid_tc_data - data entry for ufid-tc hashmaps.
+ * @ufid_to_tc_node: Element in @ufid_to_tc hash table by ufid key.
+ * @tc_to_ufid_node: Element in @tc_to_ufid hash table by tc_id key.
  * @ufid: ufid assigned to the flow
  * @id: tc id
  * @netdev: netdev associated with the tc rule
  */
 struct ufid_tc_data {
-    struct hmap_node ufid_node;
-    struct hmap_node tc_node;
+    struct hmap_node ufid_to_tc_node;
+    struct hmap_node tc_to_ufid_node;
     ovs_u128 ufid;
     struct tc_id id;
     struct netdev *netdev;
 };
 
-/* Remove matching ufid entry from ufid_tc hashmap. */
 static void
-del_ufid_tc_mapping(const ovs_u128 *ufid)
+del_ufid_tc_mapping_unlocked(const ovs_u128 *ufid)
 {
     size_t ufid_hash = hash_bytes(ufid, sizeof *ufid, 0);
     struct ufid_tc_data *data;
 
-    ovs_mutex_lock(&ufid_lock);
-    HMAP_FOR_EACH_WITH_HASH(data, ufid_node, ufid_hash, &ufid_tc) {
+    HMAP_FOR_EACH_WITH_HASH (data, ufid_to_tc_node, ufid_hash, &ufid_to_tc) {
         if (ovs_u128_equals(*ufid, data->ufid)) {
             break;
         }
     }
 
     if (!data) {
-        ovs_mutex_unlock(&ufid_lock);
         return;
     }
 
-    hmap_remove(&ufid_tc, &data->ufid_node);
-    hmap_remove(&ufid_tc, &data->tc_node);
+    hmap_remove(&ufid_to_tc, &data->ufid_to_tc_node);
+    hmap_remove(&tc_to_ufid, &data->tc_to_ufid_node);
     netdev_close(data->netdev);
     free(data);
+}
+
+/* Remove matching ufid entry from ufid-tc hashmaps. */
+static void
+del_ufid_tc_mapping(const ovs_u128 *ufid)
+{
+    ovs_mutex_lock(&ufid_lock);
+    del_ufid_tc_mapping_unlocked(ufid);
     ovs_mutex_unlock(&ufid_lock);
 }
 
@@ -195,7 +201,7 @@ del_filter_and_ufid_mapping(struct tc_id *id, const ovs_u128 *ufid)
     return err;
 }
 
-/* Add ufid entry to ufid_tc hashmap. */
+/* Add ufid entry to ufid_to_tc hashmap. */
 static void
 add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid,
                     struct tc_id *id)
@@ -209,12 +215,12 @@ add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid,
     new_data->netdev = netdev_ref(netdev);
 
     ovs_mutex_lock(&ufid_lock);
-    hmap_insert(&ufid_tc, &new_data->ufid_node, ufid_hash);
-    hmap_insert(&ufid_tc, &new_data->tc_node, tc_hash);
+    hmap_insert(&ufid_to_tc, &new_data->ufid_to_tc_node, ufid_hash);
+    hmap_insert(&tc_to_ufid, &new_data->tc_to_ufid_node, tc_hash);
     ovs_mutex_unlock(&ufid_lock);
 }
 
-/* Get tc id from ufid_tc hashmap.
+/* Get tc id from ufid_to_tc hashmap.
  *
  * Returns 0 if successful and fills id.
  * Otherwise returns the error.
@@ -226,7 +232,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, struct tc_id *id)
     struct ufid_tc_data *data;
 
     ovs_mutex_lock(&ufid_lock);
-    HMAP_FOR_EACH_WITH_HASH(data, ufid_node, ufid_hash, &ufid_tc) {
+    HMAP_FOR_EACH_WITH_HASH (data, ufid_to_tc_node, ufid_hash, &ufid_to_tc) {
         if (ovs_u128_equals(*ufid, data->ufid)) {
             *id = data->id;
             ovs_mutex_unlock(&ufid_lock);
@@ -238,7 +244,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, struct tc_id *id)
     return ENOENT;
 }
 
-/* Find ufid entry in ufid_tc hashmap using tc_id id.
+/* Find ufid entry in ufid_to_tc hashmap using tc_id id.
  * The result is saved in ufid.
  *
  * Returns true on success.
@@ -250,7 +256,7 @@ find_ufid(struct netdev *netdev, struct tc_id *id, ovs_u128 *ufid)
     struct ufid_tc_data *data;
 
     ovs_mutex_lock(&ufid_lock);
-    HMAP_FOR_EACH_WITH_HASH(data, tc_node, tc_hash,  &ufid_tc) {
+    HMAP_FOR_EACH_WITH_HASH (data, tc_to_ufid_node, tc_hash,  &tc_to_ufid) {
         if (netdev == data->netdev
             && data->id.prio == id->prio
             && data->id.handle == id->handle
@@ -298,7 +304,7 @@ get_prio_for_tc_flower(struct tc_flower *flower)
      * different prio if not. Flower classifier will reject same prio for
      * different mask combination unless multi mask per prio is supported. */
     ovs_mutex_lock(&prios_lock);
-    HMAP_FOR_EACH_WITH_HASH(data, node, hash, &prios) {
+    HMAP_FOR_EACH_WITH_HASH (data, node, hash, &prios) {
         if ((multi_mask_per_prio
              || !memcmp(&flower->mask, &data->mask, key_len))
             && data->protocol == flower->key.eth_type) {
@@ -337,21 +343,23 @@ get_block_id_from_netdev(struct netdev *netdev)
 static int
 netdev_tc_flow_flush(struct netdev *netdev)
 {
-    enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev);
-    int ifindex = netdev_get_ifindex(netdev);
-    uint32_t block_id = 0;
-    struct tc_id id;
-    int prio = 0;
+    struct ufid_tc_data *data, *next;
+    int err;
 
-    if (ifindex < 0) {
-        VLOG_ERR_RL(&error_rl, "flow_flush: failed to get ifindex for %s: %s",
-                    netdev_get_name(netdev), ovs_strerror(-ifindex));
-        return -ifindex;
+    ovs_mutex_lock(&ufid_lock);
+    HMAP_FOR_EACH_SAFE (data, next, tc_to_ufid_node, &tc_to_ufid) {
+        if (data->netdev != netdev) {
+            continue;
+        }
+
+        err = tc_del_filter(&data->id);
+        if (!err) {
+            del_ufid_tc_mapping_unlocked(&data->ufid);
+        }
     }
+    ovs_mutex_unlock(&ufid_lock);
 
-    block_id = get_block_id_from_netdev(netdev);
-    id = make_tc_id(ifindex, block_id, prio, hook);
-    return tc_del_filter(&id);
+    return 0;
 }
 
 static int
