aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/xfrm6_tunnel.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2010-02-16 04:05:04 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-16 17:55:25 -0500
commitd5aa407f59f5b83d2c50ec88f5bf56d40f1f8978 (patch)
tree664c30873708f0e361e5250835238043200f4b50 /net/ipv6/xfrm6_tunnel.c
parentc2892f02712e9516d72841d5c019ed6916329794 (diff)
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 <adobriyan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/xfrm6_tunnel.c')
-rw-r--r--net/ipv6/xfrm6_tunnel.c55
1 files changed, 20 insertions, 35 deletions
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index d6f9aeec69f..ddce21e3459 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)
84 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; 84 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
85} 85}
86 86
87
88static int __init xfrm6_tunnel_spi_init(void)
89{
90 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
91 sizeof(struct xfrm6_tunnel_spi),
92 0, SLAB_HWCACHE_ALIGN,
93 NULL);
94 if (!xfrm6_tunnel_spi_kmem)
95 return -ENOMEM;
96 return 0;
97}
98
99static void xfrm6_tunnel_spi_fini(void)
100{
101 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
102}
103
104static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr) 87static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr)
105{ 88{
106 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); 89 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
@@ -375,42 +358,44 @@ static int __init xfrm6_tunnel_init(void)
375{ 358{
376 int rv; 359 int rv;
377 360
361 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
362 sizeof(struct xfrm6_tunnel_spi),
363 0, SLAB_HWCACHE_ALIGN,
364 NULL);
365 if (!xfrm6_tunnel_spi_kmem)
366 return -ENOMEM;
367 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
368 if (rv < 0)
369 goto out_pernet;
378 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6); 370 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
379 if (rv < 0) 371 if (rv < 0)
380 goto err; 372 goto out_type;
381 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6); 373 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
382 if (rv < 0) 374 if (rv < 0)
383 goto unreg; 375 goto out_xfrm6;
384 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET); 376 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
385 if (rv < 0) 377 if (rv < 0)
386 goto dereg6; 378 goto out_xfrm46;
387 rv = xfrm6_tunnel_spi_init();
388 if (rv < 0)
389 goto dereg46;
390 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
391 if (rv < 0)
392 goto deregspi;
393 return 0; 379 return 0;
394 380
395deregspi: 381out_xfrm46:
396 xfrm6_tunnel_spi_fini();
397dereg46:
398 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
399dereg6:
400 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 382 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
401unreg: 383out_xfrm6:
402 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 384 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
403err: 385out_type:
386 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
387out_pernet:
388 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
404 return rv; 389 return rv;
405} 390}
406 391
407static void __exit xfrm6_tunnel_fini(void) 392static void __exit xfrm6_tunnel_fini(void)
408{ 393{
409 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
410 xfrm6_tunnel_spi_fini();
411 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); 394 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
412 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); 395 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
413 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 396 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
397 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
398 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
414} 399}
415 400
416module_init(xfrm6_tunnel_init); 401module_init(xfrm6_tunnel_init);