络虚拟化
理解虚拟 卡的要旨
你要知道,一块 卡就是一道门,一个接口,它上面一般接协议栈,下面一般接介质。最关键的是,你要明确它们确实在上面和下面接的是什么。
由于 卡的上接口在OS中实现,或者使用PF技术在用户态实现,总而言之,它们是软的,这就意味着你可以任意实现它们。反之,下接口便不受机器运行软件的控制了,你无法通过软件改变双绞线的事实,不是吗此,我们一般关注 卡下面接的是什么,是什么呢且将它叫做endpoint吧。在开始正文之前,我先列举几个常见的endpoint:
以太 ETHx:普通双绞线或者光纤;
TUN/TAP:用户可以用文件句柄操作的字符设备;
IFB:一次到原始 卡的重定向操作;
VETH:触发虚拟 卡对儿peer的RX;
VTI:加密引擎;
…
关于数据在宿主 卡和虚拟 卡之间的路由(广义的路由),有很多方式,在早期的内核中,对bridge(Linux的bridge也算是一种虚拟 卡)的支持是靠一个在netif_receive_skb中硬编码调用的一个br_handle_frame_hook钩子来实现的,这个钩子由bridge模块注册。但是随着虚拟 卡种类的越来越多,总不能每一种都硬编码这么一种钩子,这样会使得netif_receive_skb显得太臃肿,因此一种新的方式被提出来了,事实上很简单,就是将这种钩子向上抽象了一层,不再硬编码,而是统一在netif_receive_skb中调用唯一的一个rx_handler的钩子。具体如何设置这种钩子,就看这个宿主 卡需要绑定哪种类型的虚拟 卡了,比如:
对于bridge:调用netdev_rx_handler_register(dev, br_handle_frame, p),在netif_receive_skb中调用的是br_handle_frame;
对于bonding:调用netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave),在netif_receive_skb中调用的是bond_handle_frame;
对于MACVLAN:调用netdev_rx_handler_register(dev, macvlan_handle_frame, port),在netif_receive_skb中调用的是macvlan_handle_frame;
对于IPVLAN:调用netdev_rx_handler_register(dev, ipvlan_handle_frame, port),在netif_receive_skb中调用的是ipvlan_handle_frame;
对于…
每一块宿主 卡只能注册一个rx_handler,但是 卡和 卡却可以叠加。
VETH虚拟 卡技术
在具体的执行上,通过下面的命令,你可以创建一个MACVLAN 卡,它是基于eth0虚拟出来的:
ip link add link eth0 name macv1 type macvlan
你可以认为有人将双绞线“物理上”每根一分为二,接了两个水晶头,从而连接了两块 卡,其中一块是虚拟的MACVLAN 卡。但是既然共享介质,难道不用运行CSMA/CD吗然不用,因为事实上,最终的数据是通过eth0发出的,而现代的以太 卡工作的全双工模式,只要是交换式全双工(某些标准而言,这是必须的),eth0自己能做好。
现在可以说一下MACVLAN技术构建的虚拟 卡的模式了。之所以MACVLAN拥有所谓的模式,是因为相比VETH,它更是将复杂性建立在了一个已经容不下什么的以太 概念上,因此相互交互的元素就会太多,它们之间的关系不同,导致最终MACVLAN的行为不同。还是图解的方式:
1.bridge模式
VEPA模式我后面会专门讲。现在要知道的是,在VEPA模式下,即使是MACVLANeth1和MACVLANeth2同时配在在eth0上,它们两者之间的通信也不能直接进行,而必须通过与eth0相连的外部的交换机协助,这通常是一个支持“发夹弯”转发的交换机。
3.private模式
对于以太 卡而言,硬件上根本就不需要任何修改,软件驱动修改即可,对于交换机而言,需要修改的很少,只要在MAC/Port映射表查询失败的情况下,将数据包广播到包括入口的所有端口即可,对于STP协议,也是类似的修改。对于HP而言,发出VEPA是一个正确的选择,因为它不像Cisco和Intel那样,可以大量生产 卡和设备,从而控制硬件标准。对于支持VEPA的交换机而言,仅仅需要支持一种“发夹弯”的模式就可以了。爆炸!
IPVLAN虚拟 卡技术
这个小节我们来看下IPVLAN。在理解了MACVLAN之后,理解IPVLAN就十分容易了。IPVLAN和MACVLAN的区别在于它在IP层进行流量分离而不是基于MAC地址,因此,你可以看到,同属于一块宿主以太 卡的所有IPVLAN虚拟 卡的MAC地址都是一样的,因为宿主以太 卡根本不是用MAC地址来分流IPVLAN虚拟 卡的流量的。具体的流程如下图所示:
又要用到“万能的bridge”。这是多么的麻烦,这是多么的可悲。
正如MACVLAN替代VETH+Bridge一样,稍微该一下的MACVLAN也能替代TAP+Bridge,很简单,那就是将rx_handler实现修改一下,宿主以太 卡收到包之后,不交给MACVLAN的虚拟 卡上接口连接的协议栈,而是发到一个字符设备队列。很简单吧,这就是MACVTAP!

遗憾的多队列TUN/TAP虚拟 卡技术
这是老湿在2014年的时候做的,其实只是做了一些移植和修改工作。但是发现有了MACVTAP之后,我的这个版本瞬间就被爆了。遗憾!向之所欣,俯仰之间,已为陈迹。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!