Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=433d49c3bb14b8a2351fe97df8359e4ad0de4c7c
Commit:     433d49c3bb14b8a2351fe97df8359e4ad0de4c7c
Parent:     9eb87f3f7e0686a256c5bb4f886dede0171245f2
Author:     Daniel Lezcano <[EMAIL PROTECTED]>
AuthorDate: Fri Dec 7 00:43:48 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 14:56:47 2008 -0800

    [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 <[EMAIL PROTECTED]>
    Acked-by: Benjamin Thery <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 include/net/ip6_route.h |    2 +-
 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 5456fdd..1a0698b 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);
 extern struct dst_entry *      ip6_route_output(struct sock *sk,
                                                 struct flowi *fl);
 
-extern void                    ip6_route_init(void);
+extern int                     ip6_route_init(void);
 extern void                    ip6_route_cleanup(void);
 
 extern int                     ipv6_route_ioctl(unsigned int cmd, void __user 
*arg);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 452111f..d7754ab 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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to