diff options
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 91e46fbe6ce2..aa6efc2ab55b 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <net/inet_ecn.h> | 52 | #include <net/inet_ecn.h> |
53 | #include <net/xfrm.h> | 53 | #include <net/xfrm.h> |
54 | #include <net/dsfield.h> | 54 | #include <net/dsfield.h> |
55 | #include <net/net_namespace.h> | ||
56 | #include <net/netns/generic.h> | ||
55 | 57 | ||
56 | /* | 58 | /* |
57 | This version of net/ipv6/sit.c is cloned of net/ipv4/ip_gre.c | 59 | This version of net/ipv6/sit.c is cloned of net/ipv4/ip_gre.c |
@@ -66,6 +68,10 @@ static int ipip6_fb_tunnel_init(struct net_device *dev); | |||
66 | static int ipip6_tunnel_init(struct net_device *dev); | 68 | static int ipip6_tunnel_init(struct net_device *dev); |
67 | static void ipip6_tunnel_setup(struct net_device *dev); | 69 | static void ipip6_tunnel_setup(struct net_device *dev); |
68 | 70 | ||
71 | static int sit_net_id; | ||
72 | struct sit_net { | ||
73 | }; | ||
74 | |||
69 | static struct net_device *ipip6_fb_tunnel_dev; | 75 | static struct net_device *ipip6_fb_tunnel_dev; |
70 | 76 | ||
71 | static struct ip_tunnel *tunnels_r_l[HASH_SIZE]; | 77 | static struct ip_tunnel *tunnels_r_l[HASH_SIZE]; |
@@ -1068,6 +1074,41 @@ static void __exit sit_destroy_tunnels(void) | |||
1068 | } | 1074 | } |
1069 | } | 1075 | } |
1070 | 1076 | ||
1077 | static int sit_init_net(struct net *net) | ||
1078 | { | ||
1079 | int err; | ||
1080 | struct sit_net *sitn; | ||
1081 | |||
1082 | err = -ENOMEM; | ||
1083 | sitn = kmalloc(sizeof(struct sit_net), GFP_KERNEL); | ||
1084 | if (sitn == NULL) | ||
1085 | goto err_alloc; | ||
1086 | |||
1087 | err = net_assign_generic(net, sit_net_id, sitn); | ||
1088 | if (err < 0) | ||
1089 | goto err_assign; | ||
1090 | |||
1091 | return 0; | ||
1092 | |||
1093 | err_assign: | ||
1094 | kfree(sitn); | ||
1095 | err_alloc: | ||
1096 | return err; | ||
1097 | } | ||
1098 | |||
1099 | static void sit_exit_net(struct net *net) | ||
1100 | { | ||
1101 | struct sit_net *sitn; | ||
1102 | |||
1103 | sitn = net_generic(net, sit_net_id); | ||
1104 | kfree(sitn); | ||
1105 | } | ||
1106 | |||
1107 | static struct pernet_operations sit_net_ops = { | ||
1108 | .init = sit_init_net, | ||
1109 | .exit = sit_exit_net, | ||
1110 | }; | ||
1111 | |||
1071 | static void __exit sit_cleanup(void) | 1112 | static void __exit sit_cleanup(void) |
1072 | { | 1113 | { |
1073 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1114 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
@@ -1076,6 +1117,8 @@ static void __exit sit_cleanup(void) | |||
1076 | sit_destroy_tunnels(); | 1117 | sit_destroy_tunnels(); |
1077 | unregister_netdevice(ipip6_fb_tunnel_dev); | 1118 | unregister_netdevice(ipip6_fb_tunnel_dev); |
1078 | rtnl_unlock(); | 1119 | rtnl_unlock(); |
1120 | |||
1121 | unregister_pernet_gen_device(sit_net_id, &sit_net_ops); | ||
1079 | } | 1122 | } |
1080 | 1123 | ||
1081 | static int __init sit_init(void) | 1124 | static int __init sit_init(void) |
@@ -1101,6 +1144,10 @@ static int __init sit_init(void) | |||
1101 | if ((err = register_netdev(ipip6_fb_tunnel_dev))) | 1144 | if ((err = register_netdev(ipip6_fb_tunnel_dev))) |
1102 | goto err2; | 1145 | goto err2; |
1103 | 1146 | ||
1147 | err = register_pernet_gen_device(&sit_net_id, &sit_net_ops); | ||
1148 | if (err < 0) | ||
1149 | goto err3; | ||
1150 | |||
1104 | out: | 1151 | out: |
1105 | return err; | 1152 | return err; |
1106 | err2: | 1153 | err2: |
@@ -1108,6 +1155,9 @@ static int __init sit_init(void) | |||
1108 | err1: | 1155 | err1: |
1109 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1156 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
1110 | goto out; | 1157 | goto out; |
1158 | err3: | ||
1159 | unregister_netdevice(ipip6_fb_tunnel_dev); | ||
1160 | goto err1; | ||
1111 | } | 1161 | } |
1112 | 1162 | ||
1113 | module_init(sit_init); | 1163 | module_init(sit_init); |