FRA_UNUSED5,
        FRA_FWMARK,     /* netfilter mark (IPv4) */
        FRA_FLOW,       /* flow/class id */
+       FRA_UNUSED6,
+       FRA_UNUSED7,
+       FRA_UNUSED8,
+       FRA_TABLE,      /* Extended table id */
        __FRA_MAX
 };
 
 
        RTA_CACHEINFO,
        RTA_SESSION,
        RTA_MP_ALGO,
+       RTA_TABLE,
        __RTA_MAX
 };
 
        } \
 } while(0)
 
+static inline u32 rtm_get_table(struct rtattr **rta, u8 table)
+{
+       return RTA_GET_U32(rta[RTA_TABLE-1]);
+rtattr_failure:
+       return table;
+}
+
 #endif /* __KERNEL__ */
 
 
 
                call_rcu(&rule->rcu, fib_rule_put_rcu);
 }
 
+static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
+{
+       if (nla[FRA_TABLE])
+               return nla_get_u32(nla[FRA_TABLE]);
+       return frh->table;
+}
+
 extern int                     fib_rules_register(struct fib_rules_ops *);
 extern int                     fib_rules_unregister(struct fib_rules_ops *);
 
 
 
        rule->action = frh->action;
        rule->flags = frh->flags;
-       rule->table = frh->table;
+       rule->table = frh_get_table(frh, tb);
 
        if (!rule->pref && ops->default_pref)
                rule->pref = ops->default_pref();
                if (frh->action && (frh->action != rule->action))
                        continue;
 
-               if (frh->table && (frh->table != rule->table))
+               if (frh->table && (frh_get_table(frh, tb) != rule->table))
                        continue;
 
                if (tb[FRA_PRIORITY] &&
 
        frh = nlmsg_data(nlh);
        frh->table = rule->table;
+       NLA_PUT_U32(skb, FRA_TABLE, rule->table);
        frh->res1 = 0;
        frh->res2 = 0;
        frh->action = rule->action;
 
                if (attr) {
                        if (RTA_PAYLOAD(attr) < 4 && RTA_PAYLOAD(attr) != 2)
                                return -EINVAL;
-                       if (i != RTA_MULTIPATH && i != RTA_METRICS)
+                       if (i != RTA_MULTIPATH && i != RTA_METRICS &&
+                           i != RTA_TABLE)
                                rta[i-1] = (struct rtattr *)RTA_DATA(attr);
                }
        }
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
-       tb = dn_fib_get_table(r->rtm_table, 0);
+       tb = dn_fib_get_table(rtm_get_table(rta, r->rtm_table), 0);
        if (tb)
                return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));
 
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
-       tb = dn_fib_get_table(r->rtm_table, 1);
+       tb = dn_fib_get_table(rtm_get_table(rta, r->rtm_table), 1);
        if (tb) 
                return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));
 
 
        r->rtm_src_len = 0;
        r->rtm_tos = 0;
        r->rtm_table = RT_TABLE_MAIN;
+       RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
        r->rtm_type = rt->rt_type;
        r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
        r->rtm_scope = RT_SCOPE_UNIVERSE;
 
         rtm->rtm_src_len = 0;
         rtm->rtm_tos = 0;
         rtm->rtm_table = tb_id;
+       RTA_PUT_U32(skb, RTA_TABLE, tb_id);
         rtm->rtm_flags = fi->fib_flags;
         rtm->rtm_scope = scope;
        rtm->rtm_type  = type;
 
                if (attr) {
                        if (RTA_PAYLOAD(attr) < 4)
                                return -EINVAL;
-                       if (i != RTA_MULTIPATH && i != RTA_METRICS)
+                       if (i != RTA_MULTIPATH && i != RTA_METRICS &&
+                           i != RTA_TABLE)
                                *rta = (struct rtattr*)RTA_DATA(attr);
                }
        }
        if (inet_check_attr(r, rta))
                return -EINVAL;
 
-       tb = fib_get_table(r->rtm_table);
+       tb = fib_get_table(rtm_get_table(rta, r->rtm_table));
        if (tb)
                return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
        return -ESRCH;
        if (inet_check_attr(r, rta))
                return -EINVAL;
 
-       tb = fib_new_table(r->rtm_table);
+       tb = fib_new_table(rtm_get_table(rta, r->rtm_table));
        if (tb)
                return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
        return -ENOBUFS;
 
        [FRA_DST]       = { .type = NLA_U32 },
        [FRA_FWMARK]    = { .type = NLA_U32 },
        [FRA_FLOW]      = { .type = NLA_U32 },
+       [FRA_TABLE]     = { .type = NLA_U32 },
 };
 
 static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
 
        rtm->rtm_src_len = 0;
        rtm->rtm_tos = tos;
        rtm->rtm_table = tb_id;
+       RTA_PUT_U32(skb, RTA_TABLE, tb_id);
        rtm->rtm_type = type;
        rtm->rtm_flags = fi->fib_flags;
        rtm->rtm_scope = scope;
 
        r->rtm_src_len  = 0;
        r->rtm_tos      = rt->fl.fl4_tos;
        r->rtm_table    = RT_TABLE_MAIN;
+       RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
        r->rtm_type     = rt->rt_type;
        r->rtm_scope    = RT_SCOPE_UNIVERSE;
        r->rtm_protocol = RTPROT_UNSPEC;
 
        [FRA_PRIORITY]  = { .type = NLA_U32 },
        [FRA_SRC]       = { .minlen = sizeof(struct in6_addr) },
        [FRA_DST]       = { .minlen = sizeof(struct in6_addr) },
+       [FRA_TABLE]     = { .type = NLA_U32 },
 };
 
 static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
 
 
        if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
                return -EINVAL;
-       return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb), r->rtm_table);
+       return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb),
+                            rtm_get_table(arg, r->rtm_table));
 }
 
 int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
        if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
                return -EINVAL;
-       return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb), r->rtm_table);
+       return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb),
+                            rtm_get_table(arg, r->rtm_table));
 }
 
 struct rt6_rtnl_dump_arg
        struct nlmsghdr  *nlh;
        unsigned char    *b = skb->tail;
        struct rta_cacheinfo ci;
+       u32 table;
 
        if (prefix) {   /* user wants prefix routes only */
                if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
        rtm->rtm_src_len = rt->rt6i_src.plen;
        rtm->rtm_tos = 0;
        if (rt->rt6i_table)
-               rtm->rtm_table = rt->rt6i_table->tb6_id;
+               table = rt->rt6i_table->tb6_id;
        else
-               rtm->rtm_table = RT6_TABLE_UNSPEC;
+               table = RT6_TABLE_UNSPEC;
+       rtm->rtm_table = table;
+       RTA_PUT_U32(skb, RTA_TABLE, table);
        if (rt->rt6i_flags&RTF_REJECT)
                rtm->rtm_type = RTN_UNREACHABLE;
        else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))