xref: /openbmc/linux/Documentation/networking/tuntap.rst (revision 973d55e590beeca13fece60596ee3b511d36d9da)
1*973d55e5SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2*973d55e5SMauro Carvalho Chehab.. include:: <isonum.txt>
3*973d55e5SMauro Carvalho Chehab
4*973d55e5SMauro Carvalho Chehab===============================
5*973d55e5SMauro Carvalho ChehabUniversal TUN/TAP device driver
6*973d55e5SMauro Carvalho Chehab===============================
7*973d55e5SMauro Carvalho Chehab
8*973d55e5SMauro Carvalho ChehabCopyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
9*973d55e5SMauro Carvalho Chehab
10*973d55e5SMauro Carvalho Chehab  Linux, Solaris drivers
11*973d55e5SMauro Carvalho Chehab  Copyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
12*973d55e5SMauro Carvalho Chehab
13*973d55e5SMauro Carvalho Chehab  FreeBSD TAP driver
14*973d55e5SMauro Carvalho Chehab  Copyright |copy| 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
15*973d55e5SMauro Carvalho Chehab
16*973d55e5SMauro Carvalho Chehab  Revision of this document 2002 by Florian Thiel <florian.thiel@gmx.net>
17*973d55e5SMauro Carvalho Chehab
18*973d55e5SMauro Carvalho Chehab1. Description
19*973d55e5SMauro Carvalho Chehab==============
20*973d55e5SMauro Carvalho Chehab
21*973d55e5SMauro Carvalho Chehab  TUN/TAP provides packet reception and transmission for user space programs.
22*973d55e5SMauro Carvalho Chehab  It can be seen as a simple Point-to-Point or Ethernet device, which,
23*973d55e5SMauro Carvalho Chehab  instead of receiving packets from physical media, receives them from
24*973d55e5SMauro Carvalho Chehab  user space program and instead of sending packets via physical media
25*973d55e5SMauro Carvalho Chehab  writes them to the user space program.
26*973d55e5SMauro Carvalho Chehab
27*973d55e5SMauro Carvalho Chehab  In order to use the driver a program has to open /dev/net/tun and issue a
28*973d55e5SMauro Carvalho Chehab  corresponding ioctl() to register a network device with the kernel. A network
29*973d55e5SMauro Carvalho Chehab  device will appear as tunXX or tapXX, depending on the options chosen. When
30*973d55e5SMauro Carvalho Chehab  the program closes the file descriptor, the network device and all
31*973d55e5SMauro Carvalho Chehab  corresponding routes will disappear.
32*973d55e5SMauro Carvalho Chehab
33*973d55e5SMauro Carvalho Chehab  Depending on the type of device chosen the userspace program has to read/write
34*973d55e5SMauro Carvalho Chehab  IP packets (with tun) or ethernet frames (with tap). Which one is being used
35*973d55e5SMauro Carvalho Chehab  depends on the flags given with the ioctl().
36*973d55e5SMauro Carvalho Chehab
37*973d55e5SMauro Carvalho Chehab  The package from http://vtun.sourceforge.net/tun contains two simple examples
38*973d55e5SMauro Carvalho Chehab  for how to use tun and tap devices. Both programs work like a bridge between
39*973d55e5SMauro Carvalho Chehab  two network interfaces.
40*973d55e5SMauro Carvalho Chehab  br_select.c - bridge based on select system call.
41*973d55e5SMauro Carvalho Chehab  br_sigio.c  - bridge based on async io and SIGIO signal.
42*973d55e5SMauro Carvalho Chehab  However, the best example is VTun http://vtun.sourceforge.net :))
43*973d55e5SMauro Carvalho Chehab
44*973d55e5SMauro Carvalho Chehab2. Configuration
45*973d55e5SMauro Carvalho Chehab================
46*973d55e5SMauro Carvalho Chehab
47*973d55e5SMauro Carvalho Chehab  Create device node::
48*973d55e5SMauro Carvalho Chehab
49*973d55e5SMauro Carvalho Chehab     mkdir /dev/net (if it doesn't exist already)
50*973d55e5SMauro Carvalho Chehab     mknod /dev/net/tun c 10 200
51*973d55e5SMauro Carvalho Chehab
52*973d55e5SMauro Carvalho Chehab  Set permissions::
53*973d55e5SMauro Carvalho Chehab
54*973d55e5SMauro Carvalho Chehab     e.g. chmod 0666 /dev/net/tun
55*973d55e5SMauro Carvalho Chehab
56*973d55e5SMauro Carvalho Chehab  There's no harm in allowing the device to be accessible by non-root users,
57*973d55e5SMauro Carvalho Chehab  since CAP_NET_ADMIN is required for creating network devices or for
58*973d55e5SMauro Carvalho Chehab  connecting to network devices which aren't owned by the user in question.
59*973d55e5SMauro Carvalho Chehab  If you want to create persistent devices and give ownership of them to
60*973d55e5SMauro Carvalho Chehab  unprivileged users, then you need the /dev/net/tun device to be usable by
61*973d55e5SMauro Carvalho Chehab  those users.
62*973d55e5SMauro Carvalho Chehab
63*973d55e5SMauro Carvalho Chehab  Driver module autoloading
64*973d55e5SMauro Carvalho Chehab
65*973d55e5SMauro Carvalho Chehab     Make sure that "Kernel module loader" - module auto-loading
66*973d55e5SMauro Carvalho Chehab     support is enabled in your kernel.  The kernel should load it on
67*973d55e5SMauro Carvalho Chehab     first access.
68*973d55e5SMauro Carvalho Chehab
69*973d55e5SMauro Carvalho Chehab  Manual loading
70*973d55e5SMauro Carvalho Chehab
71*973d55e5SMauro Carvalho Chehab     insert the module by hand::
72*973d55e5SMauro Carvalho Chehab
73*973d55e5SMauro Carvalho Chehab	modprobe tun
74*973d55e5SMauro Carvalho Chehab
75*973d55e5SMauro Carvalho Chehab  If you do it the latter way, you have to load the module every time you
76*973d55e5SMauro Carvalho Chehab  need it, if you do it the other way it will be automatically loaded when
77*973d55e5SMauro Carvalho Chehab  /dev/net/tun is being opened.
78*973d55e5SMauro Carvalho Chehab
79*973d55e5SMauro Carvalho Chehab3. Program interface
80*973d55e5SMauro Carvalho Chehab====================
81*973d55e5SMauro Carvalho Chehab
82*973d55e5SMauro Carvalho Chehab3.1 Network device allocation
83*973d55e5SMauro Carvalho Chehab-----------------------------
84*973d55e5SMauro Carvalho Chehab
85*973d55e5SMauro Carvalho Chehab``char *dev`` should be the name of the device with a format string (e.g.
86*973d55e5SMauro Carvalho Chehab"tun%d"), but (as far as I can see) this can be any valid network device name.
87*973d55e5SMauro Carvalho ChehabNote that the character pointer becomes overwritten with the real device name
88*973d55e5SMauro Carvalho Chehab(e.g. "tun0")::
89*973d55e5SMauro Carvalho Chehab
90*973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
91*973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
92*973d55e5SMauro Carvalho Chehab
93*973d55e5SMauro Carvalho Chehab  int tun_alloc(char *dev)
94*973d55e5SMauro Carvalho Chehab  {
95*973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
96*973d55e5SMauro Carvalho Chehab      int fd, err;
97*973d55e5SMauro Carvalho Chehab
98*973d55e5SMauro Carvalho Chehab      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
99*973d55e5SMauro Carvalho Chehab	 return tun_alloc_old(dev);
100*973d55e5SMauro Carvalho Chehab
101*973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
102*973d55e5SMauro Carvalho Chehab
103*973d55e5SMauro Carvalho Chehab      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
104*973d55e5SMauro Carvalho Chehab       *        IFF_TAP   - TAP device
105*973d55e5SMauro Carvalho Chehab       *
106*973d55e5SMauro Carvalho Chehab       *        IFF_NO_PI - Do not provide packet information
107*973d55e5SMauro Carvalho Chehab       */
108*973d55e5SMauro Carvalho Chehab      ifr.ifr_flags = IFF_TUN;
109*973d55e5SMauro Carvalho Chehab      if( *dev )
110*973d55e5SMauro Carvalho Chehab	 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
111*973d55e5SMauro Carvalho Chehab
112*973d55e5SMauro Carvalho Chehab      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
113*973d55e5SMauro Carvalho Chehab	 close(fd);
114*973d55e5SMauro Carvalho Chehab	 return err;
115*973d55e5SMauro Carvalho Chehab      }
116*973d55e5SMauro Carvalho Chehab      strcpy(dev, ifr.ifr_name);
117*973d55e5SMauro Carvalho Chehab      return fd;
118*973d55e5SMauro Carvalho Chehab  }
119*973d55e5SMauro Carvalho Chehab
120*973d55e5SMauro Carvalho Chehab3.2 Frame format
121*973d55e5SMauro Carvalho Chehab----------------
122*973d55e5SMauro Carvalho Chehab
123*973d55e5SMauro Carvalho ChehabIf flag IFF_NO_PI is not set each frame format is::
124*973d55e5SMauro Carvalho Chehab
125*973d55e5SMauro Carvalho Chehab     Flags [2 bytes]
126*973d55e5SMauro Carvalho Chehab     Proto [2 bytes]
127*973d55e5SMauro Carvalho Chehab     Raw protocol(IP, IPv6, etc) frame.
128*973d55e5SMauro Carvalho Chehab
129*973d55e5SMauro Carvalho Chehab3.3 Multiqueue tuntap interface
130*973d55e5SMauro Carvalho Chehab-------------------------------
131*973d55e5SMauro Carvalho Chehab
132*973d55e5SMauro Carvalho ChehabFrom version 3.8, Linux supports multiqueue tuntap which can uses multiple
133*973d55e5SMauro Carvalho Chehabfile descriptors (queues) to parallelize packets sending or receiving. The
134*973d55e5SMauro Carvalho Chehabdevice allocation is the same as before, and if user wants to create multiple
135*973d55e5SMauro Carvalho Chehabqueues, TUNSETIFF with the same device name must be called many times with
136*973d55e5SMauro Carvalho ChehabIFF_MULTI_QUEUE flag.
137*973d55e5SMauro Carvalho Chehab
138*973d55e5SMauro Carvalho Chehab``char *dev`` should be the name of the device, queues is the number of queues
139*973d55e5SMauro Carvalho Chehabto be created, fds is used to store and return the file descriptors (queues)
140*973d55e5SMauro Carvalho Chehabcreated to the caller. Each file descriptor were served as the interface of a
141*973d55e5SMauro Carvalho Chehabqueue which could be accessed by userspace.
142*973d55e5SMauro Carvalho Chehab
143*973d55e5SMauro Carvalho Chehab::
144*973d55e5SMauro Carvalho Chehab
145*973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
146*973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
147*973d55e5SMauro Carvalho Chehab
148*973d55e5SMauro Carvalho Chehab  int tun_alloc_mq(char *dev, int queues, int *fds)
149*973d55e5SMauro Carvalho Chehab  {
150*973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
151*973d55e5SMauro Carvalho Chehab      int fd, err, i;
152*973d55e5SMauro Carvalho Chehab
153*973d55e5SMauro Carvalho Chehab      if (!dev)
154*973d55e5SMauro Carvalho Chehab	  return -1;
155*973d55e5SMauro Carvalho Chehab
156*973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
157*973d55e5SMauro Carvalho Chehab      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
158*973d55e5SMauro Carvalho Chehab       *        IFF_TAP   - TAP device
159*973d55e5SMauro Carvalho Chehab       *
160*973d55e5SMauro Carvalho Chehab       *        IFF_NO_PI - Do not provide packet information
161*973d55e5SMauro Carvalho Chehab       *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
162*973d55e5SMauro Carvalho Chehab       */
163*973d55e5SMauro Carvalho Chehab      ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
164*973d55e5SMauro Carvalho Chehab      strcpy(ifr.ifr_name, dev);
165*973d55e5SMauro Carvalho Chehab
166*973d55e5SMauro Carvalho Chehab      for (i = 0; i < queues; i++) {
167*973d55e5SMauro Carvalho Chehab	  if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
168*973d55e5SMauro Carvalho Chehab	     goto err;
169*973d55e5SMauro Carvalho Chehab	  err = ioctl(fd, TUNSETIFF, (void *)&ifr);
170*973d55e5SMauro Carvalho Chehab	  if (err) {
171*973d55e5SMauro Carvalho Chehab	     close(fd);
172*973d55e5SMauro Carvalho Chehab	     goto err;
173*973d55e5SMauro Carvalho Chehab	  }
174*973d55e5SMauro Carvalho Chehab	  fds[i] = fd;
175*973d55e5SMauro Carvalho Chehab      }
176*973d55e5SMauro Carvalho Chehab
177*973d55e5SMauro Carvalho Chehab      return 0;
178*973d55e5SMauro Carvalho Chehab  err:
179*973d55e5SMauro Carvalho Chehab      for (--i; i >= 0; i--)
180*973d55e5SMauro Carvalho Chehab	  close(fds[i]);
181*973d55e5SMauro Carvalho Chehab      return err;
182*973d55e5SMauro Carvalho Chehab  }
183*973d55e5SMauro Carvalho Chehab
184*973d55e5SMauro Carvalho ChehabA new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
185*973d55e5SMauro Carvalho Chehabcalling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
186*973d55e5SMauro Carvalho Chehabcalling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
187*973d55e5SMauro Carvalho Chehabenabled by default after it was created through TUNSETIFF.
188*973d55e5SMauro Carvalho Chehab
189*973d55e5SMauro Carvalho Chehabfd is the file descriptor (queue) that we want to enable or disable, when
190*973d55e5SMauro Carvalho Chehabenable is true we enable it, otherwise we disable it::
191*973d55e5SMauro Carvalho Chehab
192*973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
193*973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
194*973d55e5SMauro Carvalho Chehab
195*973d55e5SMauro Carvalho Chehab  int tun_set_queue(int fd, int enable)
196*973d55e5SMauro Carvalho Chehab  {
197*973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
198*973d55e5SMauro Carvalho Chehab
199*973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
200*973d55e5SMauro Carvalho Chehab
201*973d55e5SMauro Carvalho Chehab      if (enable)
202*973d55e5SMauro Carvalho Chehab	 ifr.ifr_flags = IFF_ATTACH_QUEUE;
203*973d55e5SMauro Carvalho Chehab      else
204*973d55e5SMauro Carvalho Chehab	 ifr.ifr_flags = IFF_DETACH_QUEUE;
205*973d55e5SMauro Carvalho Chehab
206*973d55e5SMauro Carvalho Chehab      return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
207*973d55e5SMauro Carvalho Chehab  }
208*973d55e5SMauro Carvalho Chehab
209*973d55e5SMauro Carvalho ChehabUniversal TUN/TAP device driver Frequently Asked Question
210*973d55e5SMauro Carvalho Chehab=========================================================
211*973d55e5SMauro Carvalho Chehab
212*973d55e5SMauro Carvalho Chehab1. What platforms are supported by TUN/TAP driver ?
213*973d55e5SMauro Carvalho Chehab
214*973d55e5SMauro Carvalho ChehabCurrently driver has been written for 3 Unices:
215*973d55e5SMauro Carvalho Chehab
216*973d55e5SMauro Carvalho Chehab  - Linux kernels 2.2.x, 2.4.x
217*973d55e5SMauro Carvalho Chehab  - FreeBSD 3.x, 4.x, 5.x
218*973d55e5SMauro Carvalho Chehab  - Solaris 2.6, 7.0, 8.0
219*973d55e5SMauro Carvalho Chehab
220*973d55e5SMauro Carvalho Chehab2. What is TUN/TAP driver used for?
221*973d55e5SMauro Carvalho Chehab
222*973d55e5SMauro Carvalho ChehabAs mentioned above, main purpose of TUN/TAP driver is tunneling.
223*973d55e5SMauro Carvalho ChehabIt is used by VTun (http://vtun.sourceforge.net).
224*973d55e5SMauro Carvalho Chehab
225*973d55e5SMauro Carvalho ChehabAnother interesting application using TUN/TAP is pipsecd
226*973d55e5SMauro Carvalho Chehab(http://perso.enst.fr/~beyssac/pipsec/), a userspace IPSec
227*973d55e5SMauro Carvalho Chehabimplementation that can use complete kernel routing (unlike FreeS/WAN).
228*973d55e5SMauro Carvalho Chehab
229*973d55e5SMauro Carvalho Chehab3. How does Virtual network device actually work ?
230*973d55e5SMauro Carvalho Chehab
231*973d55e5SMauro Carvalho ChehabVirtual network device can be viewed as a simple Point-to-Point or
232*973d55e5SMauro Carvalho ChehabEthernet device, which instead of receiving packets from a physical
233*973d55e5SMauro Carvalho Chehabmedia, receives them from user space program and instead of sending
234*973d55e5SMauro Carvalho Chehabpackets via physical media sends them to the user space program.
235*973d55e5SMauro Carvalho Chehab
236*973d55e5SMauro Carvalho ChehabLet's say that you configured IPv6 on the tap0, then whenever
237*973d55e5SMauro Carvalho Chehabthe kernel sends an IPv6 packet to tap0, it is passed to the application
238*973d55e5SMauro Carvalho Chehab(VTun for example). The application encrypts, compresses and sends it to
239*973d55e5SMauro Carvalho Chehabthe other side over TCP or UDP. The application on the other side decompresses
240*973d55e5SMauro Carvalho Chehaband decrypts the data received and writes the packet to the TAP device,
241*973d55e5SMauro Carvalho Chehabthe kernel handles the packet like it came from real physical device.
242*973d55e5SMauro Carvalho Chehab
243*973d55e5SMauro Carvalho Chehab4. What is the difference between TUN driver and TAP driver?
244*973d55e5SMauro Carvalho Chehab
245*973d55e5SMauro Carvalho ChehabTUN works with IP frames. TAP works with Ethernet frames.
246*973d55e5SMauro Carvalho Chehab
247*973d55e5SMauro Carvalho ChehabThis means that you have to read/write IP packets when you are using tun and
248*973d55e5SMauro Carvalho Chehabethernet frames when using tap.
249*973d55e5SMauro Carvalho Chehab
250*973d55e5SMauro Carvalho Chehab5. What is the difference between BPF and TUN/TAP driver?
251*973d55e5SMauro Carvalho Chehab
252*973d55e5SMauro Carvalho ChehabBPF is an advanced packet filter. It can be attached to existing
253*973d55e5SMauro Carvalho Chehabnetwork interface. It does not provide a virtual network interface.
254*973d55e5SMauro Carvalho ChehabA TUN/TAP driver does provide a virtual network interface and it is possible
255*973d55e5SMauro Carvalho Chehabto attach BPF to this interface.
256*973d55e5SMauro Carvalho Chehab
257*973d55e5SMauro Carvalho Chehab6. Does TAP driver support kernel Ethernet bridging?
258*973d55e5SMauro Carvalho Chehab
259*973d55e5SMauro Carvalho ChehabYes. Linux and FreeBSD drivers support Ethernet bridging.
260