[IP6TUNNEL]: Make the fallback tunnel device per-net.
All the code, that reference it already has the ip6_tnl_net pointer, so s/ip6_fb_tnl_dev/ip6n->fb_tnl_dev/ and move creation/releasing code into net init/exit ops. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8704ca7e91
commit
15820e1290
|
@ -82,12 +82,10 @@ static void ip6_tnl_dev_setup(struct net_device *dev);
|
||||||
|
|
||||||
static int ip6_tnl_net_id;
|
static int ip6_tnl_net_id;
|
||||||
struct ip6_tnl_net {
|
struct ip6_tnl_net {
|
||||||
|
/* the IPv6 tunnel fallback device */
|
||||||
|
struct net_device *fb_tnl_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the IPv6 tunnel fallback device */
|
|
||||||
static struct net_device *ip6_fb_tnl_dev;
|
|
||||||
|
|
||||||
|
|
||||||
/* lists for storing tunnels in use */
|
/* lists for storing tunnels in use */
|
||||||
static struct ip6_tnl *tnls_r_l[HASH_SIZE];
|
static struct ip6_tnl *tnls_r_l[HASH_SIZE];
|
||||||
static struct ip6_tnl *tnls_wc[1];
|
static struct ip6_tnl *tnls_wc[1];
|
||||||
|
@ -314,7 +312,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
|
||||||
struct net *net = dev_net(dev);
|
struct net *net = dev_net(dev);
|
||||||
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||||
|
|
||||||
if (dev == ip6_fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
write_lock_bh(&ip6_tnl_lock);
|
write_lock_bh(&ip6_tnl_lock);
|
||||||
tnls_wc[0] = NULL;
|
tnls_wc[0] = NULL;
|
||||||
write_unlock_bh(&ip6_tnl_lock);
|
write_unlock_bh(&ip6_tnl_lock);
|
||||||
|
@ -1209,7 +1207,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETTUNNEL:
|
case SIOCGETTUNNEL:
|
||||||
if (dev == ip6_fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
|
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
|
@ -1236,7 +1234,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
p.proto != 0)
|
p.proto != 0)
|
||||||
break;
|
break;
|
||||||
t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
|
t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
|
||||||
if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
|
if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
if (t->dev != dev) {
|
if (t->dev != dev) {
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
|
@ -1263,7 +1261,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (!capable(CAP_NET_ADMIN))
|
if (!capable(CAP_NET_ADMIN))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dev == ip6_fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
|
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
|
||||||
break;
|
break;
|
||||||
|
@ -1271,7 +1269,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
|
if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
|
||||||
break;
|
break;
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
if (t->dev == ip6_fb_tnl_dev)
|
if (t->dev == ip6n->fb_tnl_dev)
|
||||||
break;
|
break;
|
||||||
dev = t->dev;
|
dev = t->dev;
|
||||||
}
|
}
|
||||||
|
@ -1413,8 +1411,25 @@ static int ip6_tnl_init_net(struct net *net)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_assign;
|
goto err_assign;
|
||||||
|
|
||||||
|
err = -ENOMEM;
|
||||||
|
ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
|
||||||
|
ip6_tnl_dev_setup);
|
||||||
|
|
||||||
|
if (!ip6n->fb_tnl_dev)
|
||||||
|
goto err_alloc_dev;
|
||||||
|
|
||||||
|
ip6n->fb_tnl_dev->init = ip6_fb_tnl_dev_init;
|
||||||
|
dev_net_set(ip6n->fb_tnl_dev, net);
|
||||||
|
|
||||||
|
err = register_netdev(ip6n->fb_tnl_dev);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_register;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_register:
|
||||||
|
free_netdev(ip6n->fb_tnl_dev);
|
||||||
|
err_alloc_dev:
|
||||||
|
/* nothing */
|
||||||
err_assign:
|
err_assign:
|
||||||
kfree(ip6n);
|
kfree(ip6n);
|
||||||
err_alloc:
|
err_alloc:
|
||||||
|
@ -1455,27 +1470,12 @@ static int __init ip6_tunnel_init(void)
|
||||||
err = -EAGAIN;
|
err = -EAGAIN;
|
||||||
goto unreg_ip4ip6;
|
goto unreg_ip4ip6;
|
||||||
}
|
}
|
||||||
ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
|
|
||||||
ip6_tnl_dev_setup);
|
|
||||||
|
|
||||||
if (!ip6_fb_tnl_dev) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
ip6_fb_tnl_dev->init = ip6_fb_tnl_dev_init;
|
|
||||||
|
|
||||||
if ((err = register_netdev(ip6_fb_tnl_dev))) {
|
|
||||||
free_netdev(ip6_fb_tnl_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
|
err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_pernet;
|
goto err_pernet;
|
||||||
return 0;
|
return 0;
|
||||||
err_pernet:
|
err_pernet:
|
||||||
unregister_netdevice(ip6_fb_tnl_dev);
|
|
||||||
fail:
|
|
||||||
xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
|
xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
|
||||||
unreg_ip4ip6:
|
unreg_ip4ip6:
|
||||||
xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
|
xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
|
||||||
|
|
Loading…
Reference in New Issue