Skip to content

Commit

Permalink
[IPV6]: Make ip6_route_init to return an error code.
Browse files Browse the repository at this point in the history
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 <dlezcano@fr.ibm.com>
Acked-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Daniel Lezcano authored and David S. Miller committed Jan 28, 2008
1 parent 9eb87f3 commit 433d49c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 12 deletions.
2 changes: 1 addition & 1 deletion include/net/ip6_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
64 changes: 53 additions & 11 deletions net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2468,37 +2468,79 @@ 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)
{
#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
Expand Down

0 comments on commit 433d49c

Please sign in to comment.