[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