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