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