Linux中的tap/tun设备
Linux虚拟网络设备tap/tun
tap/tun常用于隧道通讯,通过一个字符设备来实现用户态和内核态的通讯,字符设备一端连接着用户空间,一端连接着内核空间。
与物理网卡的最大不同是,tap/tun的数据源来自于用户态的程序,而物理网卡的数据源来自于物理链路。
对应的字符设备文件位置:
- tap: /dev/tap0
- tun: /dev/net/tun
当应用程序打开字符设备文件时,驱动程序会创建并注册相应的虚拟设备接口,以tunX或tapX命名。应用程序关闭设备文件时,驱动程序会删除tunX和tapX网络虚拟设备,并删除建立起来的路由信息。
两个设备的不同点:
- tap是一个二层网络设备,只能处理二层的以太网帧,可以与物理网卡做桥接
- tun是一个点对点的三层网络设备,只能处理处理三层的IP数据包,无法与物理网卡做桥接,可以通过三层交换方式与物理网卡连通。Linux下的隧道协议基于该tun设备实现,如ipip、gre。
1 | ┌──────────────┐ |
tun设备应用举例
1 | ┌──────────────┐ ┌──────────────┐ |
应用程序A要发送数据到其他物理机192.168.1.100,由于物理网络环境下只有10.1.1.11和10.1.1.100是相互连通的,192.168.1.11和192.168.1.100是不通的,为了192.168.1.11和192.168.1.100能够进行通讯,需要将数据包进行一次封装。
应用程序B是通过打开字符设备文件/dev/net/tun0的方式来打开网络设备
流程如下:
- A构造数据包,目的ip为192.168.1.100,并发送给协议栈
- 协议栈根据数据包中的ip地址,匹配路由规则,要从tun0出去
- 内核协议栈将数据包发送给tun0网络设备
- tun0发送应用程序B打开,于是将数据发送给应用程序B
- B收到数据包后,在用户态构造一个新的数据包,源IP为eth0的IP 10.1.1.11,目的IP为配置的对端10.1.1.100,并封装原来的数据包
- 协议栈根据当前数据包的IP地址选择路由,将数据包发送给eth0