diff options
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 61517fe0c57c..2365eb0fb6a4 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <net/xfrm.h> | 52 | #include <net/xfrm.h> |
53 | #include <net/dsfield.h> | 53 | #include <net/dsfield.h> |
54 | #include <net/inet_ecn.h> | 54 | #include <net/inet_ecn.h> |
55 | #include <net/net_namespace.h> | ||
56 | #include <net/netns/generic.h> | ||
55 | 57 | ||
56 | MODULE_AUTHOR("Ville Nuorvala"); | 58 | MODULE_AUTHOR("Ville Nuorvala"); |
57 | MODULE_DESCRIPTION("IPv6 tunneling device"); | 59 | MODULE_DESCRIPTION("IPv6 tunneling device"); |
@@ -78,6 +80,10 @@ static int ip6_fb_tnl_dev_init(struct net_device *dev); | |||
78 | static int ip6_tnl_dev_init(struct net_device *dev); | 80 | static int ip6_tnl_dev_init(struct net_device *dev); |
79 | static void ip6_tnl_dev_setup(struct net_device *dev); | 81 | static void ip6_tnl_dev_setup(struct net_device *dev); |
80 | 82 | ||
83 | static int ip6_tnl_net_id; | ||
84 | struct ip6_tnl_net { | ||
85 | }; | ||
86 | |||
81 | /* the IPv6 tunnel fallback device */ | 87 | /* the IPv6 tunnel fallback device */ |
82 | static struct net_device *ip6_fb_tnl_dev; | 88 | static struct net_device *ip6_fb_tnl_dev; |
83 | 89 | ||
@@ -1384,6 +1390,41 @@ static struct xfrm6_tunnel ip6ip6_handler = { | |||
1384 | .priority = 1, | 1390 | .priority = 1, |
1385 | }; | 1391 | }; |
1386 | 1392 | ||
1393 | static int ip6_tnl_init_net(struct net *net) | ||
1394 | { | ||
1395 | int err; | ||
1396 | struct ip6_tnl_net *ip6n; | ||
1397 | |||
1398 | err = -ENOMEM; | ||
1399 | ip6n = kmalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL); | ||
1400 | if (ip6n == NULL) | ||
1401 | goto err_alloc; | ||
1402 | |||
1403 | err = net_assign_generic(net, ip6_tnl_net_id, ip6n); | ||
1404 | if (err < 0) | ||
1405 | goto err_assign; | ||
1406 | |||
1407 | return 0; | ||
1408 | |||
1409 | err_assign: | ||
1410 | kfree(ip6n); | ||
1411 | err_alloc: | ||
1412 | return err; | ||
1413 | } | ||
1414 | |||
1415 | static void ip6_tnl_exit_net(struct net *net) | ||
1416 | { | ||
1417 | struct ip6_tnl_net *ip6n; | ||
1418 | |||
1419 | ip6n = net_generic(net, ip6_tnl_net_id); | ||
1420 | kfree(ip6n); | ||
1421 | } | ||
1422 | |||
1423 | static struct pernet_operations ip6_tnl_net_ops = { | ||
1424 | .init = ip6_tnl_init_net, | ||
1425 | .exit = ip6_tnl_exit_net, | ||
1426 | }; | ||
1427 | |||
1387 | /** | 1428 | /** |
1388 | * ip6_tunnel_init - register protocol and reserve needed resources | 1429 | * ip6_tunnel_init - register protocol and reserve needed resources |
1389 | * | 1430 | * |
@@ -1418,7 +1459,13 @@ static int __init ip6_tunnel_init(void) | |||
1418 | free_netdev(ip6_fb_tnl_dev); | 1459 | free_netdev(ip6_fb_tnl_dev); |
1419 | goto fail; | 1460 | goto fail; |
1420 | } | 1461 | } |
1462 | |||
1463 | err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops); | ||
1464 | if (err < 0) | ||
1465 | goto err_pernet; | ||
1421 | return 0; | 1466 | return 0; |
1467 | err_pernet: | ||
1468 | unregister_netdevice(ip6_fb_tnl_dev); | ||
1422 | fail: | 1469 | fail: |
1423 | xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); | 1470 | xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); |
1424 | unreg_ip4ip6: | 1471 | unreg_ip4ip6: |
@@ -1456,6 +1503,8 @@ static void __exit ip6_tunnel_cleanup(void) | |||
1456 | rtnl_lock(); | 1503 | rtnl_lock(); |
1457 | ip6_tnl_destroy_tunnels(); | 1504 | ip6_tnl_destroy_tunnels(); |
1458 | rtnl_unlock(); | 1505 | rtnl_unlock(); |
1506 | |||
1507 | unregister_pernet_gen_device(ip6_tnl_net_id, &ip6_tnl_net_ops); | ||
1459 | } | 1508 | } |
1460 | 1509 | ||
1461 | module_init(ip6_tunnel_init); | 1510 | module_init(ip6_tunnel_init); |