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