Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 .. include:: <isonum.txt>
0003 
0004 ===============================
0005 Universal TUN/TAP device driver
0006 ===============================
0007 
0008 Copyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
0009 
0010   Linux, Solaris drivers
0011   Copyright |copy| 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
0012 
0013   FreeBSD TAP driver
0014   Copyright |copy| 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
0015 
0016   Revision of this document 2002 by Florian Thiel <florian.thiel@gmx.net>
0017 
0018 1. Description
0019 ==============
0020 
0021   TUN/TAP provides packet reception and transmission for user space programs.
0022   It can be seen as a simple Point-to-Point or Ethernet device, which,
0023   instead of receiving packets from physical media, receives them from
0024   user space program and instead of sending packets via physical media
0025   writes them to the user space program.
0026 
0027   In order to use the driver a program has to open /dev/net/tun and issue a
0028   corresponding ioctl() to register a network device with the kernel. A network
0029   device will appear as tunXX or tapXX, depending on the options chosen. When
0030   the program closes the file descriptor, the network device and all
0031   corresponding routes will disappear.
0032 
0033   Depending on the type of device chosen the userspace program has to read/write
0034   IP packets (with tun) or ethernet frames (with tap). Which one is being used
0035   depends on the flags given with the ioctl().
0036 
0037   The package from http://vtun.sourceforge.net/tun contains two simple examples
0038   for how to use tun and tap devices. Both programs work like a bridge between
0039   two network interfaces.
0040   br_select.c - bridge based on select system call.
0041   br_sigio.c  - bridge based on async io and SIGIO signal.
0042   However, the best example is VTun http://vtun.sourceforge.net :))
0043 
0044 2. Configuration
0045 ================
0046 
0047   Create device node::
0048 
0049      mkdir /dev/net (if it doesn't exist already)
0050      mknod /dev/net/tun c 10 200
0051 
0052   Set permissions::
0053 
0054      e.g. chmod 0666 /dev/net/tun
0055 
0056   There's no harm in allowing the device to be accessible by non-root users,
0057   since CAP_NET_ADMIN is required for creating network devices or for
0058   connecting to network devices which aren't owned by the user in question.
0059   If you want to create persistent devices and give ownership of them to
0060   unprivileged users, then you need the /dev/net/tun device to be usable by
0061   those users.
0062 
0063   Driver module autoloading
0064 
0065      Make sure that "Kernel module loader" - module auto-loading
0066      support is enabled in your kernel.  The kernel should load it on
0067      first access.
0068 
0069   Manual loading
0070 
0071      insert the module by hand::
0072 
0073         modprobe tun
0074 
0075   If you do it the latter way, you have to load the module every time you
0076   need it, if you do it the other way it will be automatically loaded when
0077   /dev/net/tun is being opened.
0078 
0079 3. Program interface
0080 ====================
0081 
0082 3.1 Network device allocation
0083 -----------------------------
0084 
0085 ``char *dev`` should be the name of the device with a format string (e.g.
0086 "tun%d"), but (as far as I can see) this can be any valid network device name.
0087 Note that the character pointer becomes overwritten with the real device name
0088 (e.g. "tun0")::
0089 
0090   #include <linux/if.h>
0091   #include <linux/if_tun.h>
0092 
0093   int tun_alloc(char *dev)
0094   {
0095       struct ifreq ifr;
0096       int fd, err;
0097 
0098       if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
0099          return tun_alloc_old(dev);
0100 
0101       memset(&ifr, 0, sizeof(ifr));
0102 
0103       /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
0104        *        IFF_TAP   - TAP device
0105        *
0106        *        IFF_NO_PI - Do not provide packet information
0107        */
0108       ifr.ifr_flags = IFF_TUN;
0109       if( *dev )
0110          strscpy_pad(ifr.ifr_name, dev, IFNAMSIZ);
0111 
0112       if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
0113          close(fd);
0114          return err;
0115       }
0116       strcpy(dev, ifr.ifr_name);
0117       return fd;
0118   }
0119 
0120 3.2 Frame format
0121 ----------------
0122 
0123 If flag IFF_NO_PI is not set each frame format is::
0124 
0125      Flags [2 bytes]
0126      Proto [2 bytes]
0127      Raw protocol(IP, IPv6, etc) frame.
0128 
0129 3.3 Multiqueue tuntap interface
0130 -------------------------------
0131 
0132 From version 3.8, Linux supports multiqueue tuntap which can uses multiple
0133 file descriptors (queues) to parallelize packets sending or receiving. The
0134 device allocation is the same as before, and if user wants to create multiple
0135 queues, TUNSETIFF with the same device name must be called many times with
0136 IFF_MULTI_QUEUE flag.
0137 
0138 ``char *dev`` should be the name of the device, queues is the number of queues
0139 to be created, fds is used to store and return the file descriptors (queues)
0140 created to the caller. Each file descriptor were served as the interface of a
0141 queue which could be accessed by userspace.
0142 
0143 ::
0144 
0145   #include <linux/if.h>
0146   #include <linux/if_tun.h>
0147 
0148   int tun_alloc_mq(char *dev, int queues, int *fds)
0149   {
0150       struct ifreq ifr;
0151       int fd, err, i;
0152 
0153       if (!dev)
0154           return -1;
0155 
0156       memset(&ifr, 0, sizeof(ifr));
0157       /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
0158        *        IFF_TAP   - TAP device
0159        *
0160        *        IFF_NO_PI - Do not provide packet information
0161        *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
0162        */
0163       ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
0164       strcpy(ifr.ifr_name, dev);
0165 
0166       for (i = 0; i < queues; i++) {
0167           if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
0168              goto err;
0169           err = ioctl(fd, TUNSETIFF, (void *)&ifr);
0170           if (err) {
0171              close(fd);
0172              goto err;
0173           }
0174           fds[i] = fd;
0175       }
0176 
0177       return 0;
0178   err:
0179       for (--i; i >= 0; i--)
0180           close(fds[i]);
0181       return err;
0182   }
0183 
0184 A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
0185 calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
0186 calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
0187 enabled by default after it was created through TUNSETIFF.
0188 
0189 fd is the file descriptor (queue) that we want to enable or disable, when
0190 enable is true we enable it, otherwise we disable it::
0191 
0192   #include <linux/if.h>
0193   #include <linux/if_tun.h>
0194 
0195   int tun_set_queue(int fd, int enable)
0196   {
0197       struct ifreq ifr;
0198 
0199       memset(&ifr, 0, sizeof(ifr));
0200 
0201       if (enable)
0202          ifr.ifr_flags = IFF_ATTACH_QUEUE;
0203       else
0204          ifr.ifr_flags = IFF_DETACH_QUEUE;
0205 
0206       return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
0207   }
0208 
0209 Universal TUN/TAP device driver Frequently Asked Question
0210 =========================================================
0211 
0212 1. What platforms are supported by TUN/TAP driver ?
0213 
0214 Currently driver has been written for 3 Unices:
0215 
0216   - Linux kernels 2.2.x, 2.4.x
0217   - FreeBSD 3.x, 4.x, 5.x
0218   - Solaris 2.6, 7.0, 8.0
0219 
0220 2. What is TUN/TAP driver used for?
0221 
0222 As mentioned above, main purpose of TUN/TAP driver is tunneling.
0223 It is used by VTun (http://vtun.sourceforge.net).
0224 
0225 Another interesting application using TUN/TAP is pipsecd
0226 (http://perso.enst.fr/~beyssac/pipsec/), a userspace IPSec
0227 implementation that can use complete kernel routing (unlike FreeS/WAN).
0228 
0229 3. How does Virtual network device actually work ?
0230 
0231 Virtual network device can be viewed as a simple Point-to-Point or
0232 Ethernet device, which instead of receiving packets from a physical
0233 media, receives them from user space program and instead of sending
0234 packets via physical media sends them to the user space program.
0235 
0236 Let's say that you configured IPv6 on the tap0, then whenever
0237 the kernel sends an IPv6 packet to tap0, it is passed to the application
0238 (VTun for example). The application encrypts, compresses and sends it to
0239 the other side over TCP or UDP. The application on the other side decompresses
0240 and decrypts the data received and writes the packet to the TAP device,
0241 the kernel handles the packet like it came from real physical device.
0242 
0243 4. What is the difference between TUN driver and TAP driver?
0244 
0245 TUN works with IP frames. TAP works with Ethernet frames.
0246 
0247 This means that you have to read/write IP packets when you are using tun and
0248 ethernet frames when using tap.
0249 
0250 5. What is the difference between BPF and TUN/TAP driver?
0251 
0252 BPF is an advanced packet filter. It can be attached to existing
0253 network interface. It does not provide a virtual network interface.
0254 A TUN/TAP driver does provide a virtual network interface and it is possible
0255 to attach BPF to this interface.
0256 
0257 6. Does TAP driver support kernel Ethernet bridging?
0258 
0259 Yes. Linux and FreeBSD drivers support Ethernet bridging.