由于前些日子的工作,恶补了网络知识,主要是二三层的东西,让自己学到不少东西,虽然现在工作内容可能又开始有调整了,心里有点不舒服。
不谈有的没的了,在这里写点东西来记一下一些知识点。首先从Tap/Tun设备说起吧。
Tap/Tun设备是一个虚拟网络设备,和场景的物理网络设备NIC一样,有两个接口,或者说是双方向一个数据通道,数据可以从任意一段流向另一端。
它们的主要区别就是,Tap模拟了一个二层设备,数据流是数据链路上的数据报;而Tun模拟了一个三层设备,数据流是网络层的IP数据报。
其余它们的实现相似。
我们以Tap设备举例。它主要需要实现两个东西,分别是用户态的数据提交给内核态,还有一个就是虚拟的网卡驱动。
有了这两个东西,就能实现用户态的数据到内核态,并且写入内核的协议栈的链路,实现其实现的功能。
功能主要在于,用户态通过Tap设备写入的数据,会进入内核的协议栈,由其它的进程接收;同时其它进程写入协议栈的数据,会经由虚拟网卡,提交至读该设备的进程,实现了数据在设备和网络协议栈的通路。
再总结一下,就是Tap设备可以做一个隧道,实现用户态把数据报注入到内核的协议栈;同时内核协议栈的数据可以通过虚拟网卡由用户态进程截获。
听着其实挺抽象的,其实这也算是vpn的一种实现。首先在机器上创建一张虚拟网卡,设置一个ip,同时将目标网段的发送指向该网卡。那么所有发往该网段的数据都会经由协议栈发往该网卡。应用层vpn的程序收到之后,做一些处理,比如加密什么的,再经由物理端口将数据报发送出去至远端的目标网络。
远端的vpn程序收到该数据包之后,进行解封装工作,再将该数据报写入Tap设备中,注入内核协议栈,交由对应的目标程序进行处理。 (印象中的总结,后续有错会进行修正)
Tap设备使用字符设备来进行用户态至内核态的数据投递,所以它实现了一个字符设备的驱动。当字符设备上有写入的时候,字符设备的驱动程序会被调度,从用户态拷贝一份数据至内核态,转为网卡驱动的skb数据交由tcp协议栈进行处理。
读取过程相似。对端通过用户层socket api将数据写入协议栈,协议栈会将数据转为skb交由虚拟网卡处理。虚拟网卡在获得了skb数据之后将其加入skb链表,唤醒在读取对应字符设备的进程进行读取。字符设备驱动则一个接一个读取skb链表数据,将其交由用户态进程读取。