diff options
| -rw-r--r-- | include/net/ip6_route.h | 2 | ||||
| -rw-r--r-- | net/ipv6/route.c | 64 |
2 files changed, 54 insertions, 12 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 5456fdd6d047..1a0698b1e86c 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
| @@ -50,7 +50,7 @@ extern void ip6_route_input(struct sk_buff *skb); | |||
| 50 | extern struct dst_entry * ip6_route_output(struct sock *sk, | 50 | extern struct dst_entry * ip6_route_output(struct sock *sk, |
| 51 | struct flowi *fl); | 51 | struct flowi *fl); |
| 52 | 52 | ||
| 53 | extern void ip6_route_init(void); | 53 | extern int ip6_route_init(void); |
| 54 | extern void ip6_route_cleanup(void); | 54 | extern void ip6_route_cleanup(void); |
| 55 | 55 | ||
| 56 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); | 56 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 452111fa4c52..d7754abf9216 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2468,26 +2468,70 @@ ctl_table ipv6_route_table[] = { | |||
| 2468 | 2468 | ||
| 2469 | #endif | 2469 | #endif |
| 2470 | 2470 | ||
| 2471 | void __init ip6_route_init(void) | 2471 | int __init ip6_route_init(void) |
| 2472 | { | 2472 | { |
| 2473 | int ret; | ||
| 2474 | |||
| 2473 | ip6_dst_ops.kmem_cachep = | 2475 | ip6_dst_ops.kmem_cachep = |
| 2474 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, | 2476 | kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, |
| 2475 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 2477 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
| 2476 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; | 2478 | ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; |
| 2477 | 2479 | ||
| 2478 | fib6_init(); | 2480 | ret = fib6_init(); |
| 2479 | proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops); | 2481 | if (ret) |
| 2480 | proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); | 2482 | goto out_kmem_cache; |
| 2483 | |||
| 2484 | #ifdef CONFIG_PROC_FS | ||
| 2485 | ret = -ENOMEM; | ||
| 2486 | if (!proc_net_fops_create(&init_net, "ipv6_route", | ||
| 2487 | 0, &ipv6_route_proc_fops)) | ||
| 2488 | goto out_fib6_init; | ||
| 2489 | |||
| 2490 | if (!proc_net_fops_create(&init_net, "rt6_stats", | ||
| 2491 | S_IRUGO, &rt6_stats_seq_fops)) | ||
| 2492 | goto out_proc_ipv6_route; | ||
| 2493 | #endif | ||
| 2494 | |||
| 2481 | #ifdef CONFIG_XFRM | 2495 | #ifdef CONFIG_XFRM |
| 2482 | xfrm6_init(); | 2496 | ret = xfrm6_init(); |
| 2497 | if (ret) | ||
| 2498 | goto out_proc_rt6_stats; | ||
| 2483 | #endif | 2499 | #endif |
| 2484 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 2500 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 2485 | fib6_rules_init(); | 2501 | ret = fib6_rules_init(); |
| 2502 | if (ret) | ||
| 2503 | goto xfrm6_init; | ||
| 2486 | #endif | 2504 | #endif |
| 2505 | ret = -ENOBUFS; | ||
| 2506 | if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL) || | ||
| 2507 | __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL) || | ||
| 2508 | __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL)) | ||
| 2509 | goto fib6_rules_init; | ||
| 2487 | 2510 | ||
| 2488 | __rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL); | 2511 | ret = 0; |
| 2489 | __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL); | 2512 | out: |
| 2490 | __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL); | 2513 | return ret; |
| 2514 | |||
| 2515 | fib6_rules_init: | ||
| 2516 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 2517 | fib6_rules_cleanup(); | ||
| 2518 | xfrm6_init: | ||
| 2519 | #endif | ||
| 2520 | #ifdef CONFIG_XFRM | ||
| 2521 | xfrm6_fini(); | ||
| 2522 | out_proc_rt6_stats: | ||
| 2523 | #endif | ||
| 2524 | #ifdef CONFIG_PROC_FS | ||
| 2525 | proc_net_remove(&init_net, "rt6_stats"); | ||
| 2526 | out_proc_ipv6_route: | ||
| 2527 | proc_net_remove(&init_net, "ipv6_route"); | ||
| 2528 | out_fib6_init: | ||
| 2529 | #endif | ||
| 2530 | rt6_ifdown(NULL); | ||
| 2531 | fib6_gc_cleanup(); | ||
| 2532 | out_kmem_cache: | ||
| 2533 | kmem_cache_destroy(ip6_dst_ops.kmem_cachep); | ||
| 2534 | goto out; | ||
| 2491 | } | 2535 | } |
| 2492 | 2536 | ||
| 2493 | void ip6_route_cleanup(void) | 2537 | void ip6_route_cleanup(void) |
| @@ -2495,10 +2539,8 @@ void ip6_route_cleanup(void) | |||
| 2495 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 2539 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 2496 | fib6_rules_cleanup(); | 2540 | fib6_rules_cleanup(); |
| 2497 | #endif | 2541 | #endif |
| 2498 | #ifdef CONFIG_PROC_FS | ||
| 2499 | proc_net_remove(&init_net, "ipv6_route"); | 2542 | proc_net_remove(&init_net, "ipv6_route"); |
| 2500 | proc_net_remove(&init_net, "rt6_stats"); | 2543 | proc_net_remove(&init_net, "rt6_stats"); |
| 2501 | #endif | ||
| 2502 | #ifdef CONFIG_XFRM | 2544 | #ifdef CONFIG_XFRM |
| 2503 | xfrm6_fini(); | 2545 | xfrm6_fini(); |
| 2504 | #endif | 2546 | #endif |
