#include <linux/virtio_net.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <net/rtnetlink.h>
#include <asm/system.h>
#include <asm/uaccess.h>
dev->destructor = free_netdev;
}
+/* Trivial set of netlink ops to allow deleting tun or tap
+ * device with netlink.
+ */
+static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ return -EINVAL;
+}
+
+static struct rtnl_link_ops tun_link_ops __read_mostly = {
+ .kind = DRV_NAME,
+ .priv_size = sizeof(struct tun_struct),
+ .setup = tun_setup,
+ .validate = tun_validate,
+};
+
+
static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
struct tun_struct *tun;
return -ENOMEM;
dev_net_set(dev, net);
+ dev->rtnl_link_ops = &tun_link_ops;
tun = netdev_priv(dev);
tun->dev = dev;
.set_rx_csum = tun_set_rx_csum
};
-static int tun_init_net(struct net *net)
-{
- return 0;
-}
-
-static void tun_exit_net(struct net *net)
-{
- struct net_device *dev, *next;
-
- rtnl_lock();
- for_each_netdev_safe(net, dev, next) {
- if (dev->ethtool_ops != &tun_ethtool_ops)
- continue;
- DBG(KERN_INFO "%s cleaned up\n", dev->name);
- unregister_netdevice(dev);
- }
- rtnl_unlock();
-}
-
-static struct pernet_operations tun_net_ops = {
- .init = tun_init_net,
- .exit = tun_exit_net,
-};
static int __init tun_init(void)
{
printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
- ret = register_pernet_device(&tun_net_ops);
+ ret = rtnl_link_register(&tun_link_ops);
if (ret) {
- printk(KERN_ERR "tun: Can't register pernet ops\n");
- goto err_pernet;
+ printk(KERN_ERR "tun: Can't register link_ops\n");
+ goto err_linkops;
}
ret = misc_register(&tun_miscdev);
printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
goto err_misc;
}
- return 0;
-
+ return 0;
err_misc:
- unregister_pernet_device(&tun_net_ops);
-err_pernet:
+ rtnl_link_unregister(&tun_link_ops);
+err_linkops:
return ret;
}
static void tun_cleanup(void)
{
misc_deregister(&tun_miscdev);
- unregister_pernet_device(&tun_net_ops);
+ rtnl_link_unregister(&tun_link_ops);
}
module_init(tun_init);