aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_tunnel.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-04-16 04:22:23 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-16 04:22:23 -0400
commit2dd02c897d798c6a00dca46c7a50ebc10eb3be0d (patch)
tree86e0efd5c26d5e8fe8ae17e5ac5549028750adae /net/ipv6/ip6_tunnel.c
parent13eeb8e92c95ca8a1c044e3692246f884be826ee (diff)
[IP6TUNNEL]: Add (ip6_tnl_)net argument to some calls.
Hashes and fallback device used in them will be per-net. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_tunnel.c')
-rw-r--r--net/ipv6/ip6_tunnel.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2365eb0fb6a4..fad1af8ae1cf 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -136,7 +136,7 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
136 **/ 136 **/
137 137
138static struct ip6_tnl * 138static struct ip6_tnl *
139ip6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local) 139ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
140{ 140{
141 unsigned h0 = HASH(remote); 141 unsigned h0 = HASH(remote);
142 unsigned h1 = HASH(local); 142 unsigned h1 = HASH(local);
@@ -166,7 +166,7 @@ ip6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local)
166 **/ 166 **/
167 167
168static struct ip6_tnl ** 168static struct ip6_tnl **
169ip6_tnl_bucket(struct ip6_tnl_parm *p) 169ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
170{ 170{
171 struct in6_addr *remote = &p->raddr; 171 struct in6_addr *remote = &p->raddr;
172 struct in6_addr *local = &p->laddr; 172 struct in6_addr *local = &p->laddr;
@@ -186,9 +186,9 @@ ip6_tnl_bucket(struct ip6_tnl_parm *p)
186 **/ 186 **/
187 187
188static void 188static void
189ip6_tnl_link(struct ip6_tnl *t) 189ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
190{ 190{
191 struct ip6_tnl **tp = ip6_tnl_bucket(&t->parms); 191 struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms);
192 192
193 t->next = *tp; 193 t->next = *tp;
194 write_lock_bh(&ip6_tnl_lock); 194 write_lock_bh(&ip6_tnl_lock);
@@ -202,11 +202,11 @@ ip6_tnl_link(struct ip6_tnl *t)
202 **/ 202 **/
203 203
204static void 204static void
205ip6_tnl_unlink(struct ip6_tnl *t) 205ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
206{ 206{
207 struct ip6_tnl **tp; 207 struct ip6_tnl **tp;
208 208
209 for (tp = ip6_tnl_bucket(&t->parms); *tp; tp = &(*tp)->next) { 209 for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) {
210 if (t == *tp) { 210 if (t == *tp) {
211 write_lock_bh(&ip6_tnl_lock); 211 write_lock_bh(&ip6_tnl_lock);
212 *tp = t->next; 212 *tp = t->next;
@@ -228,12 +228,13 @@ ip6_tnl_unlink(struct ip6_tnl *t)
228 * created tunnel or NULL 228 * created tunnel or NULL
229 **/ 229 **/
230 230
231static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) 231static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
232{ 232{
233 struct net_device *dev; 233 struct net_device *dev;
234 struct ip6_tnl *t; 234 struct ip6_tnl *t;
235 char name[IFNAMSIZ]; 235 char name[IFNAMSIZ];
236 int err; 236 int err;
237 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
237 238
238 if (p->name[0]) 239 if (p->name[0])
239 strlcpy(name, p->name, IFNAMSIZ); 240 strlcpy(name, p->name, IFNAMSIZ);
@@ -257,7 +258,7 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
257 goto failed_free; 258 goto failed_free;
258 259
259 dev_hold(dev); 260 dev_hold(dev);
260 ip6_tnl_link(t); 261 ip6_tnl_link(ip6n, t);
261 return t; 262 return t;
262 263
263failed_free: 264failed_free:
@@ -280,20 +281,22 @@ failed:
280 * matching tunnel or NULL 281 * matching tunnel or NULL
281 **/ 282 **/
282 283
283static struct ip6_tnl *ip6_tnl_locate(struct ip6_tnl_parm *p, int create) 284static struct ip6_tnl *ip6_tnl_locate(struct net *net,
285 struct ip6_tnl_parm *p, int create)
284{ 286{
285 struct in6_addr *remote = &p->raddr; 287 struct in6_addr *remote = &p->raddr;
286 struct in6_addr *local = &p->laddr; 288 struct in6_addr *local = &p->laddr;
287 struct ip6_tnl *t; 289 struct ip6_tnl *t;
290 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
288 291
289 for (t = *ip6_tnl_bucket(p); t; t = t->next) { 292 for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) {
290 if (ipv6_addr_equal(local, &t->parms.laddr) && 293 if (ipv6_addr_equal(local, &t->parms.laddr) &&
291 ipv6_addr_equal(remote, &t->parms.raddr)) 294 ipv6_addr_equal(remote, &t->parms.raddr))
292 return t; 295 return t;
293 } 296 }
294 if (!create) 297 if (!create)
295 return NULL; 298 return NULL;
296 return ip6_tnl_create(p); 299 return ip6_tnl_create(net, p);
297} 300}
298 301
299/** 302/**
@@ -308,13 +311,15 @@ static void
308ip6_tnl_dev_uninit(struct net_device *dev) 311ip6_tnl_dev_uninit(struct net_device *dev)
309{ 312{
310 struct ip6_tnl *t = netdev_priv(dev); 313 struct ip6_tnl *t = netdev_priv(dev);
314 struct net *net = dev_net(dev);
315 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
311 316
312 if (dev == ip6_fb_tnl_dev) { 317 if (dev == ip6_fb_tnl_dev) {
313 write_lock_bh(&ip6_tnl_lock); 318 write_lock_bh(&ip6_tnl_lock);
314 tnls_wc[0] = NULL; 319 tnls_wc[0] = NULL;
315 write_unlock_bh(&ip6_tnl_lock); 320 write_unlock_bh(&ip6_tnl_lock);
316 } else { 321 } else {
317 ip6_tnl_unlink(t); 322 ip6_tnl_unlink(ip6n, t);
318 } 323 }
319 ip6_tnl_dst_reset(t); 324 ip6_tnl_dst_reset(t);
320 dev_put(dev); 325 dev_put(dev);
@@ -407,7 +412,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
407 processing of the error. */ 412 processing of the error. */
408 413
409 read_lock(&ip6_tnl_lock); 414 read_lock(&ip6_tnl_lock);
410 if ((t = ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL) 415 if ((t = ip6_tnl_lookup(&init_net, &ipv6h->daddr,
416 &ipv6h->saddr)) == NULL)
411 goto out; 417 goto out;
412 418
413 if (t->parms.proto != ipproto && t->parms.proto != 0) 419 if (t->parms.proto != ipproto && t->parms.proto != 0)
@@ -690,7 +696,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
690 696
691 read_lock(&ip6_tnl_lock); 697 read_lock(&ip6_tnl_lock);
692 698
693 if ((t = ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { 699 if ((t = ip6_tnl_lookup(&init_net, &ipv6h->saddr,
700 &ipv6h->daddr)) != NULL) {
694 if (t->parms.proto != ipproto && t->parms.proto != 0) { 701 if (t->parms.proto != ipproto && t->parms.proto != 0) {
695 read_unlock(&ip6_tnl_lock); 702 read_unlock(&ip6_tnl_lock);
696 goto discard; 703 goto discard;
@@ -1197,6 +1204,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1197 int err = 0; 1204 int err = 0;
1198 struct ip6_tnl_parm p; 1205 struct ip6_tnl_parm p;
1199 struct ip6_tnl *t = NULL; 1206 struct ip6_tnl *t = NULL;
1207 struct net *net = dev_net(dev);
1208 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1200 1209
1201 switch (cmd) { 1210 switch (cmd) {
1202 case SIOCGETTUNNEL: 1211 case SIOCGETTUNNEL:
@@ -1205,7 +1214,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1205 err = -EFAULT; 1214 err = -EFAULT;
1206 break; 1215 break;
1207 } 1216 }
1208 t = ip6_tnl_locate(&p, 0); 1217 t = ip6_tnl_locate(net, &p, 0);
1209 } 1218 }
1210 if (t == NULL) 1219 if (t == NULL)
1211 t = netdev_priv(dev); 1220 t = netdev_priv(dev);
@@ -1226,7 +1235,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1226 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP && 1235 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
1227 p.proto != 0) 1236 p.proto != 0)
1228 break; 1237 break;
1229 t = ip6_tnl_locate(&p, cmd == SIOCADDTUNNEL); 1238 t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
1230 if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) { 1239 if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
1231 if (t != NULL) { 1240 if (t != NULL) {
1232 if (t->dev != dev) { 1241 if (t->dev != dev) {
@@ -1236,9 +1245,9 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1236 } else 1245 } else
1237 t = netdev_priv(dev); 1246 t = netdev_priv(dev);
1238 1247
1239 ip6_tnl_unlink(t); 1248 ip6_tnl_unlink(ip6n, t);
1240 err = ip6_tnl_change(t, &p); 1249 err = ip6_tnl_change(t, &p);
1241 ip6_tnl_link(t); 1250 ip6_tnl_link(ip6n, t);
1242 netdev_state_change(dev); 1251 netdev_state_change(dev);
1243 } 1252 }
1244 if (t) { 1253 if (t) {
@@ -1259,7 +1268,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1259 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) 1268 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
1260 break; 1269 break;
1261 err = -ENOENT; 1270 err = -ENOENT;
1262 if ((t = ip6_tnl_locate(&p, 0)) == NULL) 1271 if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
1263 break; 1272 break;
1264 err = -EPERM; 1273 err = -EPERM;
1265 if (t->dev == ip6_fb_tnl_dev) 1274 if (t->dev == ip6_fb_tnl_dev)