···105105 Proto [2 bytes]106106 Raw protocol(IP, IPv6, etc) frame.107107108108+ 3.3 Multiqueue tuntap interface:109109+110110+ From version 3.8, Linux supports multiqueue tuntap which can uses multiple111111+ file descriptors (queues) to parallelize packets sending or receiving. The112112+ device allocation is the same as before, and if user wants to create multiple113113+ queues, TUNSETIFF with the same device name must be called many times with114114+ IFF_MULTI_QUEUE flag.115115+116116+ char *dev should be the name of the device, queues is the number of queues to117117+ be created, fds is used to store and return the file descriptors (queues)118118+ created to the caller. Each file descriptor were served as the interface of a119119+ queue which could be accessed by userspace.120120+121121+ #include <linux/if.h>122122+ #include <linux/if_tun.h>123123+124124+ int tun_alloc_mq(char *dev, int queues, int *fds)125125+ {126126+ struct ifreq ifr;127127+ int fd, err, i;128128+129129+ if (!dev)130130+ return -1;131131+132132+ memset(&ifr, 0, sizeof(ifr));133133+ /* Flags: IFF_TUN - TUN device (no Ethernet headers)134134+ * IFF_TAP - TAP device135135+ *136136+ * IFF_NO_PI - Do not provide packet information137137+ * IFF_MULTI_QUEUE - Create a queue of multiqueue device138138+ */139139+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;140140+ strcpy(ifr.ifr_name, dev);141141+142142+ for (i = 0; i < queues; i++) {143143+ if ((fd = open("/dev/net/tun", O_RDWR)) < 0)144144+ goto err;145145+ err = ioctl(fd, TUNSETIFF, (void *)&ifr);146146+ if (err) {147147+ close(fd);148148+ goto err;149149+ }150150+ fds[i] = fd;151151+ }152152+153153+ return 0;154154+ err:155155+ for (--i; i >= 0; i--)156156+ close(fds[i]);157157+ return err;158158+ }159159+160160+ A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When161161+ calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when162162+ calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were163163+ enabled by default after it was created through TUNSETIFF.164164+165165+ fd is the file descriptor (queue) that we want to enable or disable, when166166+ enable is true we enable it, otherwise we disable it167167+168168+ #include <linux/if.h>169169+ #include <linux/if_tun.h>170170+171171+ int tun_set_queue(int fd, int enable)172172+ {173173+ struct ifreq ifr;174174+175175+ memset(&ifr, 0, sizeof(ifr));176176+177177+ if (enable)178178+ ifr.ifr_flags = IFF_ATTACH_QUEUE;179179+ else180180+ ifr.ifr_flags = IFF_DETACH_QUEUE;181181+182182+ return ioctl(fd, TUNSETQUEUE, (void *)&ifr);183183+ }184184+108185Universal TUN/TAP device driver Frequently Asked Question.1091861101871. What platforms are supported by TUN/TAP driver ?