diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-03-04 02:24:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-04 02:24:31 -0500 |
commit | e0b85590bc1b50c9bbef4dd4738d9995fb1d1f64 (patch) | |
tree | da569f756220e9917629a6eb80be82a80d344c8b | |
parent | 419271780712091ff2738aee513fa4b5b051fbdc (diff) |
[NETNS][IPV6] ip6_fib - dynamically allocate the fib tables
This patch changes the fib6 tables to be dynamically allocated. That
provides the ability to make several instances of them when a new
network namespace is created.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/ip6_fib.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index c70fd38b54b7..04d774963f3c 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -166,20 +166,14 @@ static __inline__ void rt6_release(struct rt6_info *rt) | |||
166 | dst_free(&rt->u.dst); | 166 | dst_free(&rt->u.dst); |
167 | } | 167 | } |
168 | 168 | ||
169 | static struct fib6_table fib6_main_tbl = { | 169 | static struct fib6_table *fib6_main_tbl; |
170 | .tb6_id = RT6_TABLE_MAIN, | ||
171 | .tb6_root = { | ||
172 | .leaf = &ip6_null_entry, | ||
173 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | ||
174 | }, | ||
175 | }; | ||
176 | 170 | ||
177 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 171 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
178 | #define FIB_TABLE_HASHSZ 256 | 172 | #define FIB_TABLE_HASHSZ 256 |
179 | #else | 173 | #else |
180 | #define FIB_TABLE_HASHSZ 1 | 174 | #define FIB_TABLE_HASHSZ 1 |
181 | #endif | 175 | #endif |
182 | static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; | 176 | static struct hlist_head *fib_table_hash; |
183 | 177 | ||
184 | static void fib6_link_table(struct fib6_table *tb) | 178 | static void fib6_link_table(struct fib6_table *tb) |
185 | { | 179 | { |
@@ -201,13 +195,8 @@ static void fib6_link_table(struct fib6_table *tb) | |||
201 | } | 195 | } |
202 | 196 | ||
203 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 197 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
204 | static struct fib6_table fib6_local_tbl = { | 198 | |
205 | .tb6_id = RT6_TABLE_LOCAL, | 199 | static struct fib6_table *fib6_local_tbl; |
206 | .tb6_root = { | ||
207 | .leaf = &ip6_null_entry, | ||
208 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | ||
209 | }, | ||
210 | }; | ||
211 | 200 | ||
212 | static struct fib6_table *fib6_alloc_table(u32 id) | 201 | static struct fib6_table *fib6_alloc_table(u32 id) |
213 | { | 202 | { |
@@ -263,8 +252,8 @@ struct fib6_table *fib6_get_table(u32 id) | |||
263 | 252 | ||
264 | static void __init fib6_tables_init(void) | 253 | static void __init fib6_tables_init(void) |
265 | { | 254 | { |
266 | fib6_link_table(&fib6_main_tbl); | 255 | fib6_link_table(fib6_main_tbl); |
267 | fib6_link_table(&fib6_local_tbl); | 256 | fib6_link_table(fib6_local_tbl); |
268 | } | 257 | } |
269 | 258 | ||
270 | #else | 259 | #else |
@@ -276,18 +265,18 @@ struct fib6_table *fib6_new_table(u32 id) | |||
276 | 265 | ||
277 | struct fib6_table *fib6_get_table(u32 id) | 266 | struct fib6_table *fib6_get_table(u32 id) |
278 | { | 267 | { |
279 | return &fib6_main_tbl; | 268 | return fib6_main_tbl; |
280 | } | 269 | } |
281 | 270 | ||
282 | struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, | 271 | struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, |
283 | pol_lookup_t lookup) | 272 | pol_lookup_t lookup) |
284 | { | 273 | { |
285 | return (struct dst_entry *) lookup(&fib6_main_tbl, fl, flags); | 274 | return (struct dst_entry *) lookup(fib6_main_tbl, fl, flags); |
286 | } | 275 | } |
287 | 276 | ||
288 | static void __init fib6_tables_init(void) | 277 | static void __init fib6_tables_init(void) |
289 | { | 278 | { |
290 | fib6_link_table(&fib6_main_tbl); | 279 | fib6_link_table(fib6_main_tbl); |
291 | } | 280 | } |
292 | 281 | ||
293 | #endif | 282 | #endif |
@@ -1479,22 +1468,53 @@ void fib6_run_gc(unsigned long dummy) | |||
1479 | 1468 | ||
1480 | int __init fib6_init(void) | 1469 | int __init fib6_init(void) |
1481 | { | 1470 | { |
1482 | int ret; | 1471 | int ret = -ENOMEM; |
1483 | fib6_node_kmem = kmem_cache_create("fib6_nodes", | 1472 | fib6_node_kmem = kmem_cache_create("fib6_nodes", |
1484 | sizeof(struct fib6_node), | 1473 | sizeof(struct fib6_node), |
1485 | 0, SLAB_HWCACHE_ALIGN, | 1474 | 0, SLAB_HWCACHE_ALIGN, |
1486 | NULL); | 1475 | NULL); |
1487 | if (!fib6_node_kmem) | 1476 | if (!fib6_node_kmem) |
1488 | return -ENOMEM; | 1477 | goto out; |
1478 | |||
1479 | fib_table_hash = kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, | ||
1480 | GFP_KERNEL); | ||
1481 | if (!fib_table_hash) | ||
1482 | goto out_kmem_cache_create; | ||
1483 | |||
1484 | fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL); | ||
1485 | if (!fib6_main_tbl) | ||
1486 | goto out_fib_table_hash; | ||
1487 | |||
1488 | fib6_main_tbl->tb6_id = RT6_TABLE_MAIN; | ||
1489 | fib6_main_tbl->tb6_root.leaf = &ip6_null_entry; | ||
1490 | fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; | ||
1491 | |||
1492 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
1493 | fib6_local_tbl = kzalloc(sizeof(*fib6_local_tbl), GFP_KERNEL); | ||
1494 | if (!fib6_local_tbl) | ||
1495 | goto out_fib6_main_tbl; | ||
1496 | |||
1497 | fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; | ||
1498 | fib6_local_tbl->tb6_root.leaf = &ip6_null_entry; | ||
1499 | fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; | ||
1500 | #endif | ||
1489 | 1501 | ||
1490 | fib6_tables_init(); | 1502 | fib6_tables_init(); |
1491 | 1503 | ||
1492 | ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib); | 1504 | ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib); |
1493 | if (ret) | 1505 | if (ret) |
1494 | goto out_kmem_cache_create; | 1506 | goto out_fib6_local_tbl; |
1495 | out: | 1507 | out: |
1496 | return ret; | 1508 | return ret; |
1497 | 1509 | ||
1510 | out_fib6_local_tbl: | ||
1511 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
1512 | kfree(fib6_local_tbl); | ||
1513 | out_fib6_main_tbl: | ||
1514 | #endif | ||
1515 | kfree(fib6_main_tbl); | ||
1516 | out_fib_table_hash: | ||
1517 | kfree(fib_table_hash); | ||
1498 | out_kmem_cache_create: | 1518 | out_kmem_cache_create: |
1499 | kmem_cache_destroy(fib6_node_kmem); | 1519 | kmem_cache_destroy(fib6_node_kmem); |
1500 | goto out; | 1520 | goto out; |
@@ -1503,5 +1523,10 @@ out_kmem_cache_create: | |||
1503 | void fib6_gc_cleanup(void) | 1523 | void fib6_gc_cleanup(void) |
1504 | { | 1524 | { |
1505 | del_timer(&ip6_fib_timer); | 1525 | del_timer(&ip6_fib_timer); |
1526 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
1527 | kfree(fib6_local_tbl); | ||
1528 | #endif | ||
1529 | kfree(fib6_main_tbl); | ||
1530 | kfree(fib_table_hash); | ||
1506 | kmem_cache_destroy(fib6_node_kmem); | 1531 | kmem_cache_destroy(fib6_node_kmem); |
1507 | } | 1532 | } |