IPv6 can be modular and panicking on module loading is the last thing
you want.
Two SLAB_PANIC cases converted to error propagating as well as one
panic() call.
Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]>
---
I recall release is near, so error handling continues to suck. It needs
big revamp anyway. init functions returning void. functions simply dropping
-E... Partly shared with IPv4 :-(
One more question: how can one unload ipv6? it seems to immediately get
8 users here no matter what.
include/net/ip6_fib.h | 2 +-
include/net/ip6_route.h | 2 +-
include/net/transp_v6.h | 2 +-
net/ipv6/af_inet6.c | 6 +++++-
net/ipv6/ip6_fib.c | 8 +++++---
net/ipv6/route.c | 14 +++++++++++---
net/ipv6/tcp_ipv6.c | 19 ++++++++++++++-----
7 files changed, 38 insertions(+), 15 deletions(-)
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -210,7 +210,7 @@ extern void fib6_run_gc(unsigned long
extern void fib6_gc_cleanup(void);
-extern void fib6_init(void);
+extern int fib6_init(void);
extern void fib6_rules_init(void);
extern void fib6_rules_cleanup(void);
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -59,7 +59,7 @@ extern struct dst_entry * ip6_route_outp
extern int ip6_route_me_harder(struct sk_buff *skb);
-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);
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -24,7 +24,7 @@ extern void ipv6_destopt_init(void);
/* transport protocols */
extern void rawv6_init(void);
extern void udpv6_init(void);
-extern void tcpv6_init(void);
+extern int tcpv6_init(void);
extern int udpv6_connect(struct sock *sk,
struct sockaddr *uaddr,
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -863,13 +863,17 @@ #endif
/* Init v6 transport protocols. */
udpv6_init();
- tcpv6_init();
+ err = tcpv6_init();
+ if (err)
+ goto tcpv6_init_fail;
ipv6_packet_init();
err = 0;
out:
return err;
+tcpv6_init_fail:
+ addrconf_cleanup();
addrconf_fail:
ip6_flowlabel_cleanup();
ip6_route_cleanup();
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1468,14 +1468,16 @@ void fib6_run_gc(unsigned long dummy)
spin_unlock_bh(&fib6_gc_lock);
}
-void __init fib6_init(void)
+int __init fib6_init(void)
{
fib6_node_kmem = kmem_cache_create("fib6_nodes",
sizeof(struct fib6_node),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
+ 0, SLAB_HWCACHE_ALIGN,
NULL, NULL);
-
+ if (!fib6_node_kmem)
+ return -ENOMEM;
fib6_tables_init();
+ return 0;
}
void fib6_gc_cleanup(void)
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2411,14 +2411,21 @@ ctl_table ipv6_route_table[] = {
#endif
-void __init ip6_route_init(void)
+int __init ip6_route_init(void)
{
struct proc_dir_entry *p;
+ int rv;
ip6_dst_ops.kmem_cachep =
kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
- fib6_init();
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!ip6_dst_ops.kmem_cachep)
+ return -ENOMEM;
+ rv = fib6_init();
+ if (rv < 0) {
+ kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
+ return rv;
+ }
#ifdef CONFIG_PROC_FS
p = proc_net_create("ipv6_route", 0, rt6_proc_info);
if (p)
@@ -2432,6 +2439,7 @@ #endif
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
fib6_rules_init();
#endif
+ return 0;
}
void ip6_route_cleanup(void)
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1644,14 +1644,23 @@ static struct inet_protosw tcpv6_protosw
INET_PROTOSW_ICSK,
};
-void __init tcpv6_init(void)
+int __init tcpv6_init(void)
{
+ int rv;
+
/* register inet6 protocol */
- if (inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP) < 0)
+ rv = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP);
+ if (rv < 0) {
printk(KERN_ERR "tcpv6_init: Could not register protocol\n");
+ return rv;
+ }
inet6_register_protosw(&tcpv6_protosw);
- if (inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW,
- IPPROTO_TCP) < 0)
- panic("Failed to create the TCPv6 control socket.\n");
+ rv = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW,
+ IPPROTO_TCP);
+ if (rv < 0) {
+ inet6_unregister_protosw(&tcpv6_protosw);
+ inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
+ }
+ return rv;
}
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html