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