* priority less than or equal to PRIO.
  */
 static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen,
-                                       u8 tos, u32 prio)
+                                       u8 tos, u32 prio, u32 tb_id)
 {
        struct fib_alias *fa;
 
                        continue;
                if (fa->fa_slen != slen)
                        break;
+               if (fa->tb_id > tb_id)
+                       continue;
+               if (fa->tb_id != tb_id)
+                       break;
                if (fa->fa_tos > tos)
                        continue;
                if (fa->fa_info->fib_priority >= prio || fa->fa_tos < tos)
                hlist_for_each_entry(last, &l->leaf, fa_list) {
                        if (new->fa_slen < last->fa_slen)
                                break;
+                       if ((new->fa_slen == last->fa_slen) &&
+                           (new->tb_id > last->tb_id))
+                               break;
                        fa = last;
                }
 
        }
 
        l = fib_find_node(t, &tp, key);
-       fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority) : NULL;
+       fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority,
+                               tb->tb_id) : NULL;
 
        /* Now fa, if non-NULL, points to the first fib alias
         * with the same keys [prefix,tos,priority], if such key already
                fa_match = NULL;
                fa_first = fa;
                hlist_for_each_entry_from(fa, fa_list) {
-                       if ((fa->fa_slen != slen) || (fa->fa_tos != tos))
+                       if ((fa->fa_slen != slen) ||
+                           (fa->tb_id != tb->tb_id) ||
+                           (fa->fa_tos != tos))
                                break;
                        if (fa->fa_info->fib_priority != fi->fib_priority)
                                break;
-                       /* duplicate entry from another table */
-                       if (WARN_ON(fa->tb_id != tb->tb_id))
-                               continue;
                        if (fa->fa_type == cfg->fc_type &&
                            fa->fa_info == fi) {
                                fa_match = fa;
        if (!l)
                return -ESRCH;
 
-       fa = fib_find_alias(&l->leaf, slen, tos, 0);
+       fa = fib_find_alias(&l->leaf, slen, tos, 0, tb->tb_id);
        if (!fa)
                return -ESRCH;
 
        hlist_for_each_entry_from(fa, fa_list) {
                struct fib_info *fi = fa->fa_info;
 
-               if ((fa->fa_slen != slen) || (fa->fa_tos != tos))
+               if ((fa->fa_slen != slen) ||
+                   (fa->tb_id != tb->tb_id) ||
+                   (fa->fa_tos != tos))
                        break;
 
-               if (fa->tb_id != tb->tb_id)
-                       continue;
-
                if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) &&
                    (cfg->fc_scope == RT_SCOPE_NOWHERE ||
                     fa->fa_info->fib_scope == cfg->fc_scope) &&