1973d55e5SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2973d55e5SMauro Carvalho Chehab.. include:: <isonum.txt>
3973d55e5SMauro Carvalho Chehab
4973d55e5SMauro Carvalho Chehab===============================
5973d55e5SMauro Carvalho ChehabUniversal TUN/TAP device driver
6973d55e5SMauro Carvalho Chehab===============================
7973d55e5SMauro Carvalho Chehab
8973d55e5SMauro Carvalho ChehabCopyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
9973d55e5SMauro Carvalho Chehab
10973d55e5SMauro Carvalho Chehab  Linux, Solaris drivers
11973d55e5SMauro Carvalho Chehab  Copyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
12973d55e5SMauro Carvalho Chehab
13973d55e5SMauro Carvalho Chehab  FreeBSD TAP driver
14973d55e5SMauro Carvalho Chehab  Copyright |copy| 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
15973d55e5SMauro Carvalho Chehab
16973d55e5SMauro Carvalho Chehab  Revision of this document 2002 by Florian Thiel <florian.thiel@gmx.net>
17973d55e5SMauro Carvalho Chehab
18973d55e5SMauro Carvalho Chehab1. Description
19973d55e5SMauro Carvalho Chehab==============
20973d55e5SMauro Carvalho Chehab
21973d55e5SMauro Carvalho Chehab  TUN/TAP provides packet reception and transmission for user space programs.
22973d55e5SMauro Carvalho Chehab  It can be seen as a simple Point-to-Point or Ethernet device, which,
23973d55e5SMauro Carvalho Chehab  instead of receiving packets from physical media, receives them from
24973d55e5SMauro Carvalho Chehab  user space program and instead of sending packets via physical media
25973d55e5SMauro Carvalho Chehab  writes them to the user space program.
26973d55e5SMauro Carvalho Chehab
27973d55e5SMauro Carvalho Chehab  In order to use the driver a program has to open /dev/net/tun and issue a
28973d55e5SMauro Carvalho Chehab  corresponding ioctl() to register a network device with the kernel. A network
29973d55e5SMauro Carvalho Chehab  device will appear as tunXX or tapXX, depending on the options chosen. When
30973d55e5SMauro Carvalho Chehab  the program closes the file descriptor, the network device and all
31973d55e5SMauro Carvalho Chehab  corresponding routes will disappear.
32973d55e5SMauro Carvalho Chehab
33973d55e5SMauro Carvalho Chehab  Depending on the type of device chosen the userspace program has to read/write
34973d55e5SMauro Carvalho Chehab  IP packets (with tun) or ethernet frames (with tap). Which one is being used
35973d55e5SMauro Carvalho Chehab  depends on the flags given with the ioctl().
36973d55e5SMauro Carvalho Chehab
37973d55e5SMauro Carvalho Chehab  The package from http://vtun.sourceforge.net/tun contains two simple examples
38973d55e5SMauro Carvalho Chehab  for how to use tun and tap devices. Both programs work like a bridge between
39973d55e5SMauro Carvalho Chehab  two network interfaces.
40973d55e5SMauro Carvalho Chehab  br_select.c - bridge based on select system call.
41973d55e5SMauro Carvalho Chehab  br_sigio.c  - bridge based on async io and SIGIO signal.
42973d55e5SMauro Carvalho Chehab  However, the best example is VTun http://vtun.sourceforge.net :))
43973d55e5SMauro Carvalho Chehab
44973d55e5SMauro Carvalho Chehab2. Configuration
45973d55e5SMauro Carvalho Chehab================
46973d55e5SMauro Carvalho Chehab
47973d55e5SMauro Carvalho Chehab  Create device node::
48973d55e5SMauro Carvalho Chehab
49973d55e5SMauro Carvalho Chehab     mkdir /dev/net (if it doesn't exist already)
50973d55e5SMauro Carvalho Chehab     mknod /dev/net/tun c 10 200
51973d55e5SMauro Carvalho Chehab
52973d55e5SMauro Carvalho Chehab  Set permissions::
53973d55e5SMauro Carvalho Chehab
54973d55e5SMauro Carvalho Chehab     e.g. chmod 0666 /dev/net/tun
55973d55e5SMauro Carvalho Chehab
56973d55e5SMauro Carvalho Chehab  There's no harm in allowing the device to be accessible by non-root users,
57973d55e5SMauro Carvalho Chehab  since CAP_NET_ADMIN is required for creating network devices or for
58973d55e5SMauro Carvalho Chehab  connecting to network devices which aren't owned by the user in question.
59973d55e5SMauro Carvalho Chehab  If you want to create persistent devices and give ownership of them to
60973d55e5SMauro Carvalho Chehab  unprivileged users, then you need the /dev/net/tun device to be usable by
61973d55e5SMauro Carvalho Chehab  those users.
62973d55e5SMauro Carvalho Chehab
63973d55e5SMauro Carvalho Chehab  Driver module autoloading
64973d55e5SMauro Carvalho Chehab
65973d55e5SMauro Carvalho Chehab     Make sure that "Kernel module loader" - module auto-loading
66973d55e5SMauro Carvalho Chehab     support is enabled in your kernel.  The kernel should load it on
67973d55e5SMauro Carvalho Chehab     first access.
68973d55e5SMauro Carvalho Chehab
69973d55e5SMauro Carvalho Chehab  Manual loading
70973d55e5SMauro Carvalho Chehab
71973d55e5SMauro Carvalho Chehab     insert the module by hand::
72973d55e5SMauro Carvalho Chehab
73973d55e5SMauro Carvalho Chehab	modprobe tun
74973d55e5SMauro Carvalho Chehab
75973d55e5SMauro Carvalho Chehab  If you do it the latter way, you have to load the module every time you
76973d55e5SMauro Carvalho Chehab  need it, if you do it the other way it will be automatically loaded when
77973d55e5SMauro Carvalho Chehab  /dev/net/tun is being opened.
78973d55e5SMauro Carvalho Chehab
79973d55e5SMauro Carvalho Chehab3. Program interface
80973d55e5SMauro Carvalho Chehab====================
81973d55e5SMauro Carvalho Chehab
82973d55e5SMauro Carvalho Chehab3.1 Network device allocation
83973d55e5SMauro Carvalho Chehab-----------------------------
84973d55e5SMauro Carvalho Chehab
85973d55e5SMauro Carvalho Chehab``char *dev`` should be the name of the device with a format string (e.g.
86973d55e5SMauro Carvalho Chehab"tun%d"), but (as far as I can see) this can be any valid network device name.
87973d55e5SMauro Carvalho ChehabNote that the character pointer becomes overwritten with the real device name
88973d55e5SMauro Carvalho Chehab(e.g. "tun0")::
89973d55e5SMauro Carvalho Chehab
90973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
91973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
92973d55e5SMauro Carvalho Chehab
93973d55e5SMauro Carvalho Chehab  int tun_alloc(char *dev)
94973d55e5SMauro Carvalho Chehab  {
95973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
96973d55e5SMauro Carvalho Chehab      int fd, err;
97973d55e5SMauro Carvalho Chehab
98973d55e5SMauro Carvalho Chehab      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
99973d55e5SMauro Carvalho Chehab	 return tun_alloc_old(dev);
100973d55e5SMauro Carvalho Chehab
101973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
102973d55e5SMauro Carvalho Chehab
103973d55e5SMauro Carvalho Chehab      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
104973d55e5SMauro Carvalho Chehab       *        IFF_TAP   - TAP device
105973d55e5SMauro Carvalho Chehab       *
106973d55e5SMauro Carvalho Chehab       *        IFF_NO_PI - Do not provide packet information
107973d55e5SMauro Carvalho Chehab       */
108973d55e5SMauro Carvalho Chehab      ifr.ifr_flags = IFF_TUN;
109973d55e5SMauro Carvalho Chehab      if( *dev )
110*f9ce26c5SKees Cook	 strscpy_pad(ifr.ifr_name, dev, IFNAMSIZ);
111973d55e5SMauro Carvalho Chehab
112973d55e5SMauro Carvalho Chehab      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
113973d55e5SMauro Carvalho Chehab	 close(fd);
114973d55e5SMauro Carvalho Chehab	 return err;
115973d55e5SMauro Carvalho Chehab      }
116973d55e5SMauro Carvalho Chehab      strcpy(dev, ifr.ifr_name);
117973d55e5SMauro Carvalho Chehab      return fd;
118973d55e5SMauro Carvalho Chehab  }
119973d55e5SMauro Carvalho Chehab
120973d55e5SMauro Carvalho Chehab3.2 Frame format
121973d55e5SMauro Carvalho Chehab----------------
122973d55e5SMauro Carvalho Chehab
123973d55e5SMauro Carvalho ChehabIf flag IFF_NO_PI is not set each frame format is::
124973d55e5SMauro Carvalho Chehab
125973d55e5SMauro Carvalho Chehab     Flags [2 bytes]
126973d55e5SMauro Carvalho Chehab     Proto [2 bytes]
127973d55e5SMauro Carvalho Chehab     Raw protocol(IP, IPv6, etc) frame.
128973d55e5SMauro Carvalho Chehab
129973d55e5SMauro Carvalho Chehab3.3 Multiqueue tuntap interface
130973d55e5SMauro Carvalho Chehab-------------------------------
131973d55e5SMauro Carvalho Chehab
132973d55e5SMauro Carvalho ChehabFrom version 3.8, Linux supports multiqueue tuntap which can uses multiple
133973d55e5SMauro Carvalho Chehabfile descriptors (queues) to parallelize packets sending or receiving. The
134973d55e5SMauro Carvalho Chehabdevice allocation is the same as before, and if user wants to create multiple
135973d55e5SMauro Carvalho Chehabqueues, TUNSETIFF with the same device name must be called many times with
136973d55e5SMauro Carvalho ChehabIFF_MULTI_QUEUE flag.
137973d55e5SMauro Carvalho Chehab
138973d55e5SMauro Carvalho Chehab``char *dev`` should be the name of the device, queues is the number of queues
139973d55e5SMauro Carvalho Chehabto be created, fds is used to store and return the file descriptors (queues)
140973d55e5SMauro Carvalho Chehabcreated to the caller. Each file descriptor were served as the interface of a
141973d55e5SMauro Carvalho Chehabqueue which could be accessed by userspace.
142973d55e5SMauro Carvalho Chehab
143973d55e5SMauro Carvalho Chehab::
144973d55e5SMauro Carvalho Chehab
145973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
146973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
147973d55e5SMauro Carvalho Chehab
148973d55e5SMauro Carvalho Chehab  int tun_alloc_mq(char *dev, int queues, int *fds)
149973d55e5SMauro Carvalho Chehab  {
150973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
151973d55e5SMauro Carvalho Chehab      int fd, err, i;
152973d55e5SMauro Carvalho Chehab
153973d55e5SMauro Carvalho Chehab      if (!dev)
154973d55e5SMauro Carvalho Chehab	  return -1;
155973d55e5SMauro Carvalho Chehab
156973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
157973d55e5SMauro Carvalho Chehab      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
158973d55e5SMauro Carvalho Chehab       *        IFF_TAP   - TAP device
159973d55e5SMauro Carvalho Chehab       *
160973d55e5SMauro Carvalho Chehab       *        IFF_NO_PI - Do not provide packet information
161973d55e5SMauro Carvalho Chehab       *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
162973d55e5SMauro Carvalho Chehab       */
163973d55e5SMauro Carvalho Chehab      ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
164973d55e5SMauro Carvalho Chehab      strcpy(ifr.ifr_name, dev);
165973d55e5SMauro Carvalho Chehab
166973d55e5SMauro Carvalho Chehab      for (i = 0; i < queues; i++) {
167973d55e5SMauro Carvalho Chehab	  if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
168973d55e5SMauro Carvalho Chehab	     goto err;
169973d55e5SMauro Carvalho Chehab	  err = ioctl(fd, TUNSETIFF, (void *)&ifr);
170973d55e5SMauro Carvalho Chehab	  if (err) {
171973d55e5SMauro Carvalho Chehab	     close(fd);
172973d55e5SMauro Carvalho Chehab	     goto err;
173973d55e5SMauro Carvalho Chehab	  }
174973d55e5SMauro Carvalho Chehab	  fds[i] = fd;
175973d55e5SMauro Carvalho Chehab      }
176973d55e5SMauro Carvalho Chehab
177973d55e5SMauro Carvalho Chehab      return 0;
178973d55e5SMauro Carvalho Chehab  err:
179973d55e5SMauro Carvalho Chehab      for (--i; i >= 0; i--)
180973d55e5SMauro Carvalho Chehab	  close(fds[i]);
181973d55e5SMauro Carvalho Chehab      return err;
182973d55e5SMauro Carvalho Chehab  }
183973d55e5SMauro Carvalho Chehab
184973d55e5SMauro Carvalho ChehabA new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
185973d55e5SMauro Carvalho Chehabcalling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
186973d55e5SMauro Carvalho Chehabcalling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
187973d55e5SMauro Carvalho Chehabenabled by default after it was created through TUNSETIFF.
188973d55e5SMauro Carvalho Chehab
189973d55e5SMauro Carvalho Chehabfd is the file descriptor (queue) that we want to enable or disable, when
190973d55e5SMauro Carvalho Chehabenable is true we enable it, otherwise we disable it::
191973d55e5SMauro Carvalho Chehab
192973d55e5SMauro Carvalho Chehab  #include <linux/if.h>
193973d55e5SMauro Carvalho Chehab  #include <linux/if_tun.h>
194973d55e5SMauro Carvalho Chehab
195973d55e5SMauro Carvalho Chehab  int tun_set_queue(int fd, int enable)
196973d55e5SMauro Carvalho Chehab  {
197973d55e5SMauro Carvalho Chehab      struct ifreq ifr;
198973d55e5SMauro Carvalho Chehab
199973d55e5SMauro Carvalho Chehab      memset(&ifr, 0, sizeof(ifr));
200973d55e5SMauro Carvalho Chehab
201973d55e5SMauro Carvalho Chehab      if (enable)
202973d55e5SMauro Carvalho Chehab	 ifr.ifr_flags = IFF_ATTACH_QUEUE;
203973d55e5SMauro Carvalho Chehab      else
204973d55e5SMauro Carvalho Chehab	 ifr.ifr_flags = IFF_DETACH_QUEUE;
205973d55e5SMauro Carvalho Chehab
206973d55e5SMauro Carvalho Chehab      return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
207973d55e5SMauro Carvalho Chehab  }
208973d55e5SMauro Carvalho Chehab
209973d55e5SMauro Carvalho ChehabUniversal TUN/TAP device driver Frequently Asked Question
210973d55e5SMauro Carvalho Chehab=========================================================
211973d55e5SMauro Carvalho Chehab
212973d55e5SMauro Carvalho Chehab1. What platforms are supported by TUN/TAP driver ?
213973d55e5SMauro Carvalho Chehab
214973d55e5SMauro Carvalho ChehabCurrently driver has been written for 3 Unices:
215973d55e5SMauro Carvalho Chehab
216973d55e5SMauro Carvalho Chehab  - Linux kernels 2.2.x, 2.4.x
217973d55e5SMauro Carvalho Chehab  - FreeBSD 3.x, 4.x, 5.x
218973d55e5SMauro Carvalho Chehab  - Solaris 2.6, 7.0, 8.0
219973d55e5SMauro Carvalho Chehab
220973d55e5SMauro Carvalho Chehab2. What is TUN/TAP driver used for?
221973d55e5SMauro Carvalho Chehab
222973d55e5SMauro Carvalho ChehabAs mentioned above, main purpose of TUN/TAP driver is tunneling.
223973d55e5SMauro Carvalho ChehabIt is used by VTun (http://vtun.sourceforge.net).
224973d55e5SMauro Carvalho Chehab
225973d55e5SMauro Carvalho ChehabAnother interesting application using TUN/TAP is pipsecd
226973d55e5SMauro Carvalho Chehab(http://perso.enst.fr/~beyssac/pipsec/), a userspace IPSec
227973d55e5SMauro Carvalho Chehabimplementation that can use complete kernel routing (unlike FreeS/WAN).
228973d55e5SMauro Carvalho Chehab
229973d55e5SMauro Carvalho Chehab3. How does Virtual network device actually work ?
230973d55e5SMauro Carvalho Chehab
231973d55e5SMauro Carvalho ChehabVirtual network device can be viewed as a simple Point-to-Point or
232973d55e5SMauro Carvalho ChehabEthernet device, which instead of receiving packets from a physical
233973d55e5SMauro Carvalho Chehabmedia, receives them from user space program and instead of sending
234973d55e5SMauro Carvalho Chehabpackets via physical media sends them to the user space program.
235973d55e5SMauro Carvalho Chehab
236973d55e5SMauro Carvalho ChehabLet's say that you configured IPv6 on the tap0, then whenever
237973d55e5SMauro Carvalho Chehabthe kernel sends an IPv6 packet to tap0, it is passed to the application
238973d55e5SMauro Carvalho Chehab(VTun for example). The application encrypts, compresses and sends it to
239973d55e5SMauro Carvalho Chehabthe other side over TCP or UDP. The application on the other side decompresses
240973d55e5SMauro Carvalho Chehaband decrypts the data received and writes the packet to the TAP device,
241973d55e5SMauro Carvalho Chehabthe kernel handles the packet like it came from real physical device.
242973d55e5SMauro Carvalho Chehab
243973d55e5SMauro Carvalho Chehab4. What is the difference between TUN driver and TAP driver?
244973d55e5SMauro Carvalho Chehab
245973d55e5SMauro Carvalho ChehabTUN works with IP frames. TAP works with Ethernet frames.
246973d55e5SMauro Carvalho Chehab
247973d55e5SMauro Carvalho ChehabThis means that you have to read/write IP packets when you are using tun and
248973d55e5SMauro Carvalho Chehabethernet frames when using tap.
249973d55e5SMauro Carvalho Chehab
250973d55e5SMauro Carvalho Chehab5. What is the difference between BPF and TUN/TAP driver?
251973d55e5SMauro Carvalho Chehab
252973d55e5SMauro Carvalho ChehabBPF is an advanced packet filter. It can be attached to existing
253973d55e5SMauro Carvalho Chehabnetwork interface. It does not provide a virtual network interface.
254973d55e5SMauro Carvalho ChehabA TUN/TAP driver does provide a virtual network interface and it is possible
255973d55e5SMauro Carvalho Chehabto attach BPF to this interface.
256973d55e5SMauro Carvalho Chehab
257973d55e5SMauro Carvalho Chehab6. Does TAP driver support kernel Ethernet bridging?
258973d55e5SMauro Carvalho Chehab
259973d55e5SMauro Carvalho ChehabYes. Linux and FreeBSD drivers support Ethernet bridging.
260