DragonFly On-Line Manual Pages
TUN(4) DragonFly Kernel Interfaces Manual TUN(4)
NAME
tun - tunnel software network interface
SYNOPSIS
pseudo-device tun
DESCRIPTION
The tun interface is a software loopback mechanism that can be loosely
described as the network interface analog of the pty(4), that is, tun
does for network interfaces what the pty(4) driver does for terminals.
The tun driver, like the pty(4) driver, provides two interfaces: an
interface like the usual facility it is simulating (a network interface
in the case of tun, or a terminal for pty(4)), and a character-special
device "control" interface. A client program transfers IP (by default)
packets to or from the tun "control" interface. The tap(4) interface
provides similar functionality at the Ethernet layer: a client will
transfer Ethernet frames to or from a tap(4) "control" interface.
The network interfaces are named "tun0", "tun1", etc. Each interface has
one control device, /dev/tunN. Interfaces are created in one of two
ways:
Executing "ifconfig tunN create"
This command creates interface tunN with /dev/tunN as its control
device. This is the preferred method. The interface persists
until it is removed with "ifconfig tunN destroy" or until the
if_tun.ko module is unloaded.
Opening /dev/tun
Opening the auto-cloning device /dev/tun creates a new interface
using the lowest unused unit number and returns a handle to its
control device (use devname(3) to determine which). Such an
interface is automatically destroyed on the last close of its
control device.
Access Control
Opening the auto-cloning device /dev/tun requires super-user privileges,
since it creates a new interface.
Access to the per-interface control devices /dev/tunN is governed by the
file permissions of the device node, which are created owned by
"root:wheel" with mode 0600 by default. To delegate an interface to an
unprivileged user, the administrator creates it and changes the ownership
or mode of its device node, for example:
ifconfig tun0 create
chown user /dev/tun0
The node is removed when the interface is destroyed and created afresh
with the default ownership the next time, so use devfs(5) rules to make a
permission change persistent. The owner of a control device can read and
write packets and change the per-interface settings described below.
Operation
Each interface supports the usual network-interface ioctl(2)s and thus
can be used with ifconfig(8) like any other interface. By default, they
are POINTOPOINT interfaces, but this can be changed; see the description
of TUNSIFMODE below. When the system chooses to transmit a packet on the
network interface, the packet can be read from the control device (it
appears as "input" there); writing a packet to the control device
generates an input packet on the network interface, as if the (non-
existent) hardware had just received it.
The control device is exclusive-open (it cannot be opened if it is
already open). Packets output on the interface are queued for reading
only while the control device is open and the interface is up; otherwise
they are dropped.
A read(2) will return a packet if one is available; if not, it will
either block until one is or return EWOULDBLOCK, depending on whether
non-blocking I/O has been enabled. Each read(2) returns exactly one
packet. If the packet is longer than is allowed for in the buffer passed
to read(2), the extra data will be silently dropped.
A write(2) call passes a packet in to be "received" on the pseudo-
interface. Each write(2) call supplies exactly one packet; the packet
length is determined from the amount of data provided to write(2).
Writes will not block; if the packet cannot be accepted for a transient
reason (e.g., no buffer space available), it is silently dropped; if the
reason is not transient (e.g., packet too large), an error is returned.
In both directions, the packet data may be preceded by a header,
depending on the mode of the control device as described in the Modes
section.
The control device also supports kqueue(2), and thereby select(2) and
poll(2), for read; selecting for write is pointless, and always succeeds,
since writes are always non-blocking.
On the last close of the control device, the interface is brought down
(as if with "ifconfig tunN down"), and all queued packets are thrown
away. An interface that was created by opening /dev/tun is then
destroyed; one created with ifconfig(8) remains and can be opened again.
Modes
The mode of the control device determines which header, if any, precedes
the packet data. It is selected with the TUNSIFHEAD and TUNSLMODE
ioctls, which are mutually exclusive: enabling one turns the other off.
default When neither ioctl has been set, packets are exchanged as
bare IP packets without a header. Since a packet then
carries no address family, a written packet is assumed to be
of type AF_INET, and only IPv4 packets are passed to the
control device; output packets of other address families are
discarded.
multi-af Selected by TUNSIFHEAD. Every packet is preceded by a 4-byte
address family in network byte order. Packets read from the
control device carry the address family of the packet.
Packets written must be prepended with the address family and
must contain at least one byte of data after it, otherwise
EINVAL is returned. This is the mode to use to carry IPv6,
or a mix of address families.
link-layer Selected by TUNSLMODE. Packets read from the control device
are prepended with the destination address in struct sockaddr
format; its actual length is in the member sa_len. Only
reads are affected: packets written carry no header and are
handled as in the "default" mode, i.e., they are assumed to
be of type AF_INET.
Ioctl Requests
The following ioctl(2) requests are supported (defined in
<net/tun/if_tun.h>):
TUNSDEBUG The argument should be a pointer to an int; this sets the
internal debugging variable to that value. The variable
is global: it applies to all tun devices, not only the
one the request was made on, and it is the same variable
that is exposed as the net.link.tun.debug sysctl.
Note: This request requires super-user privileges.
TUNGDEBUG The argument should be a pointer to an int; this stores
the internal debugging variable's value into it.
TUNSIFINFO The argument should be a pointer to an struct tuninfo and
allows setting the MTU and the baudrate of the tunnel
device. The type must match the type returned by
TUNGIFINFO, otherwise the call fails with EPROTOTYPE. An
MTU outside the range supported by the driver is rejected
with EINVAL. struct tuninfo is declared in
<net/tun/if_tun.h>.
TUNGIFINFO The argument should be a pointer to an struct tuninfo,
where the current MTU, type, and baudrate will be stored.
TUNGIFNAME Retrieve the name of the network interface, which may be
renamed, that is associated with the control device. The
argument should be a pointer to a struct ifreq. The
interface name will be returned in the ifr_name field.
TUNSIFMODE The argument should be a pointer to an int; its value
must be either IFF_POINTOPOINT or IFF_BROADCAST and
should have IFF_MULTICAST OR'd into the value if
multicast support is required. The corresponding flags
of the "tunN" interface are set accordingly. If the
value is anything else, an EINVAL error is returned. The
interface must be down at the time; if it is up, an EBUSY
error is returned.
TUNSLMODE The argument should be a pointer to an int; a non-zero
value turns off "multi-af" mode and turns on "link-layer"
mode; see Modes.
TUNSIFPID Will set the PID owning the tunnel device to the current
process's PID.
TUNSIFHEAD The argument should be a pointer to an int; a non-zero
value turns off "link-layer" mode, and enables "multi-af"
mode; see Modes.
TUNGIFHEAD The argument should be a pointer to an int; the ioctl
sets the value to one if the device is in "multi-af"
mode, and zero otherwise.
FIOASYNC Turn asynchronous I/O for reads (i.e., generation of
SIGIO when data is available to be read) off or on,
according as the argument int's value is or is not zero.
FIONREAD If any packets are queued to be read, store the size of
the first one into the argument int; otherwise, store
zero.
FIOSETOWN Set the process or process group to receive SIGIO
signals, when asynchronous I/O is enabled, to the
argument int value. A negative value denotes a process
group.
FIOGETOWN Retrieve the process or process group value for SIGIO
signals into the argument int value.
FILES
/dev/tun auto-cloning device, super-user only
/dev/tunN control device of interface "tunN", access governed
by its file permissions
SEE ALSO
ioctl(2), kqueue(2), devname(3), inet(4), inet6(4), tap(4), devfs(5),
ifconfig(8)
DragonFly 6.5-DEVELOPMENT October 10, 2026 DragonFly 6.5-DEVELOPMENT