发明内容
本发明要解决的技术问题是提供一种内核态虚拟网络设备的建立方法、及其包发送和接收方法,既避免了不必要的内核态/用户态切换开销和内核态/用户态数据拷贝开销,又具有较高的可扩展性和可操作性。
根据本发明的一个方面,提供一种内核态虚拟网络设备的建立方法,包括:步骤1、虚拟机监控机扫描虚拟机用户态调用参数,对于参数中给出的每个虚拟网络设备,保存该虚拟网络设备的基本配置;步骤2、位于用户态的虚拟机监控机在初始化虚拟机上下文时,初始化虚拟机上下文内核态锁;和步骤3、来宾机的虚拟网络设备初始化过程中,在映射该设备的I/O端口或I/O内存映射地址时,根据所述虚拟网络设备基本配置,向内核注册虚拟网络设备结构。
可选的,步骤1中,所述基础配置包括:虚拟网卡类型、虚拟网卡MAC地址和虚拟网卡对应的虚拟DHCP信息中的一个或多个;
所述虚拟网卡对应的虚拟DHCP信息包括:主机IP、虚拟DHCP服务器IP、DNS IP和网关IP中的一个或多个。
可选的,步骤3中,虚拟网络设备结构除包含所述基本配置外,还包含该设备的I/O端口或I/O内存映射地址。
可选的,步骤3后还包括:步骤4、宿主机内核加载时,为无锁化零拷贝接收环和无锁化零拷贝发送环开辟内存区域;步骤5、宿主机内核加载时,针对无锁化零拷贝接收环、发送环的每个页,对相应的各级页表项的USER位进行置位操作,从而用户态网络包调度程序能够访问所述无锁化零拷贝接收环、发送环;步骤6、用户态网络包调度程序启动时,通过一个系统调用获取以上无锁化零拷贝接收环和无锁化零拷贝发送环的起始地址,而标识无锁化零拷贝接收环和无锁化零拷贝发送环的头结构根据起始地址和偏离量计算。
可选的,每个无锁化零拷贝接收/发送环为环结构,包含一个头指针和一个尾指针;当系统中的进程要往无锁化环中追加网络包时,先检查无锁环是否已满,判断条件为:头指针==(尾指针+环长度+1)%环长度;如果已满则丢弃该包,否则按照尾指针的指示将网络包的内容和接口标识作为环的一项添入环中,并且计算新的尾指针:尾指针=(尾指针+1)%环长度;当系统中的进程要从环中读取网络包时,先检查环是否为空,判断条件为:头指针==尾指针;如果为空,则放弃读取操作,否则按照头指针的指示将网络包的内容和接口标识从环中读出,并计算新的头指针:头指针=(头指针+1)%环长度。
根据本发明另一个方面,提供一种基于内核态虚拟网络设备的网络包接收方法,包括:步骤1、当网络包从外接物理网卡经过网桥设备进入TAP设备后,内核将该包和该包的进入接口合并成一个数据段填充入与此物理网卡对应的接收环;步骤2、网络包调度程序直接从接收环获取网络包的内容和其进入接口标识,并按预定的调度算法进行处理;步骤3、网络包调度程序将待发送的网络包和目的接口合并成一个数据段填充到发送环;和步骤4、位于内核的发送处理线程读取发送环,并将网络包按照发送接口标识送达目的地。
可选的,在步骤1之前还包括:在宿主机操作系统内核启动时,根据外接物理网卡的个数在宿主机内核中创建多个TAP设备;在宿主机操作系统初始化时,为每个TAP设备建一个网桥设备BRIDGE,将TAP设备和对应的外接物理网卡一起链接到网桥设备上。
可选的,所述接收环为无锁化零拷贝接收环,所述发送环为无锁化零拷贝发送环。
根据本发明又一个方面,还提供一种基于内核态虚拟网络设备的网络包发送方法,包括:步骤1、内核从虚拟网络设备的发送环中读取待发送网络包,更新虚拟网络设备状态,并将网络包和该网络设备对应的接口号合并成一个数据段填充入接收环;步骤2、位于用户态或内核态的网络包调度程序直接从接收环获取网络包的内容和其进入接口标识,并按预定的调度算法进行处理;步骤3、位于用户态或内核态的网络包调度程序将待发送的网络包和目的接口合并成一个数据段填充到发送环;和步骤4、位于内核的发送处理线程读取发送环,并将网络包按照发送接口标识送达目的地。
可选的,步骤1之前还包括:当虚拟机监控机在宿主操作系统内核中处理来宾机发起的I/O端口读写或I/O内存读写时,将读写地址与注册的I/O端口或I/O内存映射地址进行比较;如果读写地址落在所述I/O端口或I/O内存映射地址之内,将读写地址和I/O端口或I/O内存地址进行比较,判断操作类型;如果操作类型为读写虚拟网络设备的状态寄存器,则对虚拟网络设备位于内核的虚拟状态寄存器进行读写,将结果返回。
可选的,所述虚拟网络设备为VIRTIO或E1000。
可选的,所述步骤4还包括:步骤4.1、判断该网络包是否发送外网口;步骤4.2、如果是发送往外网口,匹配外网口与TAP设备,并将网络包挂入与该TAP设备对应的队列中;和步骤4.3、如果是发往本地的虚拟机,将网络包挂入与虚拟网络设备对应的网络包队列中,并唤醒与此虚拟网卡对应的网络包处理线程,与此虚拟机对应的网络包处理线程将包的内容拷贝到虚拟网卡接收环中,并更新相关寄存器。
可选的,所述接收环为无锁化零拷贝接收环,所述发送环为无锁化零拷贝发送环。
与现有技术相比,本发明优点在于:
(1)内核化网络仿真基础设施对关键虚拟化设备的模拟全在内核态实现,虚拟化CPU因I/O操作退出虚拟状态后会立即在内核态完成相关功能并重返虚拟状态。对仿真节点产生以及拟发往仿真节点的网络包的处理大部分在内核态完成,并以内存零拷贝的方式对用户态控制程序开放处理接口,进而避免了不必要的内核态/用户态切换开销和内核态/用户态数据拷贝开销。
(2)进一步的,内核化网络仿真基础设施(即由虚拟机构成的网络仿真器的网络包获取、分析和交付机制)通过网络包环的方式实现网络包无锁化并行处理。
具体实施方式
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图,对本发明进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
在本发明中,对于具有虚拟机的宿主机,CPU运行的模式涉及(1)客户模式即来宾态,以及(2)非客户模式;其中所述非客户模式包括内核态和用户态。
其中,来宾机为运行在虚拟机上的虚拟机操作系统。
如图1所示,在传统虚拟机中,虚拟机的虚拟网络设备(图中表示为虚拟网卡)建立并运行在宿主机的内核态和用户态,虚拟网络设备处理程序位于用户态。虚拟机的网络数据发送给虚拟网卡,虚拟网卡与TAP设备绑定,虚拟网卡将网络数据发送给TAP设备的带锁包队列;另一方面,宿主机的物理网卡通过网桥与TAP设备绑定,并将进出物理网卡的网络数据发送给对应的TAP设备的带锁包队列;通过运行在宿主机用户态的网络包调度单元(即网络包调度进程)进行网络包的转发,实现虚拟网卡(通过TAP设备)与物理网卡之间的通信。
当来宾机读写虚拟网络设备寄存器时,运行来宾机的CPU会首先退出来宾模式(非根模式)进入根模式,再由根模式的内核态返回用户态,再进行相关处理,如网络包发送/虚拟寄存器读写等。这种模式将导致大量非必要的CPU状态切换和内核态/用户态数据拷贝。
发明人经过研究发现,如果将虚拟网络设备建立在宿主机内核态,当来宾机读写虚拟网络设备寄存器时,运行来宾机的CPU会首先退出来宾模式(非根模式)进入根模式,并在根模式的内核态直接进行处理,从而避免了虚拟网络设备处理过程向用户态的切换。
基于上述分析,根据本发明一个实施例,提供一种内核态虚拟网络设备建立方法。如图2所示,该方法包括:
S101、虚拟机监控机(虚拟机监控机运行在宿主机上)扫描虚拟机用户态调用参数,对于参数中给出的每个虚拟网络设备,在虚拟机用户态程序中开辟一块内存暂时存放该虚拟网络设备的基本配置。
该基础配置包括例如:虚拟网卡类型、虚拟网卡MAC地址、虚拟网卡对应的虚拟DHCP信息(包括主机IP,虚拟DHCP服务器IP,DNS IP,网关IP)。虚拟网卡对应的虚拟DHCP信息用于当来宾机向虚拟网卡发DHCP请求时,虚拟网卡回应给来宾机的DHCP回复,使来宾机能够对IP等信息进行正确的设置。
S102、位于用户态的虚拟机监控机在初始化虚拟机上下文时,通过ioctl接口初始化虚拟机上下文内核态锁。
以全内核virtio虚拟化网络设备为例,因为虚拟化网络设备的网络包发送和网络接收过程由不同进程完成,其中涉及对共享数据结构的读写操作,所以需用锁机制来保护。
当虚拟机监控机在准备外设相关数据结构时,发现了与virtio虚拟化网络设备有关的配置,于是针对涉及的每一个virtio虚拟化网络设备在内核中为其初始化一个内核态锁。
S103、来宾机的虚拟网络设备初始化过程中,在映射该设备的I/O端口或I/O内存映射地址时,根据S101中得到的对应虚拟网络设备基本配置,向内核注册虚拟网络设备结构。
根据本发明的一个实施例,虚拟网络设备结构除包含S101中得到的基本配置外,还包含该设备的I/O端口或I/O内存映射地址;宿主操作系统(host operating system)内核对于其支持的每个虚拟网卡都维护一个包括虚拟网络设备配置的数据结构。
以全内核virtio虚拟化网络设备的为例进一步描述内核态虚拟网络设备建立方法如下。启动虚拟机的命令行参数除了通常的参数外,还需附加:
-net nic,
model=virtio,
macaddr=00:30:11:00:00:01,hostip=192.168.0.224/24,
serverip=192.168.0.1,dnsip=159.226.39.1,
gatewayip=192.168.0.222,kvmindex=1。
其中,model指定全内核虚拟化网络设备使用virtio设备,macaddr指定虚拟机的MAC地址,hostip、serverip、dnsip、gatewayip等指定客户机操作系统能够通过DHCP协议获取的主机IP地址、服务器IP地址、DNS IP地址以及网关的IP地址,vmindex标识该虚拟化网络设备在虚拟机所在宿主操作系统的序列号。
model、macaddr、hostip、kvmindex等信息在虚拟机启动之初用ioctl系统调用传入内核,并放置在nicarray[kvmindex]结构中,并将nicarray[kvmindex]的地址链入与虚拟机对应的kvm的nic_list链表中,如图3所示。
宿主机虚拟机相关用户态代码在来宾机操作系统启动过程中,将virtio虚拟化网络设备的I/O端口寄存器基地址截获,并通过ioctl系统调用传入内核,放置位置也在nicarray结构中,过程与图3类似。
发明人还发现,以零拷贝发送、接收环的形式向运行在用户态的网络仿真部件提供高效的交互接口,网络仿真部件直接对位于内核态的零拷贝环进行无锁化读写,可以避免不必要的内核态/用户态间数据拷贝。
基于上述分析,根据本发明的一个本实施例,还提供一种无锁化零拷贝接收/发送环,作为网络包调度单元和虚拟、物理网卡之间传输数据的通道,以实现网络包无锁化并行处理。如图4所示,每个无锁化零拷贝接收/发送环包含一个头指针和一个尾指针。
当系统中的进程要往无锁化环中追加网络包时,先检查无锁环是否已满:
IF(头指针==(尾指针+环长度+1)%环长度)。
如果已满则丢弃该包,否则按照尾指针的指示将网络包的内容和接口标识作为环的一项添入环中,并且计算新的尾指针:
尾指针=(尾指针+1)%环长度。
当系统中的进程要从环中读取网络包时,先检查环是否为空:
IF(头指针==尾指针)。
如果为空,则放弃读取操作,否则按照头指针的指示将网络包的内容和接口标识从环中读出,并计算新的头指针:
头指针=(头指针+1)%环长度。
基于无锁化零拷贝接收/发送环,根据本发明的另一个实施例,内核态虚拟网络设备建立方法在步骤S103之后还包括下述步骤:
(1)宿主机内核加载时,会在数据段为无锁化零拷贝接收环和无锁化零拷贝发送环开辟内存区域(按照预期的无锁化零拷贝接收环的最大数目分配);
(2)宿主机内核加载时,针对无锁化零拷贝接收环、发送环的每个页,对相应的各级页表项的USER位进行置位操作,从而用户态网络包调度程序能够访问所述无锁化零拷贝接收环、发送环;和
(3)用户态网络包调度程序启动时,通过一个系统调用获取以上无锁化零拷贝接收环和无锁化零拷贝发送环的起始地址,而标识无锁化零拷贝接收环和无锁化零拷贝发送环的头结构根据起始地址和偏离量计算。
图5是无锁化环零拷贝机制的初始化过程的一个例子的示意图。内核在启动之初按照预期环的最大个数计算出所需内存大小,而后在内存开辟连续的存储空间,该存储空间对应的物理页大小为2M,然后依次从PML4表项开始逐层对页表的USER位置位,这样以上的连续内存页就可以直接从用户态进行访问了。
使用上述内核态虚拟网络设备建立方法建立的内核态虚拟网络设备的示意图如图6所示。运行多个虚拟机的操作系统根据虚拟化网络设备(即虚拟网卡)的数目配置有相应数量的无锁化零拷贝接收环,当虚拟机的客户操作系统执行外发网络包操作时,全内核虚拟网络设备根据外发指令构造出外发网络包,并将其内容填充入与该虚拟网络设备对应的无锁化零拷贝接收环。运行在内核态或用户态的包调度进程(即网络包调度单元)(例如:网络仿真器核心调度程序),以轮询的方式从多个无锁化零拷贝接收环中获取网络包的内容和对应接口标识。
包调度进程根据调度算法(算法由具体需求决定,例如可模仿路由器的调度机制)转发和生成网络包,并将网络包和目的接口标识填充入无锁化零拷贝发送环。本实施例中,该无锁化零拷贝发送环是唯一的;在本发明的其他实施例中,无锁化零拷贝发送环的数量是可配置的。
位于内核的网络包发送处理线程轮询无锁化零拷贝发送环,并将包的内容按照目的接口标识发往虚拟网络设备或对外接口。
下面将结合实施例描述基于上述内核态虚拟网络设备的网络包调度方法,其包括:基于内核态虚拟网络设备的网络包发送方法和基于内核态虚拟网络设备的网络包接收方法。
根据本发明的一个实施例,如图7所示,提供一种基于内核态虚拟网络设备的网络包接收方法:
S301、在宿主机操作系统内核启动时,根据外接物理网卡的个数在宿主机内核中创建多个TAP设备;
S302、在宿主机操作系统初始化时,为每个TAP设备建一个网桥设备BRIDGE,将TAP设备和对应的外接物理网卡一起链接到网桥设备上;
S303、当网络包从外接物理网卡经过网桥设备进入TAP设备后,内核将该包和该包的进入接口(即TAP号)合并成一个数据段填充入无锁化零拷贝接收环(与此物理网卡对应的无锁化零拷贝接收环);环的填充依据是环头部信息中的尾指标,填充完毕后将更新尾指标。
S304、网络包调度程序直接从无锁化零拷贝接收环获取网络包的内容和其进入接口标识,并按预定的调度算法进行处理。
具体的,网络包调度程序跟据环头结构里的头指标直接对相关无锁化零拷贝接收环进行读取,读取的依据是环头部信息的头指标,读取完毕后更新相应的头指标;然后按预定的调度算法进行处理。
S305、网络包调度程序将待发送的网络包和目的接口合并成一个数据段填充到无锁化零拷贝发送环。
具体的,网络包调度程序跟据发送环头结构里的尾指标直接对相关无锁化零拷贝发送环进行填充,填充的依据是环头部信息的尾指标,读取完毕后更新相应的尾指标。
S306、位于内核的发送处理线程读取无锁化零拷贝发送环,并将网络包按照发送接口标识送达目的地。
一个宿主机中一般只存在一个发送处理线程,其轮询全系统无锁化零拷贝发送环,并按照发送接口标识将网路包或是交付相应的虚拟网卡处理进程(每个虚拟网卡对应一个处理进程负责将外部的网络包送入来宾机)或是发送到物理网卡对应的TAP设备上。
根据本发明的一个实施例,提供一种基于内核态虚拟网络设备的网络包发送方法,如图8所示,包括:
S201、当虚拟机监控机在宿主操作系统内核中处理来宾机发起的I/O端口读写或I/O内存读写时,将读写地址与步骤S103注册的I/O端口或I/O内存映射地址进行比较;
S202、如果读写地址落在所述I/O端口或I/O内存映射地址之内,将读写地址和I/O端口或I/O内存地址进行比较,判断操作类型;
S203、如果操作类型为读写虚拟网络设备的状态寄存器,则对虚拟网络设备位于内核的虚拟状态寄存器进行读写,将结果返回,CPU重新回到客户模式。
S204、如果操作类型为发送网络包,则进行网络数据包发送流程;虚拟网络设备包括:VIRTIO或E1000:
(1)当虚拟网络设备是VIRTIO时,网络数据包发送流程包括:内核从该VIRTIO网络设备的发送环中读取待发送网络包,更新VIRTIO网络设备状态,并将网络包和该网络设备对应的接口号合并成一个数据段填充入无锁化零拷贝接收环。VIRTIO网络设备的发送环的结构是传统KVM机制。
(2)当虚拟网络设备是E1000时,网络数据包发送流程包括:内核从该E1000网络设备的发送环中读取待发送网络包,更新E1000网络设备状态,并将网络包和该网络设备对应的接口号合并成一个数据段填充入无锁化零拷贝接收环。
其他类型的内核化虚拟网络设备的网络数据包发送处理流程与上述过程类似。
S205、位于用户态或内核态的网络包调度程序直接从无锁化零拷贝接收环获取网络包的内容和其进入接口标识,并按预定的调度算法进行处理。
具体的,网络包调度程序跟据环头结构里的头指标直接对相关无锁化零拷贝接收环进行读取,读取的依据是环头部信息的头指标,读取完毕后更新相应的头指标;然后按预定的调度算法进行处理。
S206、位于用户态或内核态的网络包调度程序将待发送的网络包和目的接口合并成一个数据段填充到无锁化零拷贝发送环。
具体的,网络包调度程序跟据发送环头结构里的尾指标直接对相关无锁化零拷贝发送环进行填充,填充的依据是环头部信息的尾指标,读取完毕后更新相应的尾指标。
S207、位于内核的发送处理线程读取无锁化零拷贝发送环,并将网络包按照发送接口标识送达目的地。
根据本发明的一个实施例,步骤S207还包括:
S2071、判断该网络包是否发送外网口;
S2072、如果是发送往外网口,匹配外网口与在S301步建立的TAP设备,并将网络包挂入与该TAP设备对应的队列中;
S2073、如果是发往本地的虚拟机,将网络包挂入与虚拟网络设备对应的网络包队列中,并唤醒与此虚拟网卡对应的网络包处理线程,与此虚拟机对应的网络包处理线程将包的内容拷贝到虚拟网卡接收环(此环属于传统KVM中虚拟网卡机制)中,并更新相关寄存器。
下面以全内核virtio虚拟化网络设备的数据包处理为例,对基于内核态虚拟网络设备的网络包发送方法、接收方法进行进一步说明。虚拟机内核态代码在客户机操作系统启动过程中,截获对virtio虚拟化网络设备的I/O配置寄存器的读写,并根据具体的读写在内核态完成相应功能,然后将执行流重新交付客户机操作系统。
如图9所示,所述的截获过程包括:遍历kvm的nic_list链表,并一一比对I/O端口寄存器基地址。例如,如果是对VIRTIO_PCI_QUEUE_PFN寄存器写,则内核化网络设备将nic_list链表的成员里的rx_ring或tx_ring里面的desc、avali和used三个字段进行初始化。
如图10所示,如果是对VIRTIO_PCI_QUEUE_NOTIFY寄存器写,则表明客户机操作系统希望发送网络包,内核根据成员的rx_ring.desc和rx_ring.avail。获取网络包的具体内容,将网络包的具体内容填充入与该虚拟设备对应的零拷贝接收环,然后对rx_ring.used所指向结构进行更新。如前所述,对零拷贝接收环的已填充内容的处理由位于内核态或用户态的包调度程序处理。
客户机操作系统接收网络包的过程主要为:位于内核态或用户态的包调度程序将网络包填充入零拷贝发送环,并指明目的虚拟化网络设备号。如图11所示,位于内核的发送处理线程根据目的虚拟化网络设备号将网络包的内容挂入与虚拟网络设备对应的网络包队列中,并唤醒相应的网络包处理线程。网络包处理线程从网络包队列中摘取网络包的内容,根据成员的tx_ring.desc和tx_ring.avail.获取网络包填入地址序列,并将网络包填充入客户机操作系统内存中,然后对tx_ring.used所指向结构进行更新。此后,客户机操作系统会接收到一个中断,中断处理线程继续对该包进行处理。
本发明上述实施例中,内核化虚拟网络设备处理流程在CPU退出来宾模式后,比较涉及的I/O地址是否落在虚拟化网络设备注册的范围内,如否则按系统默认模式继续处理,如是则全内核虚拟化网络设备区别该操作是发送网络包还是读写网络设备状态寄存器,并按照上述步骤进行处理。从而避免了非必要的CPU状态切换和内核态/用户态数据拷贝的开销。
另外,为了实现无锁化,支撑多个虚拟机的物理节点上根据虚拟化网络设备的数目,配置有相应数量的无锁化零拷贝接收环,另外根据真实外接网络设备的数目,配置相应的数量的无锁化零拷贝接收环,这样物理节点无锁化零拷贝接收环的数量为虚拟化网络设备的数目加上真实外接网络设备的数目。运行在内核态或用户态的包调度进程以轮询的方式从多个无锁化零拷贝接收环中获取网络包的内容和对应接口标识,以零拷贝环的方式进行网络包交互一方面消除了网络包队列带来的锁冲突,另一方面消除了用户态/内核态之间的切换和数据拷贝(如以网络包队列的方式实现相同的功能,则位于用户态的程序必须通过特定的接口进入内核态来对位于内核态的队列进行操作)。
上述网络包调度方法实现高效、低传输时延、低处理器负荷、可扩展、异构兼容的虚拟化网络仿真。其中,高效、低传输时延、低处理器负荷等优点是通过消除不必要的内核态/用户态切换开销和内核态/用户态数据拷贝开销实现的;可扩展、异构兼容等优点是因为本发明内核态虚拟网络设备对虚拟网卡的种类和数目限制较少。
上述网络包调度方法的应用场景包括但不限于以下几种情况:大规模异构化网络仿真实验、网络靶场基础设施、异构化网络软件开发等。
以上实施例仅用以描述本发明的技术方案而不是对本技术方法进行限制,应该注意到并理解,在不脱离后附的权利要求所要求的本发明的精神和范围的情况下,能够对上述详细描述的本发明做出各种修改和改进。因此,要求保护的技术方案的范围不受所给出的任何特定示范教导的限制。