diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 228 |
1 files changed, 146 insertions, 82 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index e7821ba7a9a0..2ada033406de 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <net/dsfield.h> | 39 | #include <net/dsfield.h> |
40 | #include <net/inet_ecn.h> | 40 | #include <net/inet_ecn.h> |
41 | #include <net/xfrm.h> | 41 | #include <net/xfrm.h> |
42 | #include <net/net_namespace.h> | ||
43 | #include <net/netns/generic.h> | ||
42 | 44 | ||
43 | #ifdef CONFIG_IPV6 | 45 | #ifdef CONFIG_IPV6 |
44 | #include <net/ipv6.h> | 46 | #include <net/ipv6.h> |
@@ -122,7 +124,14 @@ static void ipgre_tunnel_setup(struct net_device *dev); | |||
122 | 124 | ||
123 | static int ipgre_fb_tunnel_init(struct net_device *dev); | 125 | static int ipgre_fb_tunnel_init(struct net_device *dev); |
124 | 126 | ||
125 | static struct net_device *ipgre_fb_tunnel_dev; | 127 | #define HASH_SIZE 16 |
128 | |||
129 | static int ipgre_net_id; | ||
130 | struct ipgre_net { | ||
131 | struct ip_tunnel *tunnels[4][HASH_SIZE]; | ||
132 | |||
133 | struct net_device *fb_tunnel_dev; | ||
134 | }; | ||
126 | 135 | ||
127 | /* Tunnel hash table */ | 136 | /* Tunnel hash table */ |
128 | 137 | ||
@@ -142,39 +151,38 @@ static struct net_device *ipgre_fb_tunnel_dev; | |||
142 | will match fallback tunnel. | 151 | will match fallback tunnel. |
143 | */ | 152 | */ |
144 | 153 | ||
145 | #define HASH_SIZE 16 | ||
146 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) | 154 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
147 | 155 | ||
148 | static struct ip_tunnel *tunnels[4][HASH_SIZE]; | 156 | #define tunnels_r_l tunnels[3] |
149 | 157 | #define tunnels_r tunnels[2] | |
150 | #define tunnels_r_l (tunnels[3]) | 158 | #define tunnels_l tunnels[1] |
151 | #define tunnels_r (tunnels[2]) | 159 | #define tunnels_wc tunnels[0] |
152 | #define tunnels_l (tunnels[1]) | ||
153 | #define tunnels_wc (tunnels[0]) | ||
154 | 160 | ||
155 | static DEFINE_RWLOCK(ipgre_lock); | 161 | static DEFINE_RWLOCK(ipgre_lock); |
156 | 162 | ||
157 | /* Given src, dst and key, find appropriate for input tunnel. */ | 163 | /* Given src, dst and key, find appropriate for input tunnel. */ |
158 | 164 | ||
159 | static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key) | 165 | static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net, |
166 | __be32 remote, __be32 local, __be32 key) | ||
160 | { | 167 | { |
161 | unsigned h0 = HASH(remote); | 168 | unsigned h0 = HASH(remote); |
162 | unsigned h1 = HASH(key); | 169 | unsigned h1 = HASH(key); |
163 | struct ip_tunnel *t; | 170 | struct ip_tunnel *t; |
171 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
164 | 172 | ||
165 | for (t = tunnels_r_l[h0^h1]; t; t = t->next) { | 173 | for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) { |
166 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { | 174 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { |
167 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 175 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) |
168 | return t; | 176 | return t; |
169 | } | 177 | } |
170 | } | 178 | } |
171 | for (t = tunnels_r[h0^h1]; t; t = t->next) { | 179 | for (t = ign->tunnels_r[h0^h1]; t; t = t->next) { |
172 | if (remote == t->parms.iph.daddr) { | 180 | if (remote == t->parms.iph.daddr) { |
173 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 181 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) |
174 | return t; | 182 | return t; |
175 | } | 183 | } |
176 | } | 184 | } |
177 | for (t = tunnels_l[h1]; t; t = t->next) { | 185 | for (t = ign->tunnels_l[h1]; t; t = t->next) { |
178 | if (local == t->parms.iph.saddr || | 186 | if (local == t->parms.iph.saddr || |
179 | (local == t->parms.iph.daddr && | 187 | (local == t->parms.iph.daddr && |
180 | ipv4_is_multicast(local))) { | 188 | ipv4_is_multicast(local))) { |
@@ -182,17 +190,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be3 | |||
182 | return t; | 190 | return t; |
183 | } | 191 | } |
184 | } | 192 | } |
185 | for (t = tunnels_wc[h1]; t; t = t->next) { | 193 | for (t = ign->tunnels_wc[h1]; t; t = t->next) { |
186 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 194 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) |
187 | return t; | 195 | return t; |
188 | } | 196 | } |
189 | 197 | ||
190 | if (ipgre_fb_tunnel_dev->flags&IFF_UP) | 198 | if (ign->fb_tunnel_dev->flags&IFF_UP) |
191 | return netdev_priv(ipgre_fb_tunnel_dev); | 199 | return netdev_priv(ign->fb_tunnel_dev); |
192 | return NULL; | 200 | return NULL; |
193 | } | 201 | } |
194 | 202 | ||
195 | static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms) | 203 | static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign, |
204 | struct ip_tunnel_parm *parms) | ||
196 | { | 205 | { |
197 | __be32 remote = parms->iph.daddr; | 206 | __be32 remote = parms->iph.daddr; |
198 | __be32 local = parms->iph.saddr; | 207 | __be32 local = parms->iph.saddr; |
@@ -207,17 +216,18 @@ static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms) | |||
207 | h ^= HASH(remote); | 216 | h ^= HASH(remote); |
208 | } | 217 | } |
209 | 218 | ||
210 | return &tunnels[prio][h]; | 219 | return &ign->tunnels[prio][h]; |
211 | } | 220 | } |
212 | 221 | ||
213 | static inline struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) | 222 | static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign, |
223 | struct ip_tunnel *t) | ||
214 | { | 224 | { |
215 | return __ipgre_bucket(&t->parms); | 225 | return __ipgre_bucket(ign, &t->parms); |
216 | } | 226 | } |
217 | 227 | ||
218 | static void ipgre_tunnel_link(struct ip_tunnel *t) | 228 | static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t) |
219 | { | 229 | { |
220 | struct ip_tunnel **tp = ipgre_bucket(t); | 230 | struct ip_tunnel **tp = ipgre_bucket(ign, t); |
221 | 231 | ||
222 | t->next = *tp; | 232 | t->next = *tp; |
223 | write_lock_bh(&ipgre_lock); | 233 | write_lock_bh(&ipgre_lock); |
@@ -225,11 +235,11 @@ static void ipgre_tunnel_link(struct ip_tunnel *t) | |||
225 | write_unlock_bh(&ipgre_lock); | 235 | write_unlock_bh(&ipgre_lock); |
226 | } | 236 | } |
227 | 237 | ||
228 | static void ipgre_tunnel_unlink(struct ip_tunnel *t) | 238 | static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t) |
229 | { | 239 | { |
230 | struct ip_tunnel **tp; | 240 | struct ip_tunnel **tp; |
231 | 241 | ||
232 | for (tp = ipgre_bucket(t); *tp; tp = &(*tp)->next) { | 242 | for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) { |
233 | if (t == *tp) { | 243 | if (t == *tp) { |
234 | write_lock_bh(&ipgre_lock); | 244 | write_lock_bh(&ipgre_lock); |
235 | *tp = t->next; | 245 | *tp = t->next; |
@@ -239,7 +249,8 @@ static void ipgre_tunnel_unlink(struct ip_tunnel *t) | |||
239 | } | 249 | } |
240 | } | 250 | } |
241 | 251 | ||
242 | static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create) | 252 | static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, |
253 | struct ip_tunnel_parm *parms, int create) | ||
243 | { | 254 | { |
244 | __be32 remote = parms->iph.daddr; | 255 | __be32 remote = parms->iph.daddr; |
245 | __be32 local = parms->iph.saddr; | 256 | __be32 local = parms->iph.saddr; |
@@ -247,8 +258,9 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
247 | struct ip_tunnel *t, **tp, *nt; | 258 | struct ip_tunnel *t, **tp, *nt; |
248 | struct net_device *dev; | 259 | struct net_device *dev; |
249 | char name[IFNAMSIZ]; | 260 | char name[IFNAMSIZ]; |
261 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
250 | 262 | ||
251 | for (tp = __ipgre_bucket(parms); (t = *tp) != NULL; tp = &t->next) { | 263 | for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) { |
252 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { | 264 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { |
253 | if (key == t->parms.i_key) | 265 | if (key == t->parms.i_key) |
254 | return t; | 266 | return t; |
@@ -266,6 +278,8 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
266 | if (!dev) | 278 | if (!dev) |
267 | return NULL; | 279 | return NULL; |
268 | 280 | ||
281 | dev_net_set(dev, net); | ||
282 | |||
269 | if (strchr(name, '%')) { | 283 | if (strchr(name, '%')) { |
270 | if (dev_alloc_name(dev, name) < 0) | 284 | if (dev_alloc_name(dev, name) < 0) |
271 | goto failed_free; | 285 | goto failed_free; |
@@ -279,7 +293,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
279 | goto failed_free; | 293 | goto failed_free; |
280 | 294 | ||
281 | dev_hold(dev); | 295 | dev_hold(dev); |
282 | ipgre_tunnel_link(nt); | 296 | ipgre_tunnel_link(ign, nt); |
283 | return nt; | 297 | return nt; |
284 | 298 | ||
285 | failed_free: | 299 | failed_free: |
@@ -289,7 +303,10 @@ failed_free: | |||
289 | 303 | ||
290 | static void ipgre_tunnel_uninit(struct net_device *dev) | 304 | static void ipgre_tunnel_uninit(struct net_device *dev) |
291 | { | 305 | { |
292 | ipgre_tunnel_unlink(netdev_priv(dev)); | 306 | struct net *net = dev_net(dev); |
307 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
308 | |||
309 | ipgre_tunnel_unlink(ign, netdev_priv(dev)); | ||
293 | dev_put(dev); | 310 | dev_put(dev); |
294 | } | 311 | } |
295 | 312 | ||
@@ -363,7 +380,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
363 | } | 380 | } |
364 | 381 | ||
365 | read_lock(&ipgre_lock); | 382 | read_lock(&ipgre_lock); |
366 | t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0); | 383 | t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr, |
384 | (flags&GRE_KEY) ? | ||
385 | *(((__be32*)p) + (grehlen>>2) - 1) : 0); | ||
367 | if (t == NULL || t->parms.iph.daddr == 0 || | 386 | if (t == NULL || t->parms.iph.daddr == 0 || |
368 | ipv4_is_multicast(t->parms.iph.daddr)) | 387 | ipv4_is_multicast(t->parms.iph.daddr)) |
369 | goto out; | 388 | goto out; |
@@ -476,7 +495,7 @@ out: | |||
476 | fl.fl4_dst = eiph->saddr; | 495 | fl.fl4_dst = eiph->saddr; |
477 | fl.fl4_tos = RT_TOS(eiph->tos); | 496 | fl.fl4_tos = RT_TOS(eiph->tos); |
478 | fl.proto = IPPROTO_GRE; | 497 | fl.proto = IPPROTO_GRE; |
479 | if (ip_route_output_key(&init_net, &rt, &fl)) { | 498 | if (ip_route_output_key(dev_net(skb->dev), &rt, &fl)) { |
480 | kfree_skb(skb2); | 499 | kfree_skb(skb2); |
481 | return; | 500 | return; |
482 | } | 501 | } |
@@ -489,7 +508,7 @@ out: | |||
489 | fl.fl4_dst = eiph->daddr; | 508 | fl.fl4_dst = eiph->daddr; |
490 | fl.fl4_src = eiph->saddr; | 509 | fl.fl4_src = eiph->saddr; |
491 | fl.fl4_tos = eiph->tos; | 510 | fl.fl4_tos = eiph->tos; |
492 | if (ip_route_output_key(&init_net, &rt, &fl) || | 511 | if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) || |
493 | rt->u.dst.dev->type != ARPHRD_IPGRE) { | 512 | rt->u.dst.dev->type != ARPHRD_IPGRE) { |
494 | ip_rt_put(rt); | 513 | ip_rt_put(rt); |
495 | kfree_skb(skb2); | 514 | kfree_skb(skb2); |
@@ -596,7 +615,8 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
596 | } | 615 | } |
597 | 616 | ||
598 | read_lock(&ipgre_lock); | 617 | read_lock(&ipgre_lock); |
599 | if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { | 618 | if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), |
619 | iph->saddr, iph->daddr, key)) != NULL) { | ||
600 | secpath_reset(skb); | 620 | secpath_reset(skb); |
601 | 621 | ||
602 | skb->protocol = *(__be16*)(h + 2); | 622 | skb->protocol = *(__be16*)(h + 2); |
@@ -619,7 +639,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
619 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 639 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
620 | if (ipv4_is_multicast(iph->daddr)) { | 640 | if (ipv4_is_multicast(iph->daddr)) { |
621 | /* Looped back packet, drop it! */ | 641 | /* Looped back packet, drop it! */ |
622 | if (((struct rtable*)skb->dst)->fl.iif == 0) | 642 | if (skb->rtable->fl.iif == 0) |
623 | goto drop; | 643 | goto drop; |
624 | tunnel->stat.multicast++; | 644 | tunnel->stat.multicast++; |
625 | skb->pkt_type = PACKET_BROADCAST; | 645 | skb->pkt_type = PACKET_BROADCAST; |
@@ -699,7 +719,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
699 | } | 719 | } |
700 | 720 | ||
701 | if (skb->protocol == htons(ETH_P_IP)) { | 721 | if (skb->protocol == htons(ETH_P_IP)) { |
702 | rt = (struct rtable*)skb->dst; | 722 | rt = skb->rtable; |
703 | if ((dst = rt->rt_gateway) == 0) | 723 | if ((dst = rt->rt_gateway) == 0) |
704 | goto tx_error_icmp; | 724 | goto tx_error_icmp; |
705 | } | 725 | } |
@@ -744,7 +764,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
744 | .saddr = tiph->saddr, | 764 | .saddr = tiph->saddr, |
745 | .tos = RT_TOS(tos) } }, | 765 | .tos = RT_TOS(tos) } }, |
746 | .proto = IPPROTO_GRE }; | 766 | .proto = IPPROTO_GRE }; |
747 | if (ip_route_output_key(&init_net, &rt, &fl)) { | 767 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { |
748 | tunnel->stat.tx_carrier_errors++; | 768 | tunnel->stat.tx_carrier_errors++; |
749 | goto tx_error; | 769 | goto tx_error; |
750 | } | 770 | } |
@@ -917,7 +937,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev) | |||
917 | .tos = RT_TOS(iph->tos) } }, | 937 | .tos = RT_TOS(iph->tos) } }, |
918 | .proto = IPPROTO_GRE }; | 938 | .proto = IPPROTO_GRE }; |
919 | struct rtable *rt; | 939 | struct rtable *rt; |
920 | if (!ip_route_output_key(&init_net, &rt, &fl)) { | 940 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { |
921 | tdev = rt->u.dst.dev; | 941 | tdev = rt->u.dst.dev; |
922 | ip_rt_put(rt); | 942 | ip_rt_put(rt); |
923 | } | 943 | } |
@@ -925,7 +945,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev) | |||
925 | } | 945 | } |
926 | 946 | ||
927 | if (!tdev && tunnel->parms.link) | 947 | if (!tdev && tunnel->parms.link) |
928 | tdev = __dev_get_by_index(&init_net, tunnel->parms.link); | 948 | tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); |
929 | 949 | ||
930 | if (tdev) { | 950 | if (tdev) { |
931 | hlen = tdev->hard_header_len; | 951 | hlen = tdev->hard_header_len; |
@@ -954,16 +974,18 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
954 | int err = 0; | 974 | int err = 0; |
955 | struct ip_tunnel_parm p; | 975 | struct ip_tunnel_parm p; |
956 | struct ip_tunnel *t; | 976 | struct ip_tunnel *t; |
977 | struct net *net = dev_net(dev); | ||
978 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
957 | 979 | ||
958 | switch (cmd) { | 980 | switch (cmd) { |
959 | case SIOCGETTUNNEL: | 981 | case SIOCGETTUNNEL: |
960 | t = NULL; | 982 | t = NULL; |
961 | if (dev == ipgre_fb_tunnel_dev) { | 983 | if (dev == ign->fb_tunnel_dev) { |
962 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { | 984 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { |
963 | err = -EFAULT; | 985 | err = -EFAULT; |
964 | break; | 986 | break; |
965 | } | 987 | } |
966 | t = ipgre_tunnel_locate(&p, 0); | 988 | t = ipgre_tunnel_locate(net, &p, 0); |
967 | } | 989 | } |
968 | if (t == NULL) | 990 | if (t == NULL) |
969 | t = netdev_priv(dev); | 991 | t = netdev_priv(dev); |
@@ -995,9 +1017,9 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
995 | if (!(p.o_flags&GRE_KEY)) | 1017 | if (!(p.o_flags&GRE_KEY)) |
996 | p.o_key = 0; | 1018 | p.o_key = 0; |
997 | 1019 | ||
998 | t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL); | 1020 | t = ipgre_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL); |
999 | 1021 | ||
1000 | if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { | 1022 | if (dev != ign->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { |
1001 | if (t != NULL) { | 1023 | if (t != NULL) { |
1002 | if (t->dev != dev) { | 1024 | if (t->dev != dev) { |
1003 | err = -EEXIST; | 1025 | err = -EEXIST; |
@@ -1017,14 +1039,14 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1017 | err = -EINVAL; | 1039 | err = -EINVAL; |
1018 | break; | 1040 | break; |
1019 | } | 1041 | } |
1020 | ipgre_tunnel_unlink(t); | 1042 | ipgre_tunnel_unlink(ign, t); |
1021 | t->parms.iph.saddr = p.iph.saddr; | 1043 | t->parms.iph.saddr = p.iph.saddr; |
1022 | t->parms.iph.daddr = p.iph.daddr; | 1044 | t->parms.iph.daddr = p.iph.daddr; |
1023 | t->parms.i_key = p.i_key; | 1045 | t->parms.i_key = p.i_key; |
1024 | t->parms.o_key = p.o_key; | 1046 | t->parms.o_key = p.o_key; |
1025 | memcpy(dev->dev_addr, &p.iph.saddr, 4); | 1047 | memcpy(dev->dev_addr, &p.iph.saddr, 4); |
1026 | memcpy(dev->broadcast, &p.iph.daddr, 4); | 1048 | memcpy(dev->broadcast, &p.iph.daddr, 4); |
1027 | ipgre_tunnel_link(t); | 1049 | ipgre_tunnel_link(ign, t); |
1028 | netdev_state_change(dev); | 1050 | netdev_state_change(dev); |
1029 | } | 1051 | } |
1030 | } | 1052 | } |
@@ -1052,15 +1074,15 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1052 | if (!capable(CAP_NET_ADMIN)) | 1074 | if (!capable(CAP_NET_ADMIN)) |
1053 | goto done; | 1075 | goto done; |
1054 | 1076 | ||
1055 | if (dev == ipgre_fb_tunnel_dev) { | 1077 | if (dev == ign->fb_tunnel_dev) { |
1056 | err = -EFAULT; | 1078 | err = -EFAULT; |
1057 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) | 1079 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) |
1058 | goto done; | 1080 | goto done; |
1059 | err = -ENOENT; | 1081 | err = -ENOENT; |
1060 | if ((t = ipgre_tunnel_locate(&p, 0)) == NULL) | 1082 | if ((t = ipgre_tunnel_locate(net, &p, 0)) == NULL) |
1061 | goto done; | 1083 | goto done; |
1062 | err = -EPERM; | 1084 | err = -EPERM; |
1063 | if (t == netdev_priv(ipgre_fb_tunnel_dev)) | 1085 | if (t == netdev_priv(ign->fb_tunnel_dev)) |
1064 | goto done; | 1086 | goto done; |
1065 | dev = t->dev; | 1087 | dev = t->dev; |
1066 | } | 1088 | } |
@@ -1173,7 +1195,7 @@ static int ipgre_open(struct net_device *dev) | |||
1173 | .tos = RT_TOS(t->parms.iph.tos) } }, | 1195 | .tos = RT_TOS(t->parms.iph.tos) } }, |
1174 | .proto = IPPROTO_GRE }; | 1196 | .proto = IPPROTO_GRE }; |
1175 | struct rtable *rt; | 1197 | struct rtable *rt; |
1176 | if (ip_route_output_key(&init_net, &rt, &fl)) | 1198 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) |
1177 | return -EADDRNOTAVAIL; | 1199 | return -EADDRNOTAVAIL; |
1178 | dev = rt->u.dst.dev; | 1200 | dev = rt->u.dst.dev; |
1179 | ip_rt_put(rt); | 1201 | ip_rt_put(rt); |
@@ -1190,7 +1212,7 @@ static int ipgre_close(struct net_device *dev) | |||
1190 | struct ip_tunnel *t = netdev_priv(dev); | 1212 | struct ip_tunnel *t = netdev_priv(dev); |
1191 | if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { | 1213 | if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { |
1192 | struct in_device *in_dev; | 1214 | struct in_device *in_dev; |
1193 | in_dev = inetdev_by_index(dev->nd_net, t->mlink); | 1215 | in_dev = inetdev_by_index(dev_net(dev), t->mlink); |
1194 | if (in_dev) { | 1216 | if (in_dev) { |
1195 | ip_mc_dec_group(in_dev, t->parms.iph.daddr); | 1217 | ip_mc_dec_group(in_dev, t->parms.iph.daddr); |
1196 | in_dev_put(in_dev); | 1218 | in_dev_put(in_dev); |
@@ -1216,6 +1238,7 @@ static void ipgre_tunnel_setup(struct net_device *dev) | |||
1216 | dev->flags = IFF_NOARP; | 1238 | dev->flags = IFF_NOARP; |
1217 | dev->iflink = 0; | 1239 | dev->iflink = 0; |
1218 | dev->addr_len = 4; | 1240 | dev->addr_len = 4; |
1241 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
1219 | } | 1242 | } |
1220 | 1243 | ||
1221 | static int ipgre_tunnel_init(struct net_device *dev) | 1244 | static int ipgre_tunnel_init(struct net_device *dev) |
@@ -1251,10 +1274,11 @@ static int ipgre_tunnel_init(struct net_device *dev) | |||
1251 | return 0; | 1274 | return 0; |
1252 | } | 1275 | } |
1253 | 1276 | ||
1254 | static int __init ipgre_fb_tunnel_init(struct net_device *dev) | 1277 | static int ipgre_fb_tunnel_init(struct net_device *dev) |
1255 | { | 1278 | { |
1256 | struct ip_tunnel *tunnel = netdev_priv(dev); | 1279 | struct ip_tunnel *tunnel = netdev_priv(dev); |
1257 | struct iphdr *iph = &tunnel->parms.iph; | 1280 | struct iphdr *iph = &tunnel->parms.iph; |
1281 | struct ipgre_net *ign = net_generic(dev_net(dev), ipgre_net_id); | ||
1258 | 1282 | ||
1259 | tunnel->dev = dev; | 1283 | tunnel->dev = dev; |
1260 | strcpy(tunnel->parms.name, dev->name); | 1284 | strcpy(tunnel->parms.name, dev->name); |
@@ -1265,7 +1289,7 @@ static int __init ipgre_fb_tunnel_init(struct net_device *dev) | |||
1265 | tunnel->hlen = sizeof(struct iphdr) + 4; | 1289 | tunnel->hlen = sizeof(struct iphdr) + 4; |
1266 | 1290 | ||
1267 | dev_hold(dev); | 1291 | dev_hold(dev); |
1268 | tunnels_wc[0] = tunnel; | 1292 | ign->tunnels_wc[0] = tunnel; |
1269 | return 0; | 1293 | return 0; |
1270 | } | 1294 | } |
1271 | 1295 | ||
@@ -1273,56 +1297,98 @@ static int __init ipgre_fb_tunnel_init(struct net_device *dev) | |||
1273 | static struct net_protocol ipgre_protocol = { | 1297 | static struct net_protocol ipgre_protocol = { |
1274 | .handler = ipgre_rcv, | 1298 | .handler = ipgre_rcv, |
1275 | .err_handler = ipgre_err, | 1299 | .err_handler = ipgre_err, |
1300 | .netns_ok = 1, | ||
1276 | }; | 1301 | }; |
1277 | 1302 | ||
1303 | static void ipgre_destroy_tunnels(struct ipgre_net *ign) | ||
1304 | { | ||
1305 | int prio; | ||
1278 | 1306 | ||
1279 | /* | 1307 | for (prio = 0; prio < 4; prio++) { |
1280 | * And now the modules code and kernel interface. | 1308 | int h; |
1281 | */ | 1309 | for (h = 0; h < HASH_SIZE; h++) { |
1310 | struct ip_tunnel *t; | ||
1311 | while ((t = ign->tunnels[prio][h]) != NULL) | ||
1312 | unregister_netdevice(t->dev); | ||
1313 | } | ||
1314 | } | ||
1315 | } | ||
1282 | 1316 | ||
1283 | static int __init ipgre_init(void) | 1317 | static int ipgre_init_net(struct net *net) |
1284 | { | 1318 | { |
1285 | int err; | 1319 | int err; |
1320 | struct ipgre_net *ign; | ||
1286 | 1321 | ||
1287 | printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); | 1322 | err = -ENOMEM; |
1323 | ign = kzalloc(sizeof(struct ipgre_net), GFP_KERNEL); | ||
1324 | if (ign == NULL) | ||
1325 | goto err_alloc; | ||
1288 | 1326 | ||
1289 | if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) { | 1327 | err = net_assign_generic(net, ipgre_net_id, ign); |
1290 | printk(KERN_INFO "ipgre init: can't add protocol\n"); | 1328 | if (err < 0) |
1291 | return -EAGAIN; | 1329 | goto err_assign; |
1292 | } | ||
1293 | 1330 | ||
1294 | ipgre_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0", | 1331 | ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0", |
1295 | ipgre_tunnel_setup); | 1332 | ipgre_tunnel_setup); |
1296 | if (!ipgre_fb_tunnel_dev) { | 1333 | if (!ign->fb_tunnel_dev) { |
1297 | err = -ENOMEM; | 1334 | err = -ENOMEM; |
1298 | goto err1; | 1335 | goto err_alloc_dev; |
1299 | } | 1336 | } |
1300 | 1337 | ||
1301 | ipgre_fb_tunnel_dev->init = ipgre_fb_tunnel_init; | 1338 | ign->fb_tunnel_dev->init = ipgre_fb_tunnel_init; |
1339 | dev_net_set(ign->fb_tunnel_dev, net); | ||
1302 | 1340 | ||
1303 | if ((err = register_netdev(ipgre_fb_tunnel_dev))) | 1341 | if ((err = register_netdev(ign->fb_tunnel_dev))) |
1304 | goto err2; | 1342 | goto err_reg_dev; |
1305 | out: | 1343 | |
1344 | return 0; | ||
1345 | |||
1346 | err_reg_dev: | ||
1347 | free_netdev(ign->fb_tunnel_dev); | ||
1348 | err_alloc_dev: | ||
1349 | /* nothing */ | ||
1350 | err_assign: | ||
1351 | kfree(ign); | ||
1352 | err_alloc: | ||
1306 | return err; | 1353 | return err; |
1307 | err2: | ||
1308 | free_netdev(ipgre_fb_tunnel_dev); | ||
1309 | err1: | ||
1310 | inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); | ||
1311 | goto out; | ||
1312 | } | 1354 | } |
1313 | 1355 | ||
1314 | static void __exit ipgre_destroy_tunnels(void) | 1356 | static void ipgre_exit_net(struct net *net) |
1315 | { | 1357 | { |
1316 | int prio; | 1358 | struct ipgre_net *ign; |
1317 | 1359 | ||
1318 | for (prio = 0; prio < 4; prio++) { | 1360 | ign = net_generic(net, ipgre_net_id); |
1319 | int h; | 1361 | rtnl_lock(); |
1320 | for (h = 0; h < HASH_SIZE; h++) { | 1362 | ipgre_destroy_tunnels(ign); |
1321 | struct ip_tunnel *t; | 1363 | rtnl_unlock(); |
1322 | while ((t = tunnels[prio][h]) != NULL) | 1364 | kfree(ign); |
1323 | unregister_netdevice(t->dev); | 1365 | } |
1324 | } | 1366 | |
1367 | static struct pernet_operations ipgre_net_ops = { | ||
1368 | .init = ipgre_init_net, | ||
1369 | .exit = ipgre_exit_net, | ||
1370 | }; | ||
1371 | |||
1372 | /* | ||
1373 | * And now the modules code and kernel interface. | ||
1374 | */ | ||
1375 | |||
1376 | static int __init ipgre_init(void) | ||
1377 | { | ||
1378 | int err; | ||
1379 | |||
1380 | printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); | ||
1381 | |||
1382 | if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) { | ||
1383 | printk(KERN_INFO "ipgre init: can't add protocol\n"); | ||
1384 | return -EAGAIN; | ||
1325 | } | 1385 | } |
1386 | |||
1387 | err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); | ||
1388 | if (err < 0) | ||
1389 | inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); | ||
1390 | |||
1391 | return err; | ||
1326 | } | 1392 | } |
1327 | 1393 | ||
1328 | static void __exit ipgre_fini(void) | 1394 | static void __exit ipgre_fini(void) |
@@ -1330,9 +1396,7 @@ static void __exit ipgre_fini(void) | |||
1330 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) | 1396 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) |
1331 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); | 1397 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); |
1332 | 1398 | ||
1333 | rtnl_lock(); | 1399 | unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); |
1334 | ipgre_destroy_tunnels(); | ||
1335 | rtnl_unlock(); | ||
1336 | } | 1400 | } |
1337 | 1401 | ||
1338 | module_init(ipgre_init); | 1402 | module_init(ipgre_init); |