From d5aa407f59f5b83d2c50ec88f5bf56d40f1f8978 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 16 Feb 2010 09:05:04 +0000 Subject: tunnels: fix netns vs proto registration ordering Same stuff as in ip_gre patch: receive hook can be called before netns setup is done, oopsing in net_generic(). Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- net/ipv6/xfrm6_tunnel.c | 55 ++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) (limited to 'net/ipv6/xfrm6_tunnel.c') diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index d6f9aee..ddce21e 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -84,23 +84,6 @@ static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi) return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; } - -static int __init xfrm6_tunnel_spi_init(void) -{ - xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi", - sizeof(struct xfrm6_tunnel_spi), - 0, SLAB_HWCACHE_ALIGN, - NULL); - if (!xfrm6_tunnel_spi_kmem) - return -ENOMEM; - return 0; -} - -static void xfrm6_tunnel_spi_fini(void) -{ - kmem_cache_destroy(xfrm6_tunnel_spi_kmem); -} - static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr) { struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); @@ -375,42 +358,44 @@ static int __init xfrm6_tunnel_init(void) { int rv; + xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi", + sizeof(struct xfrm6_tunnel_spi), + 0, SLAB_HWCACHE_ALIGN, + NULL); + if (!xfrm6_tunnel_spi_kmem) + return -ENOMEM; + rv = register_pernet_subsys(&xfrm6_tunnel_net_ops); + if (rv < 0) + goto out_pernet; rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6); if (rv < 0) - goto err; + goto out_type; rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6); if (rv < 0) - goto unreg; + goto out_xfrm6; rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET); if (rv < 0) - goto dereg6; - rv = xfrm6_tunnel_spi_init(); - if (rv < 0) - goto dereg46; - rv = register_pernet_subsys(&xfrm6_tunnel_net_ops); - if (rv < 0) - goto deregspi; + goto out_xfrm46; return 0; -deregspi: - xfrm6_tunnel_spi_fini(); -dereg46: - xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); -dereg6: +out_xfrm46: xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); -unreg: +out_xfrm6: xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); -err: +out_type: + unregister_pernet_subsys(&xfrm6_tunnel_net_ops); +out_pernet: + kmem_cache_destroy(xfrm6_tunnel_spi_kmem); return rv; } static void __exit xfrm6_tunnel_fini(void) { - unregister_pernet_subsys(&xfrm6_tunnel_net_ops); - xfrm6_tunnel_spi_fini(); xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); + unregister_pernet_subsys(&xfrm6_tunnel_net_ops); + kmem_cache_destroy(xfrm6_tunnel_spi_kmem); } module_init(xfrm6_tunnel_init); -- cgit v1.1