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