diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ipip.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e657a6605e08..bc4d4cb89b01 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -138,7 +138,8 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne | |||
138 | 138 | ||
139 | static DEFINE_RWLOCK(ipip_lock); | 139 | static DEFINE_RWLOCK(ipip_lock); |
140 | 140 | ||
141 | static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local) | 141 | static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, |
142 | __be32 remote, __be32 local) | ||
142 | { | 143 | { |
143 | unsigned h0 = HASH(remote); | 144 | unsigned h0 = HASH(remote); |
144 | unsigned h1 = HASH(local); | 145 | unsigned h1 = HASH(local); |
@@ -162,7 +163,8 @@ static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local) | |||
162 | return NULL; | 163 | return NULL; |
163 | } | 164 | } |
164 | 165 | ||
165 | static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms) | 166 | static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn, |
167 | struct ip_tunnel_parm *parms) | ||
166 | { | 168 | { |
167 | __be32 remote = parms->iph.daddr; | 169 | __be32 remote = parms->iph.daddr; |
168 | __be32 local = parms->iph.saddr; | 170 | __be32 local = parms->iph.saddr; |
@@ -180,16 +182,17 @@ static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms) | |||
180 | return &tunnels[prio][h]; | 182 | return &tunnels[prio][h]; |
181 | } | 183 | } |
182 | 184 | ||
183 | static inline struct ip_tunnel **ipip_bucket(struct ip_tunnel *t) | 185 | static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn, |
186 | struct ip_tunnel *t) | ||
184 | { | 187 | { |
185 | return __ipip_bucket(&t->parms); | 188 | return __ipip_bucket(ipn, &t->parms); |
186 | } | 189 | } |
187 | 190 | ||
188 | static void ipip_tunnel_unlink(struct ip_tunnel *t) | 191 | static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t) |
189 | { | 192 | { |
190 | struct ip_tunnel **tp; | 193 | struct ip_tunnel **tp; |
191 | 194 | ||
192 | for (tp = ipip_bucket(t); *tp; tp = &(*tp)->next) { | 195 | for (tp = ipip_bucket(ipn, t); *tp; tp = &(*tp)->next) { |
193 | if (t == *tp) { | 196 | if (t == *tp) { |
194 | write_lock_bh(&ipip_lock); | 197 | write_lock_bh(&ipip_lock); |
195 | *tp = t->next; | 198 | *tp = t->next; |
@@ -199,9 +202,9 @@ static void ipip_tunnel_unlink(struct ip_tunnel *t) | |||
199 | } | 202 | } |
200 | } | 203 | } |
201 | 204 | ||
202 | static void ipip_tunnel_link(struct ip_tunnel *t) | 205 | static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t) |
203 | { | 206 | { |
204 | struct ip_tunnel **tp = ipip_bucket(t); | 207 | struct ip_tunnel **tp = ipip_bucket(ipn, t); |
205 | 208 | ||
206 | t->next = *tp; | 209 | t->next = *tp; |
207 | write_lock_bh(&ipip_lock); | 210 | write_lock_bh(&ipip_lock); |
@@ -209,15 +212,17 @@ static void ipip_tunnel_link(struct ip_tunnel *t) | |||
209 | write_unlock_bh(&ipip_lock); | 212 | write_unlock_bh(&ipip_lock); |
210 | } | 213 | } |
211 | 214 | ||
212 | static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) | 215 | static struct ip_tunnel * ipip_tunnel_locate(struct net *net, |
216 | struct ip_tunnel_parm *parms, int create) | ||
213 | { | 217 | { |
214 | __be32 remote = parms->iph.daddr; | 218 | __be32 remote = parms->iph.daddr; |
215 | __be32 local = parms->iph.saddr; | 219 | __be32 local = parms->iph.saddr; |
216 | struct ip_tunnel *t, **tp, *nt; | 220 | struct ip_tunnel *t, **tp, *nt; |
217 | struct net_device *dev; | 221 | struct net_device *dev; |
218 | char name[IFNAMSIZ]; | 222 | char name[IFNAMSIZ]; |
223 | struct ipip_net *ipn = net_generic(net, ipip_net_id); | ||
219 | 224 | ||
220 | for (tp = __ipip_bucket(parms); (t = *tp) != NULL; tp = &t->next) { | 225 | for (tp = __ipip_bucket(ipn, parms); (t = *tp) != NULL; tp = &t->next) { |
221 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) | 226 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) |
222 | return t; | 227 | return t; |
223 | } | 228 | } |
@@ -246,7 +251,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c | |||
246 | goto failed_free; | 251 | goto failed_free; |
247 | 252 | ||
248 | dev_hold(dev); | 253 | dev_hold(dev); |
249 | ipip_tunnel_link(nt); | 254 | ipip_tunnel_link(ipn, nt); |
250 | return nt; | 255 | return nt; |
251 | 256 | ||
252 | failed_free: | 257 | failed_free: |
@@ -264,7 +269,7 @@ static void ipip_tunnel_uninit(struct net_device *dev) | |||
264 | tunnels_wc[0] = NULL; | 269 | tunnels_wc[0] = NULL; |
265 | write_unlock_bh(&ipip_lock); | 270 | write_unlock_bh(&ipip_lock); |
266 | } else | 271 | } else |
267 | ipip_tunnel_unlink(netdev_priv(dev)); | 272 | ipip_tunnel_unlink(ipn, netdev_priv(dev)); |
268 | dev_put(dev); | 273 | dev_put(dev); |
269 | } | 274 | } |
270 | 275 | ||
@@ -313,7 +318,7 @@ static int ipip_err(struct sk_buff *skb, u32 info) | |||
313 | err = -ENOENT; | 318 | err = -ENOENT; |
314 | 319 | ||
315 | read_lock(&ipip_lock); | 320 | read_lock(&ipip_lock); |
316 | t = ipip_tunnel_lookup(iph->daddr, iph->saddr); | 321 | t = ipip_tunnel_lookup(&init_net, iph->daddr, iph->saddr); |
317 | if (t == NULL || t->parms.iph.daddr == 0) | 322 | if (t == NULL || t->parms.iph.daddr == 0) |
318 | goto out; | 323 | goto out; |
319 | 324 | ||
@@ -473,7 +478,8 @@ static int ipip_rcv(struct sk_buff *skb) | |||
473 | const struct iphdr *iph = ip_hdr(skb); | 478 | const struct iphdr *iph = ip_hdr(skb); |
474 | 479 | ||
475 | read_lock(&ipip_lock); | 480 | read_lock(&ipip_lock); |
476 | if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) { | 481 | if ((tunnel = ipip_tunnel_lookup(&init_net, |
482 | iph->saddr, iph->daddr)) != NULL) { | ||
477 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 483 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
478 | read_unlock(&ipip_lock); | 484 | read_unlock(&ipip_lock); |
479 | kfree_skb(skb); | 485 | kfree_skb(skb); |
@@ -706,7 +712,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
706 | err = -EFAULT; | 712 | err = -EFAULT; |
707 | break; | 713 | break; |
708 | } | 714 | } |
709 | t = ipip_tunnel_locate(&p, 0); | 715 | t = ipip_tunnel_locate(net, &p, 0); |
710 | } | 716 | } |
711 | if (t == NULL) | 717 | if (t == NULL) |
712 | t = netdev_priv(dev); | 718 | t = netdev_priv(dev); |
@@ -732,7 +738,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
732 | if (p.iph.ttl) | 738 | if (p.iph.ttl) |
733 | p.iph.frag_off |= htons(IP_DF); | 739 | p.iph.frag_off |= htons(IP_DF); |
734 | 740 | ||
735 | t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL); | 741 | t = ipip_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL); |
736 | 742 | ||
737 | if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { | 743 | if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { |
738 | if (t != NULL) { | 744 | if (t != NULL) { |
@@ -747,12 +753,12 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
747 | break; | 753 | break; |
748 | } | 754 | } |
749 | t = netdev_priv(dev); | 755 | t = netdev_priv(dev); |
750 | ipip_tunnel_unlink(t); | 756 | ipip_tunnel_unlink(ipn, t); |
751 | t->parms.iph.saddr = p.iph.saddr; | 757 | t->parms.iph.saddr = p.iph.saddr; |
752 | t->parms.iph.daddr = p.iph.daddr; | 758 | t->parms.iph.daddr = p.iph.daddr; |
753 | memcpy(dev->dev_addr, &p.iph.saddr, 4); | 759 | memcpy(dev->dev_addr, &p.iph.saddr, 4); |
754 | memcpy(dev->broadcast, &p.iph.daddr, 4); | 760 | memcpy(dev->broadcast, &p.iph.daddr, 4); |
755 | ipip_tunnel_link(t); | 761 | ipip_tunnel_link(ipn, t); |
756 | netdev_state_change(dev); | 762 | netdev_state_change(dev); |
757 | } | 763 | } |
758 | } | 764 | } |
@@ -785,7 +791,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
785 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) | 791 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) |
786 | goto done; | 792 | goto done; |
787 | err = -ENOENT; | 793 | err = -ENOENT; |
788 | if ((t = ipip_tunnel_locate(&p, 0)) == NULL) | 794 | if ((t = ipip_tunnel_locate(net, &p, 0)) == NULL) |
789 | goto done; | 795 | goto done; |
790 | err = -EPERM; | 796 | err = -EPERM; |
791 | if (t->dev == ipn->fb_tunnel_dev) | 797 | if (t->dev == ipn->fb_tunnel_dev) |