#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);