Author: kevans
Date: Fri Oct 25 01:10:08 2019
New Revision: 354060
URL: https://svnweb.freebsd.org/changeset/base/354060

Log:
  MFC tun/tap merge: r347241, r347394, r347404, r347483, r351220, r351229,
  r352148, r353056-r353057, r353781-r353782, r353785-r353786, r353877
  
  Note: A little more than just the tun/tap merge has been MFC'd to ease
  auditing correctness/differences, as some later commits were cherry-picked
  back to tun+tap.
  
  r347241:
  tun/tap: merge and rename to `tuntap`
  
  tun(4) and tap(4) share the same general management interface and have a lot
  in common. Bugs exist in tap(4) that have been fixed in tun(4), and
  vice-versa. Let's reduce the maintenance requirements by merging them
  together and using flags to differentiate between the three interface types
  (tun, tap, vmnet).
  
  This fixes a couple of tap(4)/vmnet(4) issues right out of the gate:
  - tap devices may no longer be destroyed while they're open [0]
  - VIMAGE issues already addressed in tun by kp
  
  [0] emaste had removed an easy-panic-button in r240938 due to devdrn
  blocking. A naive glance over this leads me to believe that this isn't quite
  complete -- destroy_devl will only block while executing d_* functions, but
  doesn't block the device from being destroyed while a process has it open.
  The latter is the intent of the condvar in tun, so this is "fixed" (for
  certain definitions of the word -- it wasn't really broken in tap, it just
  wasn't quite ideal).
  
  ifconfig(8) also grew the ability to map an interface name to a kld, so
  that `ifconfig {tun,tap}0` can continue to autoload the correct module, and
  `ifconfig vmnet0 create` will now autoload the correct module. This is a
  low overhead addition.
  
  r347394:
  tuntap: Properly detach tap ifp
  
  r347404:
  tuntap: Don't down tap interfaces if LINK0 is set
  
  r347483:
  tuntap: Improve style
  
  No functional change.
  
  tun_flags of the tuntap_driver was renamed to ident_flags to reflect the
  fact that it's a subset of the tun_flags that identifies a tuntap device.
  This maps more easily (visually) to the TUN_DRIVER_IDENT_MASK that masks off
  the bits of tun_flags that are applicable to tuntap driver ident. This is a
  purely cosmetic change.
  
  r351220:
  if_tuntap: minor improvements
  
  Rewrite a loop to avoid duplicating the exit condition.
  Simplify mask processing in tunpoll().
  Fix minor typos.
  
  r351229:
  tuntap: belatedly add MODULE_VERSION for if_tun and if_tap
  
  When tun/tap were merged, appropriate MODULE_VERSION should have been added
  for things like modfind(2) to continue to do the right thing with the old
  names.
  
  r352148:
  Remove empty tap/tun modules directories after r347241
  
  r353056:
  if_tuntap: add a busy/unbusy mechanism, replace destroy OPEN check
  
  A future commit will create device aliases when a tuntap device is renamed
  so that it's still easily found in /dev after the rename.  Said mechanism
  will want to keep the tun alive long enough to either realize that it's
  about to go away or complete the alias creation, even if the alias is about
  to get destroyed.
  
  While we're introducing it, using it to prevent open devices from going away
  makes plenty of sense and keeps the logic on waking up tun_destroy clean, so
  we don't have multiple places trying to cv_broadcast unless it's still in
  use elsewhere.
  
  r353057:
  if_tuntap: create /dev aliases when a tuntap device gets renamed
  
  Currently, if you do:
  
  $ ifconfig tun0 create
  $ ifconfig tun0 name wg0
  $ ls -l /dev | egrep 'wg|tun'
  
  You will see tun0, but no wg0. In fact, it's slightly more annoying to make
  the association between the new name and the old name in order to open the
  device (if it hadn't been opened during the rename).
  
  Register an eventhandler for ifnet_arrival_events and catch interface
  renames. We can determine if the ifnet is a tun easily enough from the
  if_dname, which matches the cevsw.d_name from the associated tuntap_driver.
  
  Some locking dance is required because renames don't require the device to
  be opened, so it could go away in the middle of handling the ioctl, but as
  soon as we've verified this isn't the case we can attempt to busy the tun
  and either bail out if the tun device is dying, or we can proceed with the
  rename.
  
  We only create these aliases on a best-effort basis. Renaming a tun device
  to "usbctl", which doesn't exist as an ifnet but does as a /dev, is clearly
  not that disastrous, but we can't and won't create a /dev for that.
  
  r353781:
  tuntap(4): Drop TUN_IASET
  
  This flag appears to have been effectively unused since introduction to
  if_tun(4) -- drop it now.
  
  r353782:
  tuntap(4): break out after setting TUN_DSTADDR
  
  This is now the only flag we set in this loop, terminate early.
  
  r353785:
  tuntap(4): Use make_dev_s to avoid si_drv1 race
  
  This allows us to avoid some dance in tunopen for dealing with the
  possibility of dev->si_drv1 being NULL as it's set prior to the devfs node
  being created in all cases.
  
  There's still the possibility that the tun device hasn't been fully
  initialized, since that's done after the devfs node was created. Alleviate
  this by returning ENXIO if we're not to that point of tuncreate yet.
  
  This work is what sparked r353128, full initialization of cloned devices
  w/ specified make_dev_args.
  
  r353786:
  tuntap(4): use cdevpriv w/ dtor for last close instead of d_close
  
  cdevpriv dtors will be called when the reference count on the associated
  struct file drops to 0, while d_close can be unreliable for cleaning up
  state at "last close" for a number of reasons. As far as tunclose/tundtor is
  concerned the difference is minimal, so make the switch.
  
  r353877:
  tuntap(4): properly declare if_tun and if_tap modules
  
  Simply adding MODULE_VERSION does not do the trick, because the modules
  haven't been declared. This should actually fix modfind/kldstat, which
  r351229 aimed and failed to do.
  
  This should make vm-bhyve do the right thing again when using the ports
  version, rather than the latest version not in ports.
  
  Relnotes:     yes

Added:
  stable/12/sys/modules/if_tuntap/
     - copied from r347241, head/sys/modules/if_tuntap/
  stable/12/sys/net/if_tuntap.c
     - copied, changed from r354059, stable/12/sys/net/if_tun.c
Deleted:
  stable/12/sys/modules/if_tap/
  stable/12/sys/modules/if_tun/
  stable/12/sys/net/if_tap.c
  stable/12/sys/net/if_tapvar.h
  stable/12/sys/net/if_tun.c
Modified:
  stable/12/UPDATING
  stable/12/sbin/ifconfig/ifconfig.c
  stable/12/share/man/man4/tap.4
  stable/12/share/man/man4/tun.4
  stable/12/sys/amd64/conf/GENERIC
  stable/12/sys/amd64/conf/MINIMAL
  stable/12/sys/arm/conf/DOCKSTAR
  stable/12/sys/arm/conf/DREAMPLUG-1001
  stable/12/sys/arm/conf/EFIKA_MX
  stable/12/sys/arm/conf/IMX53
  stable/12/sys/arm/conf/IMX6
  stable/12/sys/arm/conf/TEGRA124
  stable/12/sys/arm64/conf/GENERIC
  stable/12/sys/conf/NOTES
  stable/12/sys/conf/files
  stable/12/sys/i386/conf/GENERIC
  stable/12/sys/mips/conf/ERL
  stable/12/sys/mips/conf/OCTEON1
  stable/12/sys/modules/Makefile
  stable/12/sys/modules/if_tuntap/Makefile
  stable/12/sys/net/if_tap.h
  stable/12/sys/powerpc/conf/GENERIC
  stable/12/sys/powerpc/conf/GENERIC64
  stable/12/sys/powerpc/conf/MPC85XX
  stable/12/sys/powerpc/conf/MPC85XXSPE
  stable/12/sys/powerpc/conf/QORIQ64
  stable/12/sys/riscv/conf/GENERIC
  stable/12/sys/sparc64/conf/GENERIC
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/UPDATING
==============================================================================
--- stable/12/UPDATING  Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/UPDATING  Fri Oct 25 01:10:08 2019        (r354060)
@@ -16,6 +16,14 @@ from older versions of FreeBSD, try WITHOUT_CLANG and 
 the tip of head, and then rebuild without this option. The bootstrap process
 from older version of current across the gcc/clang cutover is a bit fragile.
 
+20191024:
+       The tap(4) driver has been folded into tun(4), and the module has been
+       renamed to tuntap.  You should update any kld_load="if_tap" or
+       kld_load="if_tun" entries in /etc/rc.conf, if_tap_load="YES" or
+       if_tun_load="YES" entries in /boot/loader.conf to load the if_tuntap
+       module instead, and "device tap" or "device tun" entries in kernel
+       config files to select the tuntap device instead.
+
 20190913:
        ntpd no longer by default locks its pages in memory, allowing them
        to be paged out by the kernel. Use rlimit memlock to restore

Modified: stable/12/sbin/ifconfig/ifconfig.c
==============================================================================
--- stable/12/sbin/ifconfig/ifconfig.c  Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sbin/ifconfig/ifconfig.c  Fri Oct 25 01:10:08 2019        
(r354060)
@@ -136,8 +136,16 @@ static struct module_map_entry {
        const char *kldname;
 } module_map[] = {
        {
+               .ifname = "tun",
+               .kldname = "if_tuntap",
+       },
+       {
+               .ifname = "tap",
+               .kldname = "if_tuntap",
+       },
+       {
                .ifname = "vmnet",
-               .kldname = "if_tap",
+               .kldname = "if_tuntap",
        },
        {
                .ifname = "ipsec",

Modified: stable/12/share/man/man4/tap.4
==============================================================================
--- stable/12/share/man/man4/tap.4      Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/share/man/man4/tap.4      Fri Oct 25 01:10:08 2019        
(r354060)
@@ -1,14 +1,14 @@
 .\" $FreeBSD$
 .\" Based on PR#2411
 .\"
-.Dd November 29, 2017
+.Dd April 29, 2019
 .Dt TAP 4
 .Os
 .Sh NAME
 .Nm tap
 .Nd Ethernet tunnel software network interface
 .Sh SYNOPSIS
-.Cd device tap
+.Cd device tuntap
 .Sh DESCRIPTION
 The
 .Nm
@@ -51,7 +51,7 @@ The network interfaces are named
 .Dq Li tap1 ,
 etc., one for each control device that has been opened.
 These Ethernet network interfaces persist until
-.Pa if_tap.ko
+.Pa if_tuntap.ko
 module is unloaded, or until removed with "ifconfig destroy" (see below).
 .Pp
 .Nm
@@ -96,7 +96,7 @@ It therefore defaults to being enabled until further n
 .Ef
 .Pp
 Control devices (once successfully opened) persist until
-.Pa if_tap.ko
+.Pa if_tuntap.ko
 is unloaded or the interface is destroyed.
 .Pp
 Each interface supports the usual Ethernet network interface
@@ -296,27 +296,6 @@ device can also be used with the VMware port as a repl
 for the old
 .Em VMnet
 device driver.
-The driver uses the minor number
-to select between
-.Nm
-and
-.Nm vmnet
-devices.
-.Em VMnet
-minor numbers begin at
-.Va 0x800000
-+
-.Va N ;
-where
-.Va N
-is a
-.Em VMnet
-unit number.
-In this case the control device is expected to be
-.Pa /dev/vmnet Ns Sy N ,
-and the network interface will be
-.Sy vmnet Ns Ar N .
-Additionally,
 .Em VMnet
 devices do not
 .Xr ifconfig 8

Modified: stable/12/share/man/man4/tun.4
==============================================================================
--- stable/12/share/man/man4/tun.4      Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/share/man/man4/tun.4      Fri Oct 25 01:10:08 2019        
(r354060)
@@ -2,14 +2,14 @@
 .\" $FreeBSD$
 .\" Based on PR#2411
 .\"
-.Dd November 29, 2017
+.Dd April 29, 2019
 .Dt TUN 4
 .Os
 .Sh NAME
 .Nm tun
 .Nd tunnel software network interface
 .Sh SYNOPSIS
-.Cd device tun
+.Cd device tuntap
 .Sh DESCRIPTION
 The
 .Nm
@@ -52,7 +52,7 @@ The network interfaces are named
 .Dq Li tun1 ,
 etc., one for each control device that has been opened.
 These network interfaces persist until the
-.Pa if_tun.ko
+.Pa if_tuntap.ko
 module is unloaded, or until removed with the
 .Xr ifconfig 8
 command.
@@ -99,7 +99,7 @@ It therefore defaults to being enabled until further n
 .Ef
 .Pp
 Control devices (once successfully opened) persist until
-.Pa if_tun.ko
+.Pa if_tuntap.ko
 is unloaded in the same way that network interfaces persist (see above).
 .Pp
 Each interface supports the usual network-interface

Modified: stable/12/sys/amd64/conf/GENERIC
==============================================================================
--- stable/12/sys/amd64/conf/GENERIC    Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/amd64/conf/GENERIC    Fri Oct 25 01:10:08 2019        
(r354060)
@@ -308,7 +308,7 @@ device              padlock_rng             # VIA Padlock 
RNG
 device         rdrand_rng              # Intel Bull Mountain RNG
 device         ether                   # Ethernet support
 device         vlan                    # 802.1Q VLAN support
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         md                      # Memory "disks"
 device         gif                     # IPv6 and IPv4 tunneling
 device         firmware                # firmware assist module

Modified: stable/12/sys/amd64/conf/MINIMAL
==============================================================================
--- stable/12/sys/amd64/conf/MINIMAL    Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/amd64/conf/MINIMAL    Fri Oct 25 01:10:08 2019        
(r354060)
@@ -125,7 +125,7 @@ device              padlock_rng             # VIA Padlock 
RNG
 device         rdrand_rng              # Intel Bull Mountain RNG
 device         ether                   # Ethernet support
 device         vlan                    # 802.1Q VLAN support
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         gif                     # IPv6 and IPv4 tunneling
 
 # The `bpf' device enables the Berkeley Packet Filter.

Modified: stable/12/sys/arm/conf/DOCKSTAR
==============================================================================
--- stable/12/sys/arm/conf/DOCKSTAR     Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm/conf/DOCKSTAR     Fri Oct 25 01:10:08 2019        
(r354060)
@@ -69,7 +69,7 @@ device                loop                    # Network 
loopback
 device         md                      # Memory/malloc disk
 device         pty                     # BSD-style compatibility pseudo ttys
 device         random                  # Entropy device
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         ether                   # Required for all ethernet devices
 device         vlan                    # 802.1Q VLAN support
 device         wlan                    # 802.11 WLAN support

Modified: stable/12/sys/arm/conf/DREAMPLUG-1001
==============================================================================
--- stable/12/sys/arm/conf/DREAMPLUG-1001       Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm/conf/DREAMPLUG-1001       Fri Oct 25 01:10:08 2019        
(r354060)
@@ -72,7 +72,7 @@ device                loop                    # Network 
loopback
 device         md                      # Memory/malloc disk
 device         pty                     # BSD-style compatibility pseudo ttys
 device         random                  # Entropy device
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         ether                   # Required for all ethernet devices
 device         vlan                    # 802.1Q VLAN support
 device         wlan                    # 802.11 WLAN support

Modified: stable/12/sys/arm/conf/EFIKA_MX
==============================================================================
--- stable/12/sys/arm/conf/EFIKA_MX     Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm/conf/EFIKA_MX     Fri Oct 25 01:10:08 2019        
(r354060)
@@ -60,7 +60,7 @@ device                loop                    # Network 
loopback
 device         random                  # Entropy device
 device         ether                   # Ethernet support
 #device                vlan                    # 802.1Q VLAN support
-#device                tun                     # Packet tunnel.
+#device                tuntap                  # Packet tunnel.
 #device                md                      # Memory "disks"
 #device                gif                     # IPv6 and IPv4 tunneling
 #device                firmware                # firmware assist module

Modified: stable/12/sys/arm/conf/IMX53
==============================================================================
--- stable/12/sys/arm/conf/IMX53        Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm/conf/IMX53        Fri Oct 25 01:10:08 2019        
(r354060)
@@ -47,7 +47,7 @@ device                loop                    # Network 
loopback
 device         random                  # Entropy device
 device         ether                   # Ethernet support
 #device                vlan                    # 802.1Q VLAN support
-#device                tun                     # Packet tunnel.
+#device                tuntap                  # Packet tunnel.
 device         md                      # Memory "disks"
 #device                gif                     # IPv6 and IPv4 tunneling
 #device                firmware                # firmware assist module

Modified: stable/12/sys/arm/conf/IMX6
==============================================================================
--- stable/12/sys/arm/conf/IMX6 Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/sys/arm/conf/IMX6 Fri Oct 25 01:10:08 2019        (r354060)
@@ -51,7 +51,7 @@ device                mpcore_timer
 device         loop                    # Network loopback
 device         random                  # Entropy device
 device         vlan                    # 802.1Q VLAN support
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         md                      # Memory "disks"
 #device                gif                     # IPv6 and IPv4 tunneling
 #device                firmware                # firmware assist module

Modified: stable/12/sys/arm/conf/TEGRA124
==============================================================================
--- stable/12/sys/arm/conf/TEGRA124     Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm/conf/TEGRA124     Fri Oct 25 01:10:08 2019        
(r354060)
@@ -45,7 +45,7 @@ device                regulator
 device         loop                    # Network loopback
 device         random                  # Entropy device
 device         vlan                    # 802.1Q VLAN support
-#device                tun                     # Packet tunnel.
+#device                tuntap                  # Packet tunnel.
 device         md                      # Memory "disks"
 #device                gif                     # IPv6 and IPv4 tunneling
 device         firmware                # firmware assist module

Modified: stable/12/sys/arm64/conf/GENERIC
==============================================================================
--- stable/12/sys/arm64/conf/GENERIC    Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/arm64/conf/GENERIC    Fri Oct 25 01:10:08 2019        
(r354060)
@@ -271,7 +271,7 @@ device              loop            # Network loopback
 device         random          # Entropy device
 device         ether           # Ethernet support
 device         vlan            # 802.1Q VLAN support
-device         tun             # Packet tunnel.
+device         tuntap          # Packet tunnel.
 device         md              # Memory "disks"
 device         gif             # IPv6 and IPv4 tunneling
 device         firmware        # firmware assist module

Modified: stable/12/sys/conf/NOTES
==============================================================================
--- stable/12/sys/conf/NOTES    Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/sys/conf/NOTES    Fri Oct 25 01:10:08 2019        (r354060)
@@ -895,11 +895,9 @@ device             epair
 #  which discards all packets sent and receives none.
 device         edsc
 
-#  The `tap' device is a pty-like virtual Ethernet interface
-device         tap
-
-#  The `tun' device implements (user-)ppp and nos-tun(8)
-device         tun
+#  The `tuntap' device implements (user-)ppp, nos-tun(8) and a pty-like virtual
+#  Ethernet interface
+device         tuntap
 
 #  The `gif' device implements IPv6 over IP4 tunneling,
 #  IPv4 over IPv6 tunneling, IPv4 over IPv4 tunneling and

Modified: stable/12/sys/conf/files
==============================================================================
--- stable/12/sys/conf/files    Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/sys/conf/files    Fri Oct 25 01:10:08 2019        (r354060)
@@ -4152,8 +4152,7 @@ net/if_mib.c                      standard
 net/if_spppfr.c                        optional sppp | netgraph_sppp
 net/if_spppsubr.c              optional sppp | netgraph_sppp
 net/if_stf.c                   optional stf inet inet6
-net/if_tun.c                   optional tun
-net/if_tap.c                   optional tap
+net/if_tuntap.c                        optional tuntap
 net/if_vlan.c                  optional vlan
 net/if_vxlan.c                 optional vxlan inet | vxlan inet6
 net/ifdi_if.m                  optional ether pci iflib

Modified: stable/12/sys/i386/conf/GENERIC
==============================================================================
--- stable/12/sys/i386/conf/GENERIC     Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/i386/conf/GENERIC     Fri Oct 25 01:10:08 2019        
(r354060)
@@ -309,7 +309,7 @@ device              padlock_rng             # VIA Padlock 
RNG
 device         rdrand_rng              # Intel Bull Mountain RNG
 device         ether                   # Ethernet support
 device         vlan                    # 802.1Q VLAN support
-device         tun                     # Packet tunnel.
+device         tuntap                  # Packet tunnel.
 device         md                      # Memory "disks"
 device         gif                     # IPv6 and IPv4 tunneling
 device         firmware                # firmware assist module

Modified: stable/12/sys/mips/conf/ERL
==============================================================================
--- stable/12/sys/mips/conf/ERL Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/sys/mips/conf/ERL Fri Oct 25 01:10:08 2019        (r354060)
@@ -151,7 +151,7 @@ device              loop            # Network loopback
 device         random          # Entropy device
 device         ether           # Ethernet support
 device         vlan            # 802.1Q VLAN support
-device         tun             # Packet tunnel.
+device         tuntap          # Packet tunnel.
 device         md              # Memory "disks"
 device         gif             # IPv6 and IPv4 tunneling
 device         firmware        # firmware assist module

Modified: stable/12/sys/mips/conf/OCTEON1
==============================================================================
--- stable/12/sys/mips/conf/OCTEON1     Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/mips/conf/OCTEON1     Fri Oct 25 01:10:08 2019        
(r354060)
@@ -256,7 +256,7 @@ device              loop            # Network loopback
 device         random          # Entropy device
 device         ether           # Ethernet support
 device         vlan            # 802.1Q VLAN support
-device         tun             # Packet tunnel.
+device         tuntap          # Packet tunnel.
 device         md              # Memory "disks"
 device         gif             # IPv6 and IPv4 tunneling
 device         firmware        # firmware assist module

Modified: stable/12/sys/modules/Makefile
==============================================================================
--- stable/12/sys/modules/Makefile      Fri Oct 25 00:47:37 2019        
(r354059)
+++ stable/12/sys/modules/Makefile      Fri Oct 25 01:10:08 2019        
(r354060)
@@ -170,8 +170,7 @@ SUBDIR=     \
        if_lagg \
        ${_if_ndis} \
        ${_if_stf} \
-       if_tap \
-       if_tun \
+       if_tuntap \
        if_vlan \
        if_vxlan \
        iflib \

Modified: stable/12/sys/modules/if_tuntap/Makefile
==============================================================================
--- head/sys/modules/if_tuntap/Makefile Wed May  8 02:32:11 2019        
(r347241)
+++ stable/12/sys/modules/if_tuntap/Makefile    Fri Oct 25 01:10:08 2019        
(r354060)
@@ -31,5 +31,4 @@ alias_debug: .PHONY
 .endif
 .endif
 
-
 .include <bsd.kmod.mk>

Modified: stable/12/sys/net/if_tap.h
==============================================================================
--- stable/12/sys/net/if_tap.h  Fri Oct 25 00:47:37 2019        (r354059)
+++ stable/12/sys/net/if_tap.h  Fri Oct 25 01:10:08 2019        (r354060)
@@ -40,24 +40,22 @@
 #ifndef _NET_IF_TAP_H_
 #define _NET_IF_TAP_H_
 
-/* refer to if_tapvar.h for the softc stuff */
+#include <net/if_tun.h>
 
 /* maximum receive packet size (hard limit) */
 #define        TAPMRU          16384
 
-struct tapinfo {
-       int     baudrate;       /* linespeed                 */
-       short   mtu;            /* maximum transmission unit */
-       u_char  type;           /* ethernet, tokenring, etc. */
-       u_char  dummy;          /* place holder              */
-};
+#define        tapinfo         tuninfo
 
-/* ioctl's for get/set debug */
-#define        TAPSDEBUG               _IOW('t', 90, int)
-#define        TAPGDEBUG               _IOR('t', 89, int)
-#define        TAPSIFINFO              _IOW('t', 91, struct tapinfo)
-#define        TAPGIFINFO              _IOR('t', 92, struct tapinfo)
-#define        TAPGIFNAME              _IOR('t', 93, struct ifreq)
+/*
+ * ioctl's for get/set debug; these are aliases of TUN* ioctls, see 
net/if_tun.h
+ * for details.
+ */
+#define        TAPSDEBUG               TUNSDEBUG
+#define        TAPGDEBUG               TUNGDEBUG
+#define        TAPSIFINFO              TUNSIFINFO
+#define        TAPGIFINFO              TUNGIFINFO
+#define        TAPGIFNAME              TUNGIFNAME
 
 /* VMware ioctl's */
 #define VMIO_SIOCSIFFLAGS      _IOWINT('V', 0)

Copied and modified: stable/12/sys/net/if_tuntap.c (from r354059, 
stable/12/sys/net/if_tun.c)
==============================================================================
--- stable/12/sys/net/if_tun.c  Fri Oct 25 00:47:37 2019        (r354059, copy 
source)
+++ stable/12/sys/net/if_tuntap.c       Fri Oct 25 01:10:08 2019        
(r354060)
@@ -1,6 +1,36 @@
 /*     $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $  */
-
 /*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmen...@yahoo.com>
+ * All rights reserved.
+ * Copyright (c) 2019 Kyle Evans <kev...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BASED ON:
+ * -------------------------------------------------------------------------
+ *
  * Copyright (c) 1988, Julian Onions <j...@cs.nott.ac.uk>
  * Nottingham University 1987.
  *
@@ -46,9 +76,12 @@
 #include <sys/random.h>
 #include <sys/ctype.h>
 
+#include <net/ethernet.h>
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/if_clone.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/route.h>
@@ -57,89 +90,131 @@
 #include <netinet/in.h>
 #endif
 #include <net/bpf.h>
+#include <net/if_tap.h>
 #include <net/if_tun.h>
 
 #include <sys/queue.h>
 #include <sys/condvar.h>
-
 #include <security/mac/mac_framework.h>
 
+struct tuntap_driver;
+
 /*
  * tun_list is protected by global tunmtx.  Other mutable fields are
  * protected by tun->tun_mtx, or by their owning subsystem.  tun_dev is
  * static for the duration of a tunnel interface.
  */
-struct tun_softc {
-       TAILQ_ENTRY(tun_softc)  tun_list;
-       struct cdev *tun_dev;
-       u_short tun_flags;              /* misc flags */
+struct tuntap_softc {
+       TAILQ_ENTRY(tuntap_softc)        tun_list;
+       struct cdev                     *tun_alias;
+       struct cdev                     *tun_dev;
+       u_short                          tun_flags;     /* misc flags */
 #define        TUN_OPEN        0x0001
 #define        TUN_INITED      0x0002
-#define        TUN_RCOLL       0x0004
-#define        TUN_IASET       0x0008
+#define        TUN_UNUSED1     0x0008
 #define        TUN_DSTADDR     0x0010
 #define        TUN_LMODE       0x0020
 #define        TUN_RWAIT       0x0040
 #define        TUN_ASYNC       0x0080
 #define        TUN_IFHEAD      0x0100
 #define        TUN_DYING       0x0200
+#define        TUN_L2          0x0400
+#define        TUN_VMNET       0x0800
 
-#define TUN_READY       (TUN_OPEN | TUN_INITED)
+#define        TUN_DRIVER_IDENT_MASK   (TUN_L2 | TUN_VMNET)
+#define        TUN_READY               (TUN_OPEN | TUN_INITED)
 
-       pid_t   tun_pid;                /* owning pid */
-       struct  ifnet *tun_ifp;         /* the interface */
-       struct  sigio *tun_sigio;       /* information for async I/O */
-       struct  selinfo tun_rsel;       /* read select */
-       struct mtx      tun_mtx;        /* protect mutable softc fields */
-       struct cv       tun_cv;         /* protect against ref'd dev destroy */
+       pid_t                    tun_pid;       /* owning pid */
+       struct ifnet            *tun_ifp;       /* the interface */
+       struct sigio            *tun_sigio;     /* async I/O info */
+       struct tuntap_driver    *tun_drv;       /* appropriate driver */
+       struct selinfo           tun_rsel;      /* read select */
+       struct mtx               tun_mtx;       /* softc field mutex */
+       struct cv                tun_cv;        /* for ref'd dev destroy */
+       struct ether_addr        tun_ether;     /* remote address */
+       int                      tun_busy;      /* busy count */
 };
-#define TUN2IFP(sc)    ((sc)->tun_ifp)
+#define        TUN2IFP(sc)     ((sc)->tun_ifp)
 
-#define TUNDEBUG       if (tundebug) if_printf
+#define        TUNDEBUG        if (tundebug) if_printf
 
+#define        TUN_LOCK(tp)            mtx_lock(&(tp)->tun_mtx)
+#define        TUN_UNLOCK(tp)          mtx_unlock(&(tp)->tun_mtx)
+#define        TUN_LOCK_ASSERT(tp)     mtx_assert(&(tp)->tun_mtx, MA_OWNED);
+
+#define        TUN_VMIO_FLAG_MASK      0x0fff
+
 /*
  * All mutable global variables in if_tun are locked using tunmtx, with
- * the exception of tundebug, which is used unlocked, and tunclones,
- * which is static after setup.
+ * the exception of tundebug, which is used unlocked, and the drivers' *clones,
+ * which are static after setup.
  */
 static struct mtx tunmtx;
-static eventhandler_tag tag;
+static eventhandler_tag arrival_tag;
+static eventhandler_tag clone_tag;
 static const char tunname[] = "tun";
+static const char tapname[] = "tap";
+static const char vmnetname[] = "vmnet";
 static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
 static int tundebug = 0;
 static int tundclone = 1;
-static struct clonedevs *tunclones;
-static TAILQ_HEAD(,tun_softc)  tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
+static int tap_allow_uopen = 0;        /* allow user open() */
+static int tapuponopen = 0;    /* IFF_UP on open() */
+static int tapdclone = 1;      /* enable devfs cloning */
+
+static TAILQ_HEAD(,tuntap_softc)       tunhead = 
TAILQ_HEAD_INITIALIZER(tunhead);
 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
 
 static struct sx tun_ioctl_sx;
 SX_SYSINIT(tun_ioctl_sx, &tun_ioctl_sx, "tun_ioctl");
 
 SYSCTL_DECL(_net_link);
+/* tun */
 static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
-    "IP tunnel software network interface.");
+    "IP tunnel software network interface");
 SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tundclone, 
0,
-    "Enable legacy devfs interface creation.");
+    "Enable legacy devfs interface creation");
 
+/* tap */
+static SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
+    "Ethernet tunnel software network interface");
+SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tap_allow_uopen, 0,
+    "Allow user to open /dev/tap (based on node permissions)");
+SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0,
+    "Bring interface up when /dev/tap is opened");
+SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tapdclone, 
0,
+    "Enable legacy devfs interface creation");
+SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tundebug, 0, "");
+
+static int     tun_create_device(struct tuntap_driver *drv, int unit,
+    struct ucred *cr, struct cdev **dev, const char *name);
+static int     tun_busy_locked(struct tuntap_softc *tp);
+static void    tun_unbusy_locked(struct tuntap_softc *tp);
+static int     tun_busy(struct tuntap_softc *tp);
+static void    tun_unbusy(struct tuntap_softc *tp);
+
+static int     tuntap_name2info(const char *name, int *unit, int *flags);
 static void    tunclone(void *arg, struct ucred *cred, char *name,
                    int namelen, struct cdev **dev);
-static void    tuncreate(const char *name, struct cdev *dev);
+static void    tuncreate(struct cdev *dev);
+static void    tundtor(void *data);
+static void    tunrename(void *arg, struct ifnet *ifp);
 static int     tunifioctl(struct ifnet *, u_long, caddr_t);
 static void    tuninit(struct ifnet *);
-static int     tunmodevent(module_t, int, void *);
+static void    tunifinit(void *xtp);
+static int     tuntapmodevent(module_t, int, void *);
 static int     tunoutput(struct ifnet *, struct mbuf *,
                    const struct sockaddr *, struct route *ro);
 static void    tunstart(struct ifnet *);
+static void    tunstart_l2(struct ifnet *);
 
 static int     tun_clone_match(struct if_clone *ifc, const char *name);
+static int     tap_clone_match(struct if_clone *ifc, const char *name);
+static int     vmnet_clone_match(struct if_clone *ifc, const char *name);
 static int     tun_clone_create(struct if_clone *, char *, size_t, caddr_t);
 static int     tun_clone_destroy(struct if_clone *, struct ifnet *);
-static struct unrhdr   *tun_unrhdr;
-VNET_DEFINE_STATIC(struct if_clone *, tun_cloner);
-#define V_tun_cloner VNET(tun_cloner)
 
 static d_open_t                tunopen;
-static d_close_t       tunclose;
 static d_read_t                tunread;
 static d_write_t       tunwrite;
 static d_ioctl_t       tunioctl;
@@ -164,59 +239,295 @@ static struct filterops tun_write_filterops = {
        .f_event =      tunkqwrite,
 };
 
-static struct cdevsw tun_cdevsw = {
-       .d_version =    D_VERSION,
-       .d_flags =      D_NEEDMINOR,
-       .d_open =       tunopen,
-       .d_close =      tunclose,
-       .d_read =       tunread,
-       .d_write =      tunwrite,
-       .d_ioctl =      tunioctl,
-       .d_poll =       tunpoll,
-       .d_kqfilter =   tunkqfilter,
-       .d_name =       tunname,
+static struct tuntap_driver {
+       struct cdevsw            cdevsw;
+       int                      ident_flags;
+       struct unrhdr           *unrhdr;
+       struct clonedevs        *clones;
+       ifc_match_t             *clone_match_fn;
+       ifc_create_t            *clone_create_fn;
+       ifc_destroy_t           *clone_destroy_fn;
+} tuntap_drivers[] = {
+       {
+               .ident_flags =  0,
+               .cdevsw =       {
+                   .d_version =        D_VERSION,
+                   .d_flags =          D_NEEDMINOR,
+                   .d_open =           tunopen,
+                   .d_read =           tunread,
+                   .d_write =          tunwrite,
+                   .d_ioctl =          tunioctl,
+                   .d_poll =           tunpoll,
+                   .d_kqfilter =       tunkqfilter,
+                   .d_name =           tunname,
+               },
+               .clone_match_fn =       tun_clone_match,
+               .clone_create_fn =      tun_clone_create,
+               .clone_destroy_fn =     tun_clone_destroy,
+       },
+       {
+               .ident_flags =  TUN_L2,
+               .cdevsw =       {
+                   .d_version =        D_VERSION,
+                   .d_flags =          D_NEEDMINOR,
+                   .d_open =           tunopen,
+                   .d_read =           tunread,
+                   .d_write =          tunwrite,
+                   .d_ioctl =          tunioctl,
+                   .d_poll =           tunpoll,
+                   .d_kqfilter =       tunkqfilter,
+                   .d_name =           tapname,
+               },
+               .clone_match_fn =       tap_clone_match,
+               .clone_create_fn =      tun_clone_create,
+               .clone_destroy_fn =     tun_clone_destroy,
+       },
+       {
+               .ident_flags =  TUN_L2 | TUN_VMNET,
+               .cdevsw =       {
+                   .d_version =        D_VERSION,
+                   .d_flags =          D_NEEDMINOR,
+                   .d_open =           tunopen,
+                   .d_read =           tunread,
+                   .d_write =          tunwrite,
+                   .d_ioctl =          tunioctl,
+                   .d_poll =           tunpoll,
+                   .d_kqfilter =       tunkqfilter,
+                   .d_name =           vmnetname,
+               },
+               .clone_match_fn =       vmnet_clone_match,
+               .clone_create_fn =      tun_clone_create,
+               .clone_destroy_fn =     tun_clone_destroy,
+       },
 };
 
+struct tuntap_driver_cloner {
+       SLIST_ENTRY(tuntap_driver_cloner)        link;
+       struct tuntap_driver                    *drv;
+       struct if_clone                         *cloner;
+};
+
+VNET_DEFINE_STATIC(SLIST_HEAD(, tuntap_driver_cloner), tuntap_driver_cloners) =
+    SLIST_HEAD_INITIALIZER(tuntap_driver_cloners);
+
+#define        V_tuntap_driver_cloners VNET(tuntap_driver_cloners)
+
+/*
+ * Mechanism for marking a tunnel device as busy so that we can safely do some
+ * orthogonal operations (such as operations on devices) without racing against
+ * tun_destroy.  tun_destroy will wait on the condvar if we're at all busy or
+ * open, to be woken up when the condition is alleviated.
+ */
 static int
+tun_busy_locked(struct tuntap_softc *tp)
+{
+
+       TUN_LOCK_ASSERT(tp);
+       if ((tp->tun_flags & TUN_DYING) != 0) {
+               /*
+                * Perhaps unintuitive, but the device is busy going away.
+                * Other interpretations of EBUSY from tun_busy make little
+                * sense, since making a busy device even more busy doesn't
+                * sound like a problem.
+                */
+               return (EBUSY);
+       }
+
+       ++tp->tun_busy;
+       return (0);
+}
+
+static void
+tun_unbusy_locked(struct tuntap_softc *tp)
+{
+
+       TUN_LOCK_ASSERT(tp);
+       KASSERT(tp->tun_busy != 0, ("tun_unbusy: called for non-busy tunnel"));
+
+       --tp->tun_busy;
+       /* Wake up anything that may be waiting on our busy tunnel. */
+       if (tp->tun_busy == 0)
+               cv_broadcast(&tp->tun_cv);
+}
+
+static int
+tun_busy(struct tuntap_softc *tp)
+{
+       int ret;
+
+       TUN_LOCK(tp);
+       ret = tun_busy_locked(tp);
+       TUN_UNLOCK(tp);
+       return (ret);
+}
+
+
+static void
+tun_unbusy(struct tuntap_softc *tp)
+{
+
+       TUN_LOCK(tp);
+       tun_unbusy_locked(tp);
+       TUN_UNLOCK(tp);
+}
+
+/*
+ * Sets unit and/or flags given the device name.  Must be called with correct
+ * vnet context.
+ */
+static int
+tuntap_name2info(const char *name, int *outunit, int *outflags)
+{
+       struct tuntap_driver *drv;
+       struct tuntap_driver_cloner *drvc;
+       char *dname;
+       int flags, unit;
+       bool found;
+
+       if (name == NULL)
+               return (EINVAL);
+
+       /*
+        * Needed for dev_stdclone, but dev_stdclone will not modify, it just
+        * wants to be able to pass back a char * through the second param. We
+        * will always set that as NULL here, so we'll fake it.
+        */
+       dname = __DECONST(char *, name);
+       found = false;
+
+       KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
+           ("tuntap_driver_cloners failed to initialize"));
+       SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
+               KASSERT(drvc->drv != NULL,
+                   ("tuntap_driver_cloners entry not properly initialized"));
+               drv = drvc->drv;
+
+               if (strcmp(name, drv->cdevsw.d_name) == 0) {
+                       found = true;
+                       unit = -1;
+                       flags = drv->ident_flags;
+                       break;
+               }
+
+               if (dev_stdclone(dname, NULL, drv->cdevsw.d_name, &unit) == 1) {
+                       found = true;
+                       flags = drv->ident_flags;
+                       break;
+               }
+       }
+
+       if (!found)
+               return (ENXIO);
+
+       if (outunit != NULL)
+               *outunit = unit;
+       if (outflags != NULL)
+               *outflags = flags;
+       return (0);
+}
+
+/*
+ * Get driver information from a set of flags specified.  Masks the identifying
+ * part of the flags and compares it against all of the available
+ * tuntap_drivers. Must be called with correct vnet context.
+ */
+static struct tuntap_driver *
+tuntap_driver_from_flags(int tun_flags)
+{
+       struct tuntap_driver *drv;
+       struct tuntap_driver_cloner *drvc;
+
+       KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
+           ("tuntap_driver_cloners failed to initialize"));
+       SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
+               KASSERT(drvc->drv != NULL,
+                   ("tuntap_driver_cloners entry not properly initialized"));
+               drv = drvc->drv;
+               if ((tun_flags & TUN_DRIVER_IDENT_MASK) == drv->ident_flags)
+                       return (drv);
+       }
+
+       return (NULL);
+}
+
+
+
+static int
 tun_clone_match(struct if_clone *ifc, const char *name)
 {
-       if (strncmp(tunname, name, 3) == 0 &&
-           (name[3] == '\0' || isdigit(name[3])))
-               return (1);
+       int tunflags;
 
+       if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+               if ((tunflags & TUN_L2) == 0)
+                       return (1);
+       }
+
        return (0);
 }
 
 static int
+tap_clone_match(struct if_clone *ifc, const char *name)
+{
+       int tunflags;
+
+       if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+               if ((tunflags & (TUN_L2 | TUN_VMNET)) == TUN_L2)
+                       return (1);
+       }
+
+       return (0);
+}
+
+static int
+vmnet_clone_match(struct if_clone *ifc, const char *name)
+{
+       int tunflags;
+
+       if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+               if ((tunflags & TUN_VMNET) != 0)
+                       return (1);
+       }
+
+       return (0);
+}
+
+static int
 tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
 {
+       struct tuntap_driver *drv;
        struct cdev *dev;
-       int err, unit, i;
+       int err, i, tunflags, unit;
 
-       err = ifc_name2unit(name, &unit);
+       tunflags = 0;
+       /* The name here tells us exactly what we're creating */
+       err = tuntap_name2info(name, &unit, &tunflags);
        if (err != 0)
                return (err);
 
+       drv = tuntap_driver_from_flags(tunflags);
+       if (drv == NULL)
+               return (ENXIO);
+
        if (unit != -1) {
-               /* If this unit number is still available that/s okay. */
-               if (alloc_unr_specific(tun_unrhdr, unit) == -1)
+               /* If this unit number is still available that's okay. */
+               if (alloc_unr_specific(drv->unrhdr, unit) == -1)
                        return (EEXIST);
        } else {
-               unit = alloc_unr(tun_unrhdr);
+               unit = alloc_unr(drv->unrhdr);
        }
 
-       snprintf(name, IFNAMSIZ, "%s%d", tunname, unit);
+       snprintf(name, IFNAMSIZ, "%s%d", drv->cdevsw.d_name, unit);
 
        /* find any existing device, or allocate new unit number */
-       i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
-       if (i) {
-               /* No preexisting struct cdev *, create one */
-               dev = make_dev(&tun_cdevsw, unit,
-                   UID_UUCP, GID_DIALER, 0600, "%s%d", tunname, unit);
-       }
-       tuncreate(tunname, dev);
+       dev = NULL;
+       i = clone_create(&drv->clones, &drv->cdevsw, &unit, &dev, 0);
+       /* No preexisting struct cdev *, create one */
+       if (i != 0)
+               i = tun_create_device(drv, unit, NULL, &dev, name);
+       if (i == 0)
+               tuncreate(dev);
 
-       return (0);
+       return (i);
 }
 
 static void
@@ -224,76 +535,91 @@ tunclone(void *arg, struct ucred *cred, char *name, in
     struct cdev **dev)
 {
        char devname[SPECNAMELEN + 1];
-       int u, i, append_unit;
+       struct tuntap_driver *drv;
+       int append_unit, i, u, tunflags;
+       bool mayclone;
 
        if (*dev != NULL)
                return;
 
+       tunflags = 0;
+       CURVNET_SET(CRED_TO_VNET(cred));
+       if (tuntap_name2info(name, &u, &tunflags) != 0)
+               goto out;       /* Not recognized */
+
+       if (u != -1 && u > IF_MAXUNIT)
+               goto out;       /* Unit number too high */
+
+       mayclone = priv_check_cred(cred, PRIV_NET_IFCREATE, 0) == 0;
+       if ((tunflags & TUN_L2) != 0) {
+               /* tap/vmnet allow user open with a sysctl */
+               mayclone = (mayclone || tap_allow_uopen) && tapdclone;
+       } else {
+               mayclone = mayclone && tundclone;
+       }
+
        /*
         * If tun cloning is enabled, only the superuser can create an
         * interface.
         */
-       if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
-               return;
+       if (!mayclone)
+               goto out;
 
-       if (strcmp(name, tunname) == 0) {
-               u = -1;
-       } else if (dev_stdclone(name, NULL, tunname, &u) != 1)
-               return; /* Don't recognise the name */
-       if (u != -1 && u > IF_MAXUNIT)
-               return; /* Unit number too high */
-
        if (u == -1)
                append_unit = 1;
        else
                append_unit = 0;
 
-       CURVNET_SET(CRED_TO_VNET(cred));
+       drv = tuntap_driver_from_flags(tunflags);
+       if (drv == NULL)
+               goto out;
+
        /* find any existing device, or allocate new unit number */
-       i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
+       i = clone_create(&drv->clones, &drv->cdevsw, &u, dev, 0);
        if (i) {
                if (append_unit) {
                        namelen = snprintf(devname, sizeof(devname), "%s%d",
                            name, u);
                        name = devname;
                }
-               /* No preexisting struct cdev *, create one */
-               *dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred,
-                   UID_UUCP, GID_DIALER, 0600, "%s", name);
-       }
 
-       if_clone_create(name, namelen, NULL);
+               i = tun_create_device(drv, u, cred, dev, name);
+       }
+       if (i == 0)
+               if_clone_create(name, namelen, NULL);
+out:
        CURVNET_RESTORE();
 }
 
 static void
-tun_destroy(struct tun_softc *tp)
+tun_destroy(struct tuntap_softc *tp)
 {
-       struct cdev *dev;
 
-       mtx_lock(&tp->tun_mtx);
+       TUN_LOCK(tp);
        tp->tun_flags |= TUN_DYING;
-       if ((tp->tun_flags & TUN_OPEN) != 0)
+       if (tp->tun_busy != 0)
                cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
        else
-               mtx_unlock(&tp->tun_mtx);
+               TUN_UNLOCK(tp);
 
        CURVNET_SET(TUN2IFP(tp)->if_vnet);
 
-       dev = tp->tun_dev;
-       bpfdetach(TUN2IFP(tp));
-       if_detach(TUN2IFP(tp));
-
+       /* destroy_dev will take care of any alias. */
+       destroy_dev(tp->tun_dev);
+       seldrain(&tp->tun_rsel);
+       knlist_clear(&tp->tun_rsel.si_note, 0);
+       knlist_destroy(&tp->tun_rsel.si_note);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to