Linux Tun Device工作原理


接收数据(转自其它网卡的设备)
先看标准接口定义

在要往这个设备发送数据时,会调用tun_net_xmit函数。


这里,待发送的数据进入了skb队列,等待被读取。对于实际的物理设备,驱动会把这些数据读走然后发送到网络上。但是tun是虚拟设备,需要应用层来读走这些数据。
应用层是如何读取tun接收到的数据呢?答案就是socket。


这里,接收消息的函数是tun_recvmsg。


这样数据就从skb队列里读出来了。然后,应用程序应该根据自己的逻辑对数据进行处理,比如转发(完成物理设备的发送动作)。
前面已经看到了,socket的发送函数是tun_sendmsg。

这里的netif_rx_ni是网络设备接收到数据(从物理媒介)之后的标准入口,通知系统进行转发。
最终调用的是netif_rx函数(源码在dev.c)


这样就完成了数据的转发。

一个简单的数据流转图

这时候,我们才注意到tun完整名称是tunnel,因为app在这个数据的流转过程中做很多事情,完成各种穿越。
我们可以合理的设置陷阱(比如ip subnet),让系统把数据转发到tun上,然后我们就可以做很多工作,然后再把数据放回去。
最后,tun是layer3的设备,tap是layer2的设备,源代码其实就一份tun.c。

原文时间:2014.1