diff options
author | Patrick McHardy <kaber@trash.net> | 2006-08-11 02:11:17 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:54:27 -0400 |
commit | 1b43af5480c351dbcb2eef478bafe179cbeb6e83 (patch) | |
tree | c69adf005f89c7f5147ad338f1e7243aebc14008 /net/ipv6/route.c | |
parent | 1af5a8c4a11cfed0c9a7f30fcfb689981750599c (diff) |
[IPV6]: Increase number of possible routing tables to 2^32
Increase number of possible routing tables to 2^32 by replacing iterations
over all possible table IDs by hash table walking.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 128 |
1 files changed, 1 insertions, 127 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 843c5509fced..9ce28277f47f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1874,12 +1874,6 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1874 | rtm_get_table(arg, r->rtm_table)); | 1874 | rtm_get_table(arg, r->rtm_table)); |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | struct rt6_rtnl_dump_arg | ||
1878 | { | ||
1879 | struct sk_buff *skb; | ||
1880 | struct netlink_callback *cb; | ||
1881 | }; | ||
1882 | |||
1883 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 1877 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, |
1884 | struct in6_addr *dst, struct in6_addr *src, | 1878 | struct in6_addr *dst, struct in6_addr *src, |
1885 | int iif, int type, u32 pid, u32 seq, | 1879 | int iif, int type, u32 pid, u32 seq, |
@@ -1976,7 +1970,7 @@ rtattr_failure: | |||
1976 | return -1; | 1970 | return -1; |
1977 | } | 1971 | } |
1978 | 1972 | ||
1979 | static int rt6_dump_route(struct rt6_info *rt, void *p_arg) | 1973 | int rt6_dump_route(struct rt6_info *rt, void *p_arg) |
1980 | { | 1974 | { |
1981 | struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg; | 1975 | struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg; |
1982 | int prefix; | 1976 | int prefix; |
@@ -1992,126 +1986,6 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
1992 | prefix, NLM_F_MULTI); | 1986 | prefix, NLM_F_MULTI); |
1993 | } | 1987 | } |
1994 | 1988 | ||
1995 | static int fib6_dump_node(struct fib6_walker_t *w) | ||
1996 | { | ||
1997 | int res; | ||
1998 | struct rt6_info *rt; | ||
1999 | |||
2000 | for (rt = w->leaf; rt; rt = rt->u.next) { | ||
2001 | res = rt6_dump_route(rt, w->args); | ||
2002 | if (res < 0) { | ||
2003 | /* Frame is full, suspend walking */ | ||
2004 | w->leaf = rt; | ||
2005 | return 1; | ||
2006 | } | ||
2007 | BUG_TRAP(res!=0); | ||
2008 | } | ||
2009 | w->leaf = NULL; | ||
2010 | return 0; | ||
2011 | } | ||
2012 | |||
2013 | static void fib6_dump_end(struct netlink_callback *cb) | ||
2014 | { | ||
2015 | struct fib6_walker_t *w = (void*)cb->args[0]; | ||
2016 | |||
2017 | if (w) { | ||
2018 | cb->args[0] = 0; | ||
2019 | kfree(w); | ||
2020 | } | ||
2021 | cb->done = (void*)cb->args[1]; | ||
2022 | cb->args[1] = 0; | ||
2023 | } | ||
2024 | |||
2025 | static int fib6_dump_done(struct netlink_callback *cb) | ||
2026 | { | ||
2027 | fib6_dump_end(cb); | ||
2028 | return cb->done ? cb->done(cb) : 0; | ||
2029 | } | ||
2030 | |||
2031 | int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | ||
2032 | { | ||
2033 | struct fib6_table *table; | ||
2034 | struct rt6_rtnl_dump_arg arg; | ||
2035 | struct fib6_walker_t *w; | ||
2036 | int i, res = 0; | ||
2037 | |||
2038 | arg.skb = skb; | ||
2039 | arg.cb = cb; | ||
2040 | |||
2041 | /* | ||
2042 | * cb->args[0] = pointer to walker structure | ||
2043 | * cb->args[1] = saved cb->done() pointer | ||
2044 | * cb->args[2] = current table being dumped | ||
2045 | */ | ||
2046 | |||
2047 | w = (void*)cb->args[0]; | ||
2048 | if (w == NULL) { | ||
2049 | /* New dump: | ||
2050 | * | ||
2051 | * 1. hook callback destructor. | ||
2052 | */ | ||
2053 | cb->args[1] = (long)cb->done; | ||
2054 | cb->done = fib6_dump_done; | ||
2055 | |||
2056 | /* | ||
2057 | * 2. allocate and initialize walker. | ||
2058 | */ | ||
2059 | w = kzalloc(sizeof(*w), GFP_ATOMIC); | ||
2060 | if (w == NULL) | ||
2061 | return -ENOMEM; | ||
2062 | w->func = fib6_dump_node; | ||
2063 | w->args = &arg; | ||
2064 | cb->args[0] = (long)w; | ||
2065 | cb->args[2] = FIB6_TABLE_MIN; | ||
2066 | } else { | ||
2067 | w->args = &arg; | ||
2068 | i = cb->args[2]; | ||
2069 | if (i > FIB6_TABLE_MAX) | ||
2070 | goto end; | ||
2071 | |||
2072 | table = fib6_get_table(i); | ||
2073 | if (table != NULL) { | ||
2074 | read_lock_bh(&table->tb6_lock); | ||
2075 | w->root = &table->tb6_root; | ||
2076 | res = fib6_walk_continue(w); | ||
2077 | read_unlock_bh(&table->tb6_lock); | ||
2078 | if (res != 0) { | ||
2079 | if (res < 0) | ||
2080 | fib6_walker_unlink(w); | ||
2081 | goto end; | ||
2082 | } | ||
2083 | } | ||
2084 | |||
2085 | fib6_walker_unlink(w); | ||
2086 | cb->args[2] = ++i; | ||
2087 | } | ||
2088 | |||
2089 | for (i = cb->args[2]; i <= FIB6_TABLE_MAX; i++) { | ||
2090 | table = fib6_get_table(i); | ||
2091 | if (table == NULL) | ||
2092 | continue; | ||
2093 | |||
2094 | read_lock_bh(&table->tb6_lock); | ||
2095 | w->root = &table->tb6_root; | ||
2096 | res = fib6_walk(w); | ||
2097 | read_unlock_bh(&table->tb6_lock); | ||
2098 | if (res) | ||
2099 | break; | ||
2100 | } | ||
2101 | end: | ||
2102 | cb->args[2] = i; | ||
2103 | |||
2104 | res = res < 0 ? res : skb->len; | ||
2105 | /* res < 0 is an error. (really, impossible) | ||
2106 | res == 0 means that dump is complete, but skb still can contain data. | ||
2107 | res > 0 dump is not complete, but frame is full. | ||
2108 | */ | ||
2109 | /* Destroy walker, if dump of this table is complete. */ | ||
2110 | if (res <= 0) | ||
2111 | fib6_dump_end(cb); | ||
2112 | return res; | ||
2113 | } | ||
2114 | |||
2115 | int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) | 1989 | int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) |
2116 | { | 1990 | { |
2117 | struct rtattr **rta = arg; | 1991 | struct rtattr **rta = arg; |