long                    knodes;
 };
 
+static u32 handle2id(u32 h)
+{
+       return ((h & 0x80000000) ? ((h >> 20) & 0x7FF) : h);
+}
+
+static u32 id2handle(u32 id)
+{
+       return (id | 0x800U) << 20;
+}
+
 static inline unsigned int u32_hash_fold(__be32 key,
                                         const struct tc_u32_sel *sel,
                                         u8 fshift)
        int id = idr_alloc_cyclic(&tp_c->handle_idr, ptr, 1, 0x7FF, GFP_KERNEL);
        if (id < 0)
                return 0;
-       return (id | 0x800U) << 20;
+       return id2handle(id);
 }
 
 static struct hlist_head *tc_u_common_hash;
                return -ENOBUFS;
 
        refcount_set(&root_ht->refcnt, 1);
-       root_ht->handle = tp_c ? gen_new_htid(tp_c, root_ht) : 0x80000000;
+       root_ht->handle = tp_c ? gen_new_htid(tp_c, root_ht) : id2handle(0);
        root_ht->prio = tp->prio;
        root_ht->is_root = true;
        idr_init(&root_ht->handle_idr);
                if (phn == ht) {
                        u32_clear_hw_hnode(tp, ht, extack);
                        idr_destroy(&ht->handle_idr);
-                       idr_remove(&tp_c->handle_idr, ht->handle);
+                       idr_remove(&tp_c->handle_idr, handle2id(ht->handle));
                        RCU_INIT_POINTER(*hn, ht->next);
                        kfree_rcu(ht, rcu);
                        return 0;
 
                err = u32_replace_hw_hnode(tp, ht, userflags, extack);
                if (err) {
-                       idr_remove(&tp_c->handle_idr, handle);
+                       idr_remove(&tp_c->handle_idr, handle2id(handle));
                        kfree(ht);
                        return err;
                }