Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Oct 2019 01:10:08 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r354060 - in stable/12: . sbin/ifconfig share/man/man4 sys/amd64/conf sys/arm/conf sys/arm64/conf sys/conf sys/i386/conf sys/mips/conf sys/modules sys/modules/if_tap sys/modules/if_tun ...
Message-ID:  <201910250110.x9P1A8bl014107@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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_evmenkin@yahoo.com>
+ * All rights reserved.
+ * Copyright (c) 2019 Kyle Evans <kevans@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 <jpo@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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910250110.x9P1A8bl014107>