Virtual Network Card tun/TAP Driver Design Principle

Source: Internet
Author: User

From http://www.ibm.com/developerworks/cn/linux/l-tuntap/index.html

Introduction

The virtual Nic tun/TAP driver is an open-source project that supports many UNIX-like platforms. Both openvpn and vtun implement tunnel package encapsulation based on it. This article introduces the use of the tun/TAP driver and analyzes the design ideas of the tun/TAP driver in the Linux environment.

The tun/TAP driver implements the virtual Nic function. Tun indicates virtual devices are point-to-point devices, and tap indicates virtual devices are Ethernet devices. These two devices implement different encapsulation for network packets. By using the tun/TAP driver, the network packet processed by the TCP/IP protocol stack can be transferred to any process that uses the tun/TAP driver, and then processed by the process and sent to the physical link. Open source projects openvpn (http://openvpn.sourceforge.net) and vtun (http://vtun.sourceforge.net) are both tunnel packages implemented using the tun/TAP driver.

Use the tun/TAP driver

In Linux 2.4 and later versions, the tun/TAP driver is pre-compiled into the kernel as the system by default. Before use, make sure that the tun/TAP module is mounted and the device file is created:

 # Modprobe Tun <br/> # mknod/dev/NET/tun c 10 200 <br/>

 

Parameter C indicates the character device, and the 10 and 200 parameters are the master device number and the secondary device number respectively.

In this way, we can use the driver in the program.

Sample program using the tun/TAP device (from the openvpn open source project http://openvpn.sourceforge.net, Tun. c file)

Int open_tun (const char * Dev, char * Actual, int size) <br/>{< br/> struct ifreq IFR; <br/> int FD; <br/> char * Device = "/dev/NET/TUN"; <br/> If (FD = open (device, o_rdwr) <0) // create a descriptor <br/> MSG (m_err, "cannot open tun/TAP Dev % s", device); <br/> memset (& IFR, 0, sizeof (IFR); <br/> IFR. ifr_flags = iff_no_pi; <br/> If (! Strncmp (Dev, "tun", 3) {<br/> IFR. ifr_flags | = iff_tun; <br/>}< br/> else if (! Strncmp (Dev, "tap", 3) {<br/> IFR. ifr_flags | = iff_tap; <br/>}< br/> else {<br/> MSG (m_fatal, "I don't recognize device % s as a tun or tap device", Dev); <br/>}< br/> If (strlen (Dev)> 3) /* unit number specified? */<Br/> strncpy (IFR. ifr_name, Dev, ifnamsiz); <br/> If (IOCTL (FD, tunsetiff, (void *) & IFR) <0) // enable the virtual Nic <br/> MSG (m_err, "cannot IOCTL tunsetiff % s", Dev); <br/> set_nonblock (FD ); <br/> MSG (m_info, "tun/TAP device % s opened", IFR. ifr_name); <br/> strncpynt (actual, IFR. ifr_name, size); <br/> return FD; <br/>}< br/>

 

After calling the above function, you can use the ifconfig command under the shell command line to configure the virtual network card, through the generated character device descriptor, you can use the Read and Write Functions in the program to read or send data to the virtual Nic.

 

How the tun/TAP driver works

As a virtual NIC driver, the data receiving and sending of the tun/TAP driver does not directly deal with the real Nic, but is transferred through the user State. In Linux, there are multiple ways to achieve interaction between core and user-state data: Common sockets can be used to create special sockets and data interaction can be achieved through sockets; you can use the proc file system to create files for Data Interaction. You can also use the device file method to access the device file and call the corresponding routine of the device driver, the device driver itself is an interface between the core State and the user State. The tun/TAP driver uses the device file to realize data interaction between the user State and the core state.

In terms of structure, the tun/TAP driver is not simply a NIC driver, but also a character device driver. Connect user and core states as character devices. Below is:

The tun/TAP driver consists of two parts: the character device driver and the NIC Driver. The NIC Driver is used to receive network packets from the TCP/IP protocol stack and send them or, in turn, transfer the received network packets to the protocol stack for processing, the character-driven part transfers the network packet between the kernel and the user State, simulating the data receiving and sending of the physical link. The tun/TAP driver is a good combination of the two drivers.

The tun/TAP device structure is defined as follows:

 Struct tun_struct {<br/> char name [8]; // device name <br/> unsigned long flags; // differentiate Tun and tap devices <br/> struct fasync_struct * fasync; // file asynchronous notification structure <br/> wait_queue_head_t read_wait; // wait queue <br/> struct net_devicedev; // Linux abstract network device structure <br/> struct sk_buff_head txq; // network Buffer Queue <br/> struct net_device_statsstats; // network adapter status information structure <br/> }; <br/>

The struct net_device structure is a unified network device structure provided by the Linux kernel and defines a unified access interface for the system.

The NIC Driver processing routine in the tun/tap driver:

Static int tun_net_open (struct net_device * Dev );
Static int tun_net_close (struct net_device * Dev );
Static int tun_net_xmit (struct sk_buff * SKB, struct net_device * Dev); // data packet sending routine
Static void tun_net_mclist (struct net_device * Dev); // you can specify an address linked list for multipoint transmission.
Static struct net_device_stats * tun_net_stats (struct net_device * Dev); // you can call this function when an application needs to know statistics about network interfaces, such as ifconfig and netstat.
Int tun_net_init (struct net_device * Dev); // network device initial routine

Character device section:

In Linux, character devices and Block devices are uniformly accessed in the form of files, and their access interfaces are unified. They all use the open () function to open a device file or a common file, use the read () and write () functions to read and write files. The access interface for the character device defined by the tun/TAP driver is as follows:

Static struct file_operations tun_fops = {
Owner: this_module,
Llseek: tun_chr_lseek,
Read tun_chr_read,
Write: tun_chr_write,
Poll: tun_chr_poll,
IOCTL: tun_chr_ioctl,
Open: tun_chr_open,
Release: tun_chr_close,
Fasync: tun_chr_fasync
};

In the kernel, use the misc_register () function to register the driver as a non-standard character device driver and provide various program interfaces of the character device. Code from linux-2.4.20/linux-2.4.20/Drivers/NET/TUN. c

Static struct miscdevice tun_miscdev = <br/>{< br/> tun_minor, <br/> "net/TUN", <br/> & tun_fops <br/> }; <br/> int _ init tun_init (void) <br/>{< br/>... <Br/> If (misc_register (& tun_miscdev) {<br/> printk (kern_err "tun: Can't register MISC device % d/N", tun_minor ); <br/> return-EIO; <br/>}< br/> return 0; <br/>}< br/>

 

When a tun/TAP device is enabled, the open function calls the tun_chr_open () function, which completes some important initialization processes, including the initialization function of the NIC driver, the initialization of the network buffer list, and the waiting queue. In the tun/TAP driver, Nic registration is embedded in the character-driven IOCTL routine. It registers the NIC by using the custom IOCTL settings flag tunsetiff for the character device file descriptor. The following is the function call relationship:

The IOCTL () function is used to operate the character device file descriptor. tun_chr_ioctl in the character device is called to set the open tun/TAP device. If the flag is set to tunsetiff, The tun_set_iff () function is called, this function performs an important step, that is, registering the NIC Driver register_netdev (& Tun-> Dev ), the process routine of NIC Driver is initialized by the tun_chr_open () function during the open operation.

TUN/TAP device operation process:

The virtual NIC Driver provided by the tun/TAP device, which is no different from the real NIC Driver from the perspective of TCP/IP protocol stack. From the driver perspective, it differs from the real Nic in that the data obtained by the tun/TAP device is not from the physical link, but from the user zone, the tun/TAP Device Driver obtains data from the user zone through the character device file. When data is sent, the tun/TAP device is not sent to the physical link, but sent to the user area through the character device, and then sent by the user area program through other channels.

Sending process:

The program using the tun/TAP Nic transmits data to the driver through the Protocol Stack. The driver calls the registered hard_start_xmit function to send the data. The hard_start_xmit function calls the tun_net_xmit function again, SKB will be added to the SKB linked list, and then wake up the blocked process of using the tun/TAP device characters to drive Data Reading. Then, the tun/TAP device character driver calls its tun_chr_read () the process reads the SKB linked list and sends each read SKB to the user area to complete data transmission of the virtual Nic.

The process of receiving data:

When we use the write () system to write data to the character device file of the tun/TAP device, the tun_chr_write function is called, which uses tun_get_user to receive data from the user area, store the data in SKB, and then call the key function netif_rx (SKB) to send the SKB to the TCP/IP protocol stack for processing, to complete the data reception of the virtual Nic.

Summary

The tun/TAP driver cleverly combines the character driver with the NIC Driver. This article focuses on the analysis of the connection between the two drivers. The specific driver processing details are not listed one by one, please refer to the relevant documentation.

References

  • Linux Device Driver Version 2 (US) alessando Rubini
  • Http://openvpn.sourceforge.net
  • Simple implementation of LINUX serial port Internet access
  • Linux source code
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.