From 433d49c3bb14b8a2351fe97df8359e4ad0de4c7c Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 7 Dec 2007 00:43:48 -0800 Subject: [IPV6]: Make ip6_route_init to return an error code. The route initialization function does not return any value to notify if the initialization is successful or not. This patch checks all calls made for the initilization in order to return a value for the caller. Unfortunately, proc_net_fops_create will return a NULL pointer if CONFIG_PROC_FS is off, so we can not check the return code without an ifdef CONFIG_PROC_FS block in the ip6_route_init function. Signed-off-by: Daniel Lezcano Acked-by: Benjamin Thery Signed-off-by: David S. Miller --- net/ipv6/route.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'net') diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 452111fa4c5..d7754abf921 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2468,26 +2468,70 @@ ctl_table ipv6_route_table[] = { #endif -void __init ip6_route_init(void) +int __init ip6_route_init(void) { + int ret; + ip6_dst_ops.kmem_cachep = kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; - fib6_init(); - proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops); - proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); + ret = fib6_init(); + if (ret) + goto out_kmem_cache; + +#ifdef CONFIG_PROC_FS + ret = -ENOMEM; + if (!proc_net_fops_create(&init_net, "ipv6_route", + 0, &ipv6_route_proc_fops)) + goto out_fib6_init; + + if (!proc_net_fops_create(&init_net, "rt6_stats", + S_IRUGO, &rt6_stats_seq_fops)) + goto out_proc_ipv6_route; +#endif + #ifdef CONFIG_XFRM - xfrm6_init(); + ret = xfrm6_init(); + if (ret) + goto out_proc_rt6_stats; #endif #ifdef CONFIG_IPV6_MULTIPLE_TABLES - fib6_rules_init(); + ret = fib6_rules_init(); + if (ret) + goto xfrm6_init; #endif + ret = -ENOBUFS; + if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL) || + __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL) || + __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL)) + goto fib6_rules_init; - __rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL); - __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL); - __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL); + ret = 0; +out: + return ret; + +fib6_rules_init: +#ifdef CONFIG_IPV6_MULTIPLE_TABLES + fib6_rules_cleanup(); +xfrm6_init: +#endif +#ifdef CONFIG_XFRM + xfrm6_fini(); +out_proc_rt6_stats: +#endif +#ifdef CONFIG_PROC_FS + proc_net_remove(&init_net, "rt6_stats"); +out_proc_ipv6_route: + proc_net_remove(&init_net, "ipv6_route"); +out_fib6_init: +#endif + rt6_ifdown(NULL); + fib6_gc_cleanup(); +out_kmem_cache: + kmem_cache_destroy(ip6_dst_ops.kmem_cachep); + goto out; } void ip6_route_cleanup(void) @@ -2495,10 +2539,8 @@ void ip6_route_cleanup(void) #ifdef CONFIG_IPV6_MULTIPLE_TABLES fib6_rules_cleanup(); #endif -#ifdef CONFIG_PROC_FS proc_net_remove(&init_net, "ipv6_route"); proc_net_remove(&init_net, "rt6_stats"); -#endif #ifdef CONFIG_XFRM xfrm6_fini(); #endif -- cgit v1.2.3-18-g5258