在neutron中核心部分是对二层物理网络的抽象和管理。原来传统网络的形式是服务器承载操作系统,操作系统上部署一些上层功能(fire wall、application server、Database server)。然后通过物理网卡传递流量(traffic)——>物理交换机——>路由器。
当虚拟化技术出现,对于物理设备的利用率变高了。上述所有的服务,均可部署在虚拟机里。虚拟机之间也需要通讯,从而虚拟网络的概念就诞生了。对于二层的虚拟化:vswitch、vNIC。
在Linux中的虚拟网络设备
(1)TAP/TUN/VETH
TAP/TUN是linux内核实现的一队虚拟网络设备,TAP工作在二层,TUN工作在三层。Linux内核通过TAP/TUN设备向邦定该设备的用户空间发送数据。
struct tun_struct { char name[8]; // 设备名 unsigned long flags; // 区分tun 和 tap 设备 struct fasync_struct *fasync; // 文件异步通知结构 wait_queue_head_t read_wait // 等待队列 struct net_device dev; // Linux抽象设备结构 struct sk_buff_head txq; // 网络缓冲区 struct net_device_stats stats; // 网卡状态信息结构 };
从数据结构上看tap和tun的定义是同一个。但工作的网络层却不同。数据链路层的协议中,tap只能对应其中一种:以太网协议。所以tap也称虚拟以太设备。应用程序使用read()/write()操作使tap接受和发送数据给linux网络协议栈。
tun是一个网络层的点对点的设备,linux原生支持的三层隧道。也需要配置ip等等。
VETH pair 是成对出现的。需要跟namespace一起配合。不然是没有意义的。送到一端请求发送的数据总是从另一端以请求接受的形式出现。该设备不能被用户程序直接操作,但使用起来比较简单。创建并配置正确后,向其一端输入数据,VETH 会改变数据的方向并将其送入内核网络核心,完成数据的注入。在另一端能读到此数据。
(2)Bridge
可以看做是虚拟的二层交换设备。其他的Linux网络设备可以绑定在Bridge上,作为从设备。将这些设备虚拟化为端口。从物理角度看,就是我们把从设备连接在Bridge上。
在内核程序里,netdev_rx_handler_register()被调用, 一个用于接受数据的回调函数被注册。以后每当这个从设备收到数据时都会调用这个函数可以把数据转发到 Bridge 上。当 Bridge 接收到此数据时,br_handle_frame()被调用,进行一个和现实世界中的交换机类似的处理过程:判断包的类别(广播/单点),查找内部 MAC 端口映射表,定位目标端口号,将数据转发到目标端口或丢弃,自动更新内部 MAC 端口映射表以自我学习。
Bridge本身是有一个隐藏mac地址(直接接受linux内核栈的数据)和隐藏虚拟网卡(bridge0)的。所以我们可以直接给网桥设置ip。所以挂载在Bridge上的从设备ip都不需要配置,如果挂载前从设备是存在ip的,挂载后ip会失效。网络协议栈顶层只能看到Bridge,Bridge上的挂载的设备对它是隐藏的。
找了一个图,作为虚拟设备工作流程的参考。
详细解释:https://www.ibm.com/developerworks/cn/linux/1310_xiawc_networkdevice/index.html