[NET]: Introduce RTA_TABLE routing attribute

Introduce RTA_TABLE routing attribute to hold 32 bit routing table IDs.
Usespace compatibility is provided by continuing to accept and send the
rtm_table field, but because of its limited size it can only carry the
low 8 bits of the table ID. This implies that if larger IDs are used,
_all_ userspace programs using them need to use RTA_TABLE.

Signed-off-by: Patrick McHardy <[EMAIL PROTECTED]>

---
commit 8cf1ae7345f935350dede855381dfbb620cabc1c
tree d674b6bb251dda0fcb915db0dbca98cda7779348
parent 7e3ac412e095b5a4d29a7244d5cee795267a7c6a
author Patrick McHardy <[EMAIL PROTECTED]> Mon, 03 Jul 2006 08:13:14 +0200
committer Patrick McHardy <[EMAIL PROTECTED]> Mon, 03 Jul 2006 08:13:14 +0200

 include/linux/rtnetlink.h |    8 ++++++++
 net/decnet/dn_fib.c       |    7 ++++---
 net/decnet/dn_route.c     |    1 +
 net/decnet/dn_rules.c     |    6 ++++--
 net/decnet/dn_table.c     |    1 +
 net/ipv4/fib_frontend.c   |    7 ++++---
 net/ipv4/fib_rules.c      |    6 ++++--
 net/ipv4/fib_semantics.c  |    1 +
 net/ipv4/route.c          |    1 +
 net/ipv6/route.c          |    1 +
 10 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index facd9ee..8f6efff 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -263,6 +263,7 @@ enum rtattr_type_t
        RTA_CACHEINFO,
        RTA_SESSION,
        RTA_MP_ALGO,
+       RTA_TABLE,
        __RTA_MAX
 };
 
@@ -1065,6 +1066,13 @@ #define BUG_TRAP(x) do { \
        } \
 } while(0)
 
+static inline u32 rtm_get_table(struct rtmsg *rtm, struct rtattr **rta)
+{
+       return RTA_GET_U32(rta[RTA_TABLE-1]);
+rtattr_failure:
+       return rtm->rtm_table;
+}
+
 #endif /* __KERNEL__ */
 
 
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index f4c1c1e..a43e59b 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -491,7 +491,8 @@ static int dn_fib_check_attr(struct rtms
                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);
                }
        }
@@ -508,7 +509,7 @@ int dn_fib_rtm_delroute(struct sk_buff *
        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(r, rta), 0);
        if (tb)
                return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, 
&NETLINK_CB(skb));
 
@@ -524,7 +525,7 @@ int dn_fib_rtm_newroute(struct sk_buff *
        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(r, rta), 1);
        if (tb) 
                return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, 
&NETLINK_CB(skb));
 
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 1355614..2c5bc4e 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1480,6 +1480,7 @@ static int dn_rt_fill_info(struct sk_buf
        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;
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 16ca66b..d274d59 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -77,6 +77,7 @@ int dn_fib_rtm_delrule(struct sk_buff *s
        struct rtmsg *rtm = NLMSG_DATA(nlh);
        struct dn_fib_rule *r;
        struct hlist_node *node;
+       u32 table = rtm_get_table(rtm, rta);
        int err = -ESRCH;
 
        hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
@@ -90,7 +91,7 @@ #endif
                        (!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
                        (!rta[RTA_PRIORITY-1] || 
memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
                        (!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], 
r->r_ifname) == 0) &&
-                       (!rtm->rtm_table || (r && rtm->rtm_table == 
r->r_table))) {
+                       (!table || (r && table == r->r_table))) {
 
                        err = -EPERM;
                        if (r == &default_rule)
@@ -141,7 +142,7 @@ int dn_fib_rtm_newrule(struct sk_buff *s
        if (rtm->rtm_type == RTN_NAT)
                return -EINVAL;
 
-       table_id = rtm->rtm_table;
+       table_id = rtm_get_table(rtm, rta);
        if (table_id == RT_TABLE_UNSPEC) {
                struct dn_fib_table *tb;
                if (rtm->rtm_type == RTN_UNICAST) {
@@ -365,6 +366,7 @@ #ifdef CONFIG_DECNET_ROUTE_FWMARK
                RTA_PUT(skb, RTA_PROTOINFO, 4, &r->r_fwmark);
 #endif
        rtm->rtm_table = r->r_table;
+       RTA_PUT_U32(skb, RTA_TABLE, r->r_table);
        rtm->rtm_protocol = 0;
        rtm->rtm_scope = 0;
        rtm->rtm_type = r->r_action;
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 7de6a88..b165282 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -282,6 +282,7 @@ static int dn_fib_dump_info(struct sk_bu
         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;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4d5429a..2f54f22 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -293,7 +293,8 @@ static int inet_check_attr(struct rtmsg 
                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);
                }
        }
@@ -309,7 +310,7 @@ int inet_rtm_delroute(struct sk_buff *sk
        if (inet_check_attr(r, rta))
                return -EINVAL;
 
-       tb = fib_get_table(r->rtm_table);
+       tb = fib_get_table(rtm_get_table(r, rta));
        if (tb)
                return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, 
&NETLINK_CB(skb));
        return -ESRCH;
@@ -324,7 +325,7 @@ int inet_rtm_newroute(struct sk_buff *sk
        if (inet_check_attr(r, rta))
                return -EINVAL;
 
-       tb = fib_new_table(r->rtm_table);
+       tb = fib_new_table(rtm_get_table(r, rta));
        if (tb)
                return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, 
&NETLINK_CB(skb));
        return -ENOBUFS;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 71ede02..e6d1f5a 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -111,6 +111,7 @@ int inet_rtm_delrule(struct sk_buff *skb
        struct rtmsg *rtm = NLMSG_DATA(nlh);
        struct fib_rule *r;
        struct hlist_node *node;
+       u32 table = rtm_get_table(rtm, rta);
        int err = -ESRCH;
 
        hlist_for_each_entry(r, node, &fib_rules, hlist) {
@@ -125,7 +126,7 @@ #endif
                    (!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
                    (!rta[RTA_PRIORITY-1] || 
memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
                    (!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], 
r->r_ifname) == 0) &&
-                   (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
+                   (!table || (r && table == r->r_table))) {
                        err = -EPERM;
                        if (r == &local_rule)
                                break;
@@ -186,7 +187,7 @@ int inet_rtm_newrule(struct sk_buff *skb
        if (rta[RTA_IIF-1] && RTA_PAYLOAD(rta[RTA_IIF-1]) > IFNAMSIZ)
                return -EINVAL;
 
-       table_id = rtm->rtm_table;
+       table_id = rtm_get_table(rtm, rta);
        if (table_id == RT_TABLE_UNSPEC) {
                struct fib_table *table;
                if (rtm->rtm_type == RTN_UNICAST) {
@@ -403,6 +404,7 @@ #ifdef CONFIG_IP_ROUTE_FWMARK
                RTA_PUT(skb, RTA_PROTOINFO, 4, &r->r_fwmark);
 #endif
        rtm->rtm_table = r->r_table;
+       RTA_PUT_U32(skb, RTA_TABLE, r->r_table);
        rtm->rtm_protocol = 0;
        rtm->rtm_scope = 0;
        rtm->rtm_type = r->r_action;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 84537df..3c45256 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -954,6 +954,7 @@ fib_dump_info(struct sk_buff *skb, u32 p
        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;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index da44fab..7ef78f3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2638,6 +2638,7 @@ #endif
        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;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 87c39c9..4410282 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1745,6 +1745,7 @@ static int rt6_fill_node(struct sk_buff 
        rtm->rtm_src_len = rt->rt6i_src.plen;
        rtm->rtm_tos = 0;
        rtm->rtm_table = RT_TABLE_MAIN;
+       RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
        if (rt->rt6i_flags&RTF_REJECT)
                rtm->rtm_type = RTN_UNREACHABLE;
        else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to