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 ...
Kyle Evans
kevans at FreeBSD.org
Fri Oct 25 01:10:13 UTC 2019
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 at yahoo.com>
+ * All rights reserved.
+ * Copyright (c) 2019 Kyle Evans <kevans at 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 at 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 ***
More information about the svn-src-all
mailing list