: Increase number of possible routing tables
Subsystems (3)
cover : Increase number of possible routing tables
These patches add support for a larger number of routing tables to iproute and are needed for the patches doing the same for the kernel I just sent. They apply on top of the "[IPROUTE]: Support IPv6 routing table filter" patch.
Please apply, thanks.
include/linux/rtnetlink.h | 4 - include/rt_names.h | 2 ip/ip_common.h | 8 +++ ip/iproute.c | 63 ++++++++++++++++------------ ip/iprule.c | 14 +++++- lib/rt_names.c | 100 ++++++++++++++++++++++++++++++++++------------ 6 files changed, 133 insertions(+), 58 deletions(-)
Patrick McHardy:
[IPROUTE]: Preparation for 32 bit table IDs [IPROUTE]: Use hash for routing table name cache [IPROUTE]: Add support for larger number of routing tables
PATCH 1/3 : Preparation for 32 bit table IDs
[IPROUTE]: Preparation for 32 bit table IDs
The route table filter uses an integer for the table number and the value -1 to represent cloned routes. For 32 bit table IDs it needs to become an unsigned, so this won't work anymore. Introduce a new filter flag "cloned" and use instead of filter.tb = -1.
---
commit 00d896184c5f8737269ac05264446c58133ec414
tree 3eb3760b7b5b8b5811cadeaaec1b949533fb5ffd
parent 14d210c56edd67973439acd67d916de84a6e0384
author Patrick McHardy <[email protected]> Thu, 10 Aug 2006 23:19:31 +0200 committer Patrick McHardy <[email protected]> Thu, 10 Aug 2006 23:19:31 +0200
ip/iproute.c | 42 +++++++++++++++++++++--------------------- 1 files changed, 21 insertions(+), 21 deletions(-)
ip/iproute.c +21 -21
@@ -89,6 +89,7 @@ static void usage(void) static struct { int tb; + int cloned; int flushed; char *flushb; int flushp;
@@ -168,22 +169,21 @@ int print_route(const struct sockaddr_nl ip6_multiple_tables =1 ;if (r->rtm_family ==AF_INET6 && !ip6_multiple_tables) { +if (filter.cloned) { +if (!(r->rtm_flags&RTM_F_CLONED )) +return 0 ; + }if (filter.tb) { -if (filter.tb <0 ) { -if (!(r->rtm_flags&RTM_F_CLONED )) -return 0 ; - }else { -if (r->rtm_flags&RTM_F_CLONED ) +if (r->rtm_flags&RTM_F_CLONED ) +return 0 ; +if (filter.tb ==RT_TABLE_LOCAL ) { +if (r->rtm_type !=RTN_LOCAL )return 0 ; -if (filter.tb ==RT_TABLE_LOCAL ) { -if (r->rtm_type !=RTN_LOCAL ) -return 0 ; - }else if (filter.tb ==RT_TABLE_MAIN ) { -if (r->rtm_type ==RTN_LOCAL ) -return 0 ; - }else { + }else if (filter.tb ==RT_TABLE_MAIN ) { +if (r->rtm_type ==RTN_LOCAL )return 0 ; - } + }else { +return 0 ; } } }else {
@@ -1045,19 +1045,19 @@ static int iproute_list_or_flush(int argNEXT_ARG ();if (rtnl_rttable_a2n (&tid, *argv)) {if (strcmp (*argv,"all" ) ==0 ) { - tid =0 ; + filter.tb =0 ; }else if (strcmp (*argv,"cache" ) ==0 ) { - tid =-1 ; + filter.cloned =1 ; }else if (strcmp (*argv,"help" ) ==0 ) {usage (); }else {invarg ("table id value is invalid\n" , *argv); } - } - filter.tb = tid; + }else + filter.tb = tid; }else if (matches (*argv,"cached" ) ==0 ||matches (*argv,"cloned" ) ==0 ) { - filter.tb =-1 ; + filter.cloned =1 ; }else if (strcmp (*argv,"tos" ) ==0 ||matches (*argv,"dsfield" ) ==0 ) {__u32 tos;
@@ -1189,7 +1189,7 @@ static int iproute_list_or_flush(int argchar flushb[4096 -512 ];time_t start =time (0 ); -if (filter.tb ==-1 ) { +if (filter.cloned) {if (do_ipv6 !=AF_INET6 ) {iproute_flush_cache ();if (show_stats)
@@ -1215,7 +1215,7 @@ static int iproute_list_or_flush(int arg }if (filter.flushed ==0 ) {if (round ==0 ) { -if (filter.tb !=-1 || do_ipv6 ==AF_INET6 ) +if (!filter.cloned || do_ipv6 ==AF_INET6 )fprintf (stderr,"Nothing to flush.\n" ); }else if (show_stats)printf ("*** Flush is complete after %d round%s ***\n" , round, round>1 ?"s" :"" );
@@ -1239,7 +1239,7 @@ static int iproute_list_or_flush(int arg } } -if (filter.tb !=-1 ) { +if (!filter.cloned) {if (rtnl_wilddump_request (&rth, do_ipv6,RTM_GETROUTE ) <0 ) {perror ("Cannot send dump request" );exit (1 );
PATCH 2/3 : Use hash for routing table name cache
In reply to Patrick McHardy[IPROUTE]: Use hash for routing table name cache
Use a hash for routing table name cache instead of the fixed size array.
---
commit ccd621fbb5faa91a98479e9492baee525c6f10c0
tree e4e1416406b5ed252b3b1a91efc3d8caadbf1bd0
parent 00d896184c5f8737269ac05264446c58133ec414
author Patrick McHardy <[email protected]> Thu, 10 Aug 2006 23:27:59 +0200 committer Patrick McHardy <[email protected]> Thu, 10 Aug 2006 23:27:59 +0200
lib/rt_names.c | 96 +++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 74 insertions(+), 22 deletions(-)
lib/rt_names.c +74 -22
@@ -23,6 +23,51 @@ #include <linux/rtnetlink.h>#include "rt_names.h" +struct rtnl_hash_entry { +struct rtnl_hash_entry *next; +char * name; +unsigned int id; +}; + +static void +rtnl_hash_initialize (char *file,struct rtnl_hash_entry **hash,int size) +{ +struct rtnl_hash_entry *entry; +char buf[512 ]; +FILE *fp; + + fp =fopen (file,"r" ); +if (!fp) +return ; +while (fgets (buf,sizeof (buf), fp)) { +char *p = buf; +int id; +char namebuf[512 ]; + +while (*p ==' ' || *p =='\t' ) + p++; +if (*p =='#' || *p =='\n' || *p ==0 ) +continue ; +if (sscanf (p,"0x%x %s\n" , &id, namebuf) !=2 && +sscanf (p,"0x%x %s #" , &id, namebuf) !=2 && +sscanf (p,"%d %s\n" , &id, namebuf) !=2 && +sscanf (p,"%d %s #" , &id, namebuf) !=2 ) { +fprintf (stderr,"Database %s is corrupted at %s\n" , + file, p); +return ; + } + +if (id<0 ) +continue ; + entry =malloc (sizeof (*entry)); + entry->id = id; + entry->name =strdup (namebuf); + entry->next = hash[id & (size -1 )]; + hash[id & (size -1 )] = entry; + } +fclose (fp); +} +static void rtnl_tab_initialize (char *file,char **tab,int size) {char buf[512 ];
@@ -57,7 +102,6 @@ static void rtnl_tab_initialize(char *fifclose (fp); } -static char * rtnl_rtprot_tab[256 ] = { [RTPROT_UNSPEC ] ="none" , [RTPROT_REDIRECT ] ="redirect" ,
@@ -266,9 +310,14 @@ int rtnl_rtrealm_a2n(__u32 *id, char *ar } +static struct rtnl_hash_entry dflt_table_entry = { .id =253 , .name ="default" }; +static struct rtnl_hash_entry main_table_entry = { .id =254 , .name ="main" }; +static struct rtnl_hash_entry local_table_entry = { .id =255 , .name ="local" }; -static char * rtnl_rttable_tab[256 ] = { -"unspec" , +static struct rtnl_hash_entry * rtnl_rttable_hash[256 ] = { + [253 ] = &dflt_table_entry, + [254 ] = &main_table_entry, + [255 ] = &local_table_entry, };static int rtnl_rttable_init;
@@ -276,26 +325,26 @@ static int rtnl_rttable_init;static void rtnl_rttable_initialize (void ) { rtnl_rttable_init =1 ; - rtnl_rttable_tab[255 ] ="local" ; - rtnl_rttable_tab[254 ] ="main" ; - rtnl_rttable_tab[253 ] ="default" ; -rtnl_tab_initialize ("/etc/iproute2/rt_tables" , - rtnl_rttable_tab,256 ); +rtnl_hash_initialize ("/etc/iproute2/rt_tables" , + rtnl_rttable_hash,256 ); }char *rtnl_rttable_n2a (int id,char *buf,int len) { -if (id<0 || id>=256 ) { -snprintf (buf, len,"%d" , id); +struct rtnl_hash_entry *entry; + +if (id >=RT_TABLE_MAX ) { +snprintf (buf, len,"%u" , id);return buf; } -if (!rtnl_rttable_tab[id]) { -if (!rtnl_rttable_init) -rtnl_rttable_initialize (); - } -if (rtnl_rttable_tab[id]) -return rtnl_rttable_tab[id]; -snprintf (buf, len,"%d" , id); +if (!rtnl_rttable_init) +rtnl_rttable_initialize (); + entry = rtnl_rttable_hash[id &255 ]; +while (entry && entry->id != id) + entry = entry->next; +if (entry) +return entry->name; +snprintf (buf, len,"%u" , id);return buf; }
@@ -303,6 +352,7 @@ int rtnl_rttable_a2n(__u32 *id, char *ar {static char *cache =NULL ;static unsigned long res; +struct rtnl_hash_entry *entry;char *end;int i;
@@ -315,17 +365,19 @@ int rtnl_rttable_a2n(__u32 *id, char *arrtnl_rttable_initialize ();for (i=0 ; i<256 ; i++) { -if (rtnl_rttable_tab[i] && -strcmp (rtnl_rttable_tab[i], arg) ==0 ) { - cache = rtnl_rttable_tab[i]; - res = i; + entry = rtnl_rttable_hash[i]; +while (entry &&strcmp (entry->name, arg)) + entry = entry->next; +if (entry) { + cache = entry->name; + res = entry->id; *id = res;return 0 ; } } i =strtoul (arg, &end,0 ); -if (!end || end == arg || *end || i >255 ) +if (!end || end == arg || *end || i >RT_TABLE_MAX )return -1 ; *id = i;return 0 ;
PATCH 3/3 : Add support for larger number of routing tables
In reply to Patrick McHardy[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.
---
commit 7980d6ceea890359173344e71c1139b252fd9894
tree 19a33af25df28c002569e85b34a8c90ca517d875
parent ccd621fbb5faa91a98479e9492baee525c6f10c0
author Patrick McHardy <[email protected]> Fri, 11 Aug 2006 00:03:32 +0200 committer Patrick McHardy <[email protected]> Fri, 11 Aug 2006 00:03:32 +0200
include/linux/rtnetlink.h | 4 ++-- include/rt_names.h | 2 +- ip/ip_common.h | 8 ++++++++ ip/iproute.c | 21 ++++++++++++++------- ip/iprule.c | 14 +++++++++++--- lib/rt_names.c | 4 ++-- 6 files changed, 38 insertions(+), 15 deletions(-)
include/linux/rtnetlink.h +2 -2
@@ -238,9 +238,8 @@ enum rt_class_tRT_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_tRTA_CACHEINFO ,RTA_SESSION ,RTA_MP_ALGO , +RTA_TABLE , __RTA_MAX };
include/rt_names.h +1 -1
@@ -5,7 +5,7 @@ #include <asm/types.h>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);
ip/ip_common.h +8 -0
@@ -32,4 +32,12 @@ extern int do_multiaddr(int argc, char *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;
ip/iproute.c +14 -7
@@ -140,6 +140,7 @@ int print_route(const struct sockaddr_nlinet_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_nlelse 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 } } }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_nlif (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_nlfprintf (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 @@ #endifNEXT_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 ) {
ip/iprule.c +11 -3
@@ -27,6 +27,7 @@ #include <string.h>#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 sockastruct 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 sockafprintf (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 arNEXT_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 ) {
lib/rt_names.c +2 -2
@@ -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 *arstatic unsigned long res;struct rtnl_hash_entry *entry;char *end; -int i; +__u32 i;if (cache &&strcmp (cache, arg) ==0 ) { *id = res;
Quoted 15 lines · On Fri, 11 Aug 2006 00:14:47 +0200 (MEST) Patrick McHardy <[email protected]>…
These patches add support for a larger number of routing tables to iproute and are needed for the patches doing the same for the kernel I just sent. They apply on top of the "[IPROUTE]: Support IPv6 routing table filter" patch.
Please apply, thanks.
include/linux/rtnetlink.h | 4 - include/rt_names.h | 2 ip/ip_common.h | 8 +++ ip/iproute.c | 63 ++++++++++++++++------------ ip/iprule.c | 14 +++++- lib/rt_names.c | 100 ++++++++++++++++++++++++++++++++++------------ 6 files changed, 133 insertions(+), 58 deletions(-)
Quoted 4 lines
Patrick McHardy:
[IPROUTE]: Preparation for 32 bit table IDs [IPROUTE]: Use hash for routing table name cache [IPROUTE]: Add support for larger number of routing tables
Applied thanks. Let me know when your done, it has been too long since a real release of iproute2. I'll roll one as soon as the flow subsides.
Quoted 2 lines · Stephen Hemminger
Applied thanks. Let me know when your done, it has been too long since a real release of iproute2. I'll roll one as soon as the flow subsides.
I only have one more patchset I would like to submit soon, the time cleanups. But they are only meant to make auditing for integer overflows easier, so we can one day switch to a higher clock resolution. iproute seems to be mostly fine, but the kernel will probably take a bit longer, so I wouldn't mind missing this release. I'll submit them in the next days anyway, but feel free to release without them.