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