diff options
-rw-r--r-- | drivers/net/tun.c | 56 |
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 | */ | ||
819 | static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
820 | { | ||
821 | return -EINVAL; | ||
822 | } | ||
823 | |||
824 | static 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 | |||
815 | static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | 832 | static 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 | ||
1320 | static int tun_init_net(struct net *net) | ||
1321 | { | ||
1322 | return 0; | ||
1323 | } | ||
1324 | |||
1325 | static 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 | |||
1339 | static struct pernet_operations tun_net_ops = { | ||
1340 | .init = tun_init_net, | ||
1341 | .exit = tun_exit_net, | ||
1342 | }; | ||
1343 | 1338 | ||
1344 | static int __init tun_init(void) | 1339 | static 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 | |||
1364 | err_misc: | 1358 | err_misc: |
1365 | unregister_pernet_device(&tun_net_ops); | 1359 | rtnl_link_unregister(&tun_link_ops); |
1366 | err_pernet: | 1360 | err_linkops: |
1367 | return ret; | 1361 | return ret; |
1368 | } | 1362 | } |
1369 | 1363 | ||
1370 | static void tun_cleanup(void) | 1364 | static 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 | ||
1376 | module_init(tun_init); | 1370 | module_init(tun_init); |