aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/ip_gre.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index d729ca820931..6209ab36cab7 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -162,7 +162,8 @@ static DEFINE_RWLOCK(ipgre_lock);
162 162
163/* Given src, dst and key, find appropriate for input tunnel. */ 163/* Given src, dst and key, find appropriate for input tunnel. */
164 164
165static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key) 165static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net,
166 __be32 remote, __be32 local, __be32 key)
166{ 167{
167 unsigned h0 = HASH(remote); 168 unsigned h0 = HASH(remote);
168 unsigned h1 = HASH(key); 169 unsigned h1 = HASH(key);
@@ -198,7 +199,8 @@ static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be3
198 return NULL; 199 return NULL;
199} 200}
200 201
201static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms) 202static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign,
203 struct ip_tunnel_parm *parms)
202{ 204{
203 __be32 remote = parms->iph.daddr; 205 __be32 remote = parms->iph.daddr;
204 __be32 local = parms->iph.saddr; 206 __be32 local = parms->iph.saddr;
@@ -216,14 +218,15 @@ static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms)
216 return &tunnels[prio][h]; 218 return &tunnels[prio][h];
217} 219}
218 220
219static inline struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) 221static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign,
222 struct ip_tunnel *t)
220{ 223{
221 return __ipgre_bucket(&t->parms); 224 return __ipgre_bucket(ign, &t->parms);
222} 225}
223 226
224static void ipgre_tunnel_link(struct ip_tunnel *t) 227static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t)
225{ 228{
226 struct ip_tunnel **tp = ipgre_bucket(t); 229 struct ip_tunnel **tp = ipgre_bucket(ign, t);
227 230
228 t->next = *tp; 231 t->next = *tp;
229 write_lock_bh(&ipgre_lock); 232 write_lock_bh(&ipgre_lock);
@@ -231,11 +234,11 @@ static void ipgre_tunnel_link(struct ip_tunnel *t)
231 write_unlock_bh(&ipgre_lock); 234 write_unlock_bh(&ipgre_lock);
232} 235}
233 236
234static void ipgre_tunnel_unlink(struct ip_tunnel *t) 237static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
235{ 238{
236 struct ip_tunnel **tp; 239 struct ip_tunnel **tp;
237 240
238 for (tp = ipgre_bucket(t); *tp; tp = &(*tp)->next) { 241 for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) {
239 if (t == *tp) { 242 if (t == *tp) {
240 write_lock_bh(&ipgre_lock); 243 write_lock_bh(&ipgre_lock);
241 *tp = t->next; 244 *tp = t->next;
@@ -245,7 +248,8 @@ static void ipgre_tunnel_unlink(struct ip_tunnel *t)
245 } 248 }
246} 249}
247 250
248static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create) 251static struct ip_tunnel * ipgre_tunnel_locate(struct net *net,
252 struct ip_tunnel_parm *parms, int create)
249{ 253{
250 __be32 remote = parms->iph.daddr; 254 __be32 remote = parms->iph.daddr;
251 __be32 local = parms->iph.saddr; 255 __be32 local = parms->iph.saddr;
@@ -253,8 +257,9 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
253 struct ip_tunnel *t, **tp, *nt; 257 struct ip_tunnel *t, **tp, *nt;
254 struct net_device *dev; 258 struct net_device *dev;
255 char name[IFNAMSIZ]; 259 char name[IFNAMSIZ];
260 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
256 261
257 for (tp = __ipgre_bucket(parms); (t = *tp) != NULL; tp = &t->next) { 262 for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) {
258 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 263 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
259 if (key == t->parms.i_key) 264 if (key == t->parms.i_key)
260 return t; 265 return t;
@@ -285,7 +290,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
285 goto failed_free; 290 goto failed_free;
286 291
287 dev_hold(dev); 292 dev_hold(dev);
288 ipgre_tunnel_link(nt); 293 ipgre_tunnel_link(ign, nt);
289 return nt; 294 return nt;
290 295
291failed_free: 296failed_free:
@@ -295,7 +300,10 @@ failed_free:
295 300
296static void ipgre_tunnel_uninit(struct net_device *dev) 301static void ipgre_tunnel_uninit(struct net_device *dev)
297{ 302{
298 ipgre_tunnel_unlink(netdev_priv(dev)); 303 struct net *net = dev_net(dev);
304 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
305
306 ipgre_tunnel_unlink(ign, netdev_priv(dev));
299 dev_put(dev); 307 dev_put(dev);
300} 308}
301 309
@@ -369,7 +377,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
369 } 377 }
370 378
371 read_lock(&ipgre_lock); 379 read_lock(&ipgre_lock);
372 t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0); 380 t = ipgre_tunnel_lookup(&init_net, iph->daddr, iph->saddr,
381 (flags&GRE_KEY) ?
382 *(((__be32*)p) + (grehlen>>2) - 1) : 0);
373 if (t == NULL || t->parms.iph.daddr == 0 || 383 if (t == NULL || t->parms.iph.daddr == 0 ||
374 ipv4_is_multicast(t->parms.iph.daddr)) 384 ipv4_is_multicast(t->parms.iph.daddr))
375 goto out; 385 goto out;
@@ -602,7 +612,8 @@ static int ipgre_rcv(struct sk_buff *skb)
602 } 612 }
603 613
604 read_lock(&ipgre_lock); 614 read_lock(&ipgre_lock);
605 if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { 615 if ((tunnel = ipgre_tunnel_lookup(&init_net,
616 iph->saddr, iph->daddr, key)) != NULL) {
606 secpath_reset(skb); 617 secpath_reset(skb);
607 618
608 skb->protocol = *(__be16*)(h + 2); 619 skb->protocol = *(__be16*)(h + 2);
@@ -960,6 +971,8 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
960 int err = 0; 971 int err = 0;
961 struct ip_tunnel_parm p; 972 struct ip_tunnel_parm p;
962 struct ip_tunnel *t; 973 struct ip_tunnel *t;
974 struct net *net = dev_net(dev);
975 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
963 976
964 switch (cmd) { 977 switch (cmd) {
965 case SIOCGETTUNNEL: 978 case SIOCGETTUNNEL:
@@ -969,7 +982,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
969 err = -EFAULT; 982 err = -EFAULT;
970 break; 983 break;
971 } 984 }
972 t = ipgre_tunnel_locate(&p, 0); 985 t = ipgre_tunnel_locate(net, &p, 0);
973 } 986 }
974 if (t == NULL) 987 if (t == NULL)
975 t = netdev_priv(dev); 988 t = netdev_priv(dev);
@@ -1001,7 +1014,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1001 if (!(p.o_flags&GRE_KEY)) 1014 if (!(p.o_flags&GRE_KEY))
1002 p.o_key = 0; 1015 p.o_key = 0;
1003 1016
1004 t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL); 1017 t = ipgre_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
1005 1018
1006 if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { 1019 if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
1007 if (t != NULL) { 1020 if (t != NULL) {
@@ -1023,14 +1036,14 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1023 err = -EINVAL; 1036 err = -EINVAL;
1024 break; 1037 break;
1025 } 1038 }
1026 ipgre_tunnel_unlink(t); 1039 ipgre_tunnel_unlink(ign, t);
1027 t->parms.iph.saddr = p.iph.saddr; 1040 t->parms.iph.saddr = p.iph.saddr;
1028 t->parms.iph.daddr = p.iph.daddr; 1041 t->parms.iph.daddr = p.iph.daddr;
1029 t->parms.i_key = p.i_key; 1042 t->parms.i_key = p.i_key;
1030 t->parms.o_key = p.o_key; 1043 t->parms.o_key = p.o_key;
1031 memcpy(dev->dev_addr, &p.iph.saddr, 4); 1044 memcpy(dev->dev_addr, &p.iph.saddr, 4);
1032 memcpy(dev->broadcast, &p.iph.daddr, 4); 1045 memcpy(dev->broadcast, &p.iph.daddr, 4);
1033 ipgre_tunnel_link(t); 1046 ipgre_tunnel_link(ign, t);
1034 netdev_state_change(dev); 1047 netdev_state_change(dev);
1035 } 1048 }
1036 } 1049 }
@@ -1063,7 +1076,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1063 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1076 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1064 goto done; 1077 goto done;
1065 err = -ENOENT; 1078 err = -ENOENT;
1066 if ((t = ipgre_tunnel_locate(&p, 0)) == NULL) 1079 if ((t = ipgre_tunnel_locate(net, &p, 0)) == NULL)
1067 goto done; 1080 goto done;
1068 err = -EPERM; 1081 err = -EPERM;
1069 if (t == netdev_priv(ipgre_fb_tunnel_dev)) 1082 if (t == netdev_priv(ipgre_fb_tunnel_dev))