]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
Add support for larger number of routing tables
authorPatrick McHardy <kaber@trash.net>
Thu, 10 Aug 2006 22:14:51 +0000 (00:14 +0200)
committerStephen Hemminger <shemminger@osdl.org>
Thu, 10 Aug 2006 23:12:07 +0000 (16:12 -0700)
[IPROUTE]: Add support for larger number of routing tables

Support support for 2^32 routing tables by using the new RTA_TABLE
attribute for specifying tables > 255 and intepreting it if it is
sent by the kernel.

When tables > 255 are used on a kernel not supporting it an error will
occur because of the unknown netlink attribute.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
include/linux/rtnetlink.h
include/rt_names.h
ip/ip_common.h
ip/iproute.c
ip/iprule.c
lib/rt_names.c

index 5e33a203b52e5a5ae3e112ad45b367314835ebe3..d63578c53850f635dd884f7f571a4d29a0b37873 100644 (file)
@@ -238,9 +238,8 @@ enum rt_class_t
        RT_TABLE_DEFAULT=253,
        RT_TABLE_MAIN=254,
        RT_TABLE_LOCAL=255,
-       __RT_TABLE_MAX
+       RT_TABLE_MAX=0xFFFFFFFF,
 };
-#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
 
 
 
@@ -263,6 +262,7 @@ enum rtattr_type_t
        RTA_CACHEINFO,
        RTA_SESSION,
        RTA_MP_ALGO,
+       RTA_TABLE,
        __RTA_MAX
 };
 
index 2d9ef1019c5cd917ab4a0e145c0eea1602257aa1..07a10e0bcfe2f1b6aeddfc1c24306f5d1987d4ec 100644 (file)
@@ -5,7 +5,7 @@
 
 char* rtnl_rtprot_n2a(int id, char *buf, int len);
 char* rtnl_rtscope_n2a(int id, char *buf, int len);
-char* rtnl_rttable_n2a(int id, char *buf, int len);
+char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
 char* rtnl_rtrealm_n2a(int id, char *buf, int len);
 char* rtnl_dsfield_n2a(int id, char *buf, int len);
 int rtnl_rtprot_a2n(__u32 *id, char *arg);
index 1fe4a691e8d1318922ae8b3d53b4dd2477b21349..8b286b0a4c6e6103f30e17daf70081cb2d44797a 100644 (file)
@@ -32,4 +32,12 @@ extern int do_multiaddr(int argc, char **argv);
 extern int do_multiroute(int argc, char **argv);
 extern int do_xfrm(int argc, char **argv);
 
+static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
+{
+       __u32 table = r->rtm_table;
+       if (tb[RTA_TABLE])
+               table = *(__u32*) RTA_DATA(tb[RTA_TABLE]);
+       return table;
+}
+
 extern struct rtnl_handle rth;
index cb674d7e2bef253a37c535b5479ea46ef7099f7d..24e7a862250b89dad5dd7f16199826e33c6e7c96 100644 (file)
@@ -140,6 +140,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
        inet_prefix via;
        int host_len = -1;
        static int ip6_multiple_tables;
+       __u32 table;
        SPRINT_BUF(b1);
        
 
@@ -165,7 +166,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
        else if (r->rtm_family == AF_IPX)
                host_len = 80;
 
-       if (r->rtm_family == AF_INET6 && r->rtm_table != RT_TABLE_MAIN)
+       parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+       table = rtm_get_table(r, tb);
+
+       if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN)
                ip6_multiple_tables = 1;
 
        if (r->rtm_family == AF_INET6 && !ip6_multiple_tables) {
@@ -187,7 +191,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                        }
                }
        } else {
-               if (filter.tb > 0 && filter.tb != r->rtm_table)
+               if (filter.tb > 0 && filter.tb != table)
                        return 0;
        }
        if ((filter.protocol^r->rtm_protocol)&filter.protocolmask)
@@ -217,8 +221,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
        if (filter.rprefsrc.family && r->rtm_family != filter.rprefsrc.family)
                return 0;
 
-       parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
-
        memset(&dst, 0, sizeof(dst));
        dst.family = r->rtm_family;
        if (tb[RTA_DST])
@@ -371,8 +373,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
 
        if (!(r->rtm_flags&RTM_F_CLONED)) {
-               if (r->rtm_table != RT_TABLE_MAIN && !filter.tb)
-                       fprintf(fp, " table %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+               if (table != RT_TABLE_MAIN && !filter.tb)
+                       fprintf(fp, " table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
                if (r->rtm_protocol != RTPROT_BOOT && filter.protocolmask != -1)
                        fprintf(fp, " proto %s ", rtnl_rtprot_n2a(r->rtm_protocol, b1, sizeof(b1)));
                if (r->rtm_scope != RT_SCOPE_UNIVERSE && filter.scopemask != -1)
@@ -875,7 +877,12 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                        NEXT_ARG();
                        if (rtnl_rttable_a2n(&tid, *argv))
                                invarg("\"table\" value is invalid\n", *argv);
-                       req.r.rtm_table = tid;
+                       if (tid < 256)
+                               req.r.rtm_table = tid;
+                       else {
+                               req.r.rtm_table = RT_TABLE_UNSPEC;
+                               addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+                       }
                        table_ok = 1;
                } else if (strcmp(*argv, "dev") == 0 ||
                           strcmp(*argv, "oif") == 0) {
index ccf699ffeb1c108142bf6ac23d732d72b878f3a6..6caf573cef365e2c0522649502523d0362a998f2 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "rt_names.h"
 #include "utils.h"
+#include "ip_common.h"
 
 extern struct rtnl_handle rth;
 
@@ -51,6 +52,7 @@ static int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
        struct rtmsg *r = NLMSG_DATA(n);
        int len = n->nlmsg_len;
        int host_len = -1;
+       __u32 table;
        struct rtattr * tb[RTA_MAX+1];
        char abuf[256];
        SPRINT_BUF(b1);
@@ -129,8 +131,9 @@ static int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
                fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
        }
 
-       if (r->rtm_table)
-               fprintf(fp, "lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+       table = rtm_get_table(r, tb);
+       if (table)
+               fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
 
        if (tb[RTA_FLOW]) {
                __u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
@@ -257,7 +260,12 @@ static int iprule_modify(int cmd, int argc, char **argv)
                        NEXT_ARG();
                        if (rtnl_rttable_a2n(&tid, *argv))
                                invarg("invalid table ID\n", *argv);
-                       req.r.rtm_table = tid;
+                       if (tid < 256)
+                               req.r.rtm_table = tid;
+                       else {
+                               req.r.rtm_table = RT_TABLE_UNSPEC;
+                               addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+                       }
                        table_ok = 1;
                } else if (strcmp(*argv, "dev") == 0 ||
                           strcmp(*argv, "iif") == 0) {
index 620f3115a2a999bd02bd179e4b0f2296fb37c021..0e5055968752fca065bc53e182c3ceda18b634a6 100644 (file)
@@ -329,7 +329,7 @@ static void rtnl_rttable_initialize(void)
                             rtnl_rttable_hash, 256);
 }
 
-char * rtnl_rttable_n2a(int id, char *buf, int len)
+char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
 {
        struct rtnl_hash_entry *entry;
 
@@ -354,7 +354,7 @@ int rtnl_rttable_a2n(__u32 *id, char *arg)
        static unsigned long res;
        struct rtnl_hash_entry *entry;
        char *end;
-       int i;
+       __u32 i;
 
        if (cache && strcmp(cache, arg) == 0) {
                *id = res;