struct tun_prog __rcu *steering_prog;
        struct tun_prog __rcu *filter_prog;
        struct ethtool_link_ksettings link_ksettings;
+       /* init args */
+       struct file *file;
+       struct ifreq *ifr;
 };
 
 struct veth {
        __be16 h_vlan_TCI;
 };
 
+static void tun_flow_init(struct tun_struct *tun);
+static void tun_flow_uninit(struct tun_struct *tun);
+
 static int tun_napi_receive(struct napi_struct *napi, int budget)
 {
        struct tun_file *tfile = container_of(napi, struct tun_file, napi);
 
 static const struct ethtool_ops tun_ethtool_ops;
 
+static int tun_net_init(struct net_device *dev)
+{
+       struct tun_struct *tun = netdev_priv(dev);
+       struct ifreq *ifr = tun->ifr;
+       int err;
+
+       dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+       if (!dev->tstats)
+               return -ENOMEM;
+
+       spin_lock_init(&tun->lock);
+
+       err = security_tun_dev_alloc_security(&tun->security);
+       if (err < 0) {
+               free_percpu(dev->tstats);
+               return err;
+       }
+
+       tun_flow_init(tun);
+
+       dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
+                          TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
+                          NETIF_F_HW_VLAN_STAG_TX;
+       dev->features = dev->hw_features | NETIF_F_LLTX;
+       dev->vlan_features = dev->features &
+                            ~(NETIF_F_HW_VLAN_CTAG_TX |
+                              NETIF_F_HW_VLAN_STAG_TX);
+
+       tun->flags = (tun->flags & ~TUN_FEATURES) |
+                     (ifr->ifr_flags & TUN_FEATURES);
+
+       INIT_LIST_HEAD(&tun->disabled);
+       err = tun_attach(tun, tun->file, false, ifr->ifr_flags & IFF_NAPI,
+                        ifr->ifr_flags & IFF_NAPI_FRAGS, false);
+       if (err < 0) {
+               tun_flow_uninit(tun);
+               security_tun_dev_free_security(tun->security);
+               free_percpu(dev->tstats);
+               return err;
+       }
+       return 0;
+}
+
 /* Net device detach from fd. */
 static void tun_net_uninit(struct net_device *dev)
 {
 }
 
 static const struct net_device_ops tun_netdev_ops = {
+       .ndo_init               = tun_net_init,
        .ndo_uninit             = tun_net_uninit,
        .ndo_open               = tun_net_open,
        .ndo_stop               = tun_net_close,
 }
 
 static const struct net_device_ops tap_netdev_ops = {
+       .ndo_init               = tun_net_init,
        .ndo_uninit             = tun_net_uninit,
        .ndo_open               = tun_net_open,
        .ndo_stop               = tun_net_close,
 #define MAX_MTU 65535
 
 /* Initialize net device. */
-static void tun_net_init(struct net_device *dev)
+static void tun_net_initialize(struct net_device *dev)
 {
        struct tun_struct *tun = netdev_priv(dev);
 
        BUG_ON(!(list_empty(&tun->disabled)));
 
        free_percpu(dev->tstats);
-       /* We clear tstats so that tun_set_iff() can tell if
-        * tun_free_netdev() has been called from register_netdevice().
-        */
-       dev->tstats = NULL;
-
        tun_flow_uninit(tun);
        security_tun_dev_free_security(tun->security);
        __tun_set_ebpf(tun, &tun->steering_prog, NULL);
                tun->rx_batched = 0;
                RCU_INIT_POINTER(tun->steering_prog, NULL);
 
-               dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
-               if (!dev->tstats) {
-                       err = -ENOMEM;
-                       goto err_free_dev;
-               }
-
-               spin_lock_init(&tun->lock);
-
-               err = security_tun_dev_alloc_security(&tun->security);
-               if (err < 0)
-                       goto err_free_stat;
-
-               tun_net_init(dev);
-               tun_flow_init(tun);
+               tun->ifr = ifr;
+               tun->file = file;
 
-               dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
-                                  TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
-                                  NETIF_F_HW_VLAN_STAG_TX;
-               dev->features = dev->hw_features | NETIF_F_LLTX;
-               dev->vlan_features = dev->features &
-                                    ~(NETIF_F_HW_VLAN_CTAG_TX |
-                                      NETIF_F_HW_VLAN_STAG_TX);
-
-               tun->flags = (tun->flags & ~TUN_FEATURES) |
-                             (ifr->ifr_flags & TUN_FEATURES);
-
-               INIT_LIST_HEAD(&tun->disabled);
-               err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI,
-                                ifr->ifr_flags & IFF_NAPI_FRAGS, false);
-               if (err < 0)
-                       goto err_free_flow;
+               tun_net_initialize(dev);
 
                err = register_netdevice(tun->dev);
-               if (err < 0)
-                       goto err_detach;
+               if (err < 0) {
+                       free_netdev(dev);
+                       return err;
+               }
                /* free_netdev() won't check refcnt, to avoid race
                 * with dev_put() we need publish tun after registration.
                 */
 
        strcpy(ifr->ifr_name, tun->dev->name);
        return 0;
-
-err_detach:
-       tun_detach_all(dev);
-       /* We are here because register_netdevice() has failed.
-        * If register_netdevice() already called tun_free_netdev()
-        * while dealing with the error, dev->stats has been cleared.
-        */
-       if (!dev->tstats)
-               goto err_free_dev;
-
-err_free_flow:
-       tun_flow_uninit(tun);
-       security_tun_dev_free_security(tun->security);
-err_free_stat:
-       free_percpu(dev->tstats);
-err_free_dev:
-       free_netdev(dev);
-       return err;
 }
 
 static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr)