aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2009-01-21 19:02:16 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 19:02:16 -0500
commitf019a7a594d951f085eb3878c3d825556d447efe (patch)
tree9abbe6c51ef39a4b9ab3b06dbc71c415ca443b4e /drivers
parentaec191aa2a04b082238156dc9690fff8ce95dd6b (diff)
tun: Implement ip link del tunXXX
This greatly simplifies testing to verify I have fixed the problems with a tun device disappearing when the tun file descriptor is still held open. Further it allows removal network namespace operations for the tun driver. Reducing the network namespace handling in the driver to the minimum. i.e. When we are creating a tun device. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tun.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 97b050015f5e..e9bcbdfe015a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -63,6 +63,7 @@
63#include <linux/virtio_net.h> 63#include <linux/virtio_net.h>
64#include <net/net_namespace.h> 64#include <net/net_namespace.h>
65#include <net/netns/generic.h> 65#include <net/netns/generic.h>
66#include <net/rtnetlink.h>
66 67
67#include <asm/system.h> 68#include <asm/system.h>
68#include <asm/uaccess.h> 69#include <asm/uaccess.h>
@@ -812,6 +813,22 @@ static void tun_setup(struct net_device *dev)
812 dev->destructor = free_netdev; 813 dev->destructor = free_netdev;
813} 814}
814 815
816/* Trivial set of netlink ops to allow deleting tun or tap
817 * device with netlink.
818 */
819static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
820{
821 return -EINVAL;
822}
823
824static struct rtnl_link_ops tun_link_ops __read_mostly = {
825 .kind = DRV_NAME,
826 .priv_size = sizeof(struct tun_struct),
827 .setup = tun_setup,
828 .validate = tun_validate,
829};
830
831
815static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) 832static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
816{ 833{
817 struct tun_struct *tun; 834 struct tun_struct *tun;
@@ -861,6 +878,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
861 return -ENOMEM; 878 return -ENOMEM;
862 879
863 dev_net_set(dev, net); 880 dev_net_set(dev, net);
881 dev->rtnl_link_ops = &tun_link_ops;
864 882
865 tun = netdev_priv(dev); 883 tun = netdev_priv(dev);
866 tun->dev = dev; 884 tun->dev = dev;
@@ -1317,29 +1335,6 @@ static const struct ethtool_ops tun_ethtool_ops = {
1317 .set_rx_csum = tun_set_rx_csum 1335 .set_rx_csum = tun_set_rx_csum
1318}; 1336};
1319 1337
1320static int tun_init_net(struct net *net)
1321{
1322 return 0;
1323}
1324
1325static void tun_exit_net(struct net *net)
1326{
1327 struct net_device *dev, *next;
1328
1329 rtnl_lock();
1330 for_each_netdev_safe(net, dev, next) {
1331 if (dev->ethtool_ops != &tun_ethtool_ops)
1332 continue;
1333 DBG(KERN_INFO "%s cleaned up\n", dev->name);
1334 unregister_netdevice(dev);
1335 }
1336 rtnl_unlock();
1337}
1338
1339static struct pernet_operations tun_net_ops = {
1340 .init = tun_init_net,
1341 .exit = tun_exit_net,
1342};
1343 1338
1344static int __init tun_init(void) 1339static int __init tun_init(void)
1345{ 1340{
@@ -1348,10 +1343,10 @@ static int __init tun_init(void)
1348 printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 1343 printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
1349 printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT); 1344 printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
1350 1345
1351 ret = register_pernet_device(&tun_net_ops); 1346 ret = rtnl_link_register(&tun_link_ops);
1352 if (ret) { 1347 if (ret) {
1353 printk(KERN_ERR "tun: Can't register pernet ops\n"); 1348 printk(KERN_ERR "tun: Can't register link_ops\n");
1354 goto err_pernet; 1349 goto err_linkops;
1355 } 1350 }
1356 1351
1357 ret = misc_register(&tun_miscdev); 1352 ret = misc_register(&tun_miscdev);
@@ -1359,18 +1354,17 @@ static int __init tun_init(void)
1359 printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR); 1354 printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
1360 goto err_misc; 1355 goto err_misc;
1361 } 1356 }
1362 return 0; 1357 return 0;
1363
1364err_misc: 1358err_misc:
1365 unregister_pernet_device(&tun_net_ops); 1359 rtnl_link_unregister(&tun_link_ops);
1366err_pernet: 1360err_linkops:
1367 return ret; 1361 return ret;
1368} 1362}
1369 1363
1370static void tun_cleanup(void) 1364static void tun_cleanup(void)
1371{ 1365{
1372 misc_deregister(&tun_miscdev); 1366 misc_deregister(&tun_miscdev);
1373 unregister_pernet_device(&tun_net_ops); 1367 rtnl_link_unregister(&tun_link_ops);
1374} 1368}
1375 1369
1376module_init(tun_init); 1370module_init(tun_init);