数据平面开发套件DPDK(Data Plane Development Kit)是一个由多家公司(如6WIND、Intel等)开发的数据平面开发套件,也是一个用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。它不同于Linux系统以通用性设计为目的,而是专注于多核架构上网络应用中数据包的高性能处理。
DPDK软件架构
DPDK主要由一系列用户态基础软件及少量内核态模块组成,软件架构如图1所示。
图1 DPDK软件架构
- 最底部的内核态(Linux Kernel)DPDK有两个模块:KNI与IGB_UIO。
- KNI(Kernel NIC Interface)提供给用户一个使用Linux内核态的协议栈,以及传统的Linux网络工具(如ethtool、ifconfig)(DPDK本身没有协议栈)。KNI是DPDK允许用户态和内核态交换报文的解决方案,模拟了一个虚拟的网口,提供DPDK的应用程序和Linux内核之间通讯。KNI接口允许报文从用户态接收后转发到Linux协议栈去。
- IGB_UIO(igb_uio.ko和kni.ko.IGB_UIO)则借助了UIO技术,在初始化过程中将网卡硬件寄存器映射到用户态。
- DPDK的上层用户态由很多库组成,主要包括核心部件库(Core Libraries)、平台相关模块(Platform)、网卡轮询模式驱动模块(PMD-Natives&Virtual)、QoS库、报文转发分类算法(Classify)等几大类。
- 核心部件库:该模块构成的运行环境是建立在Linux上,通过环境抽象层EAL(Environment Abstraction Layer)的运行环境进行初始化,包括HugePage内存分配、内存/缓冲区/队列分配与无锁操作、CPU亲和性绑定等;其次,EAL实现了对操作系统内核与底层网卡I/O操作的屏蔽(I/O旁路了内核及其协议栈),为DPDK应用程序提供了一组调用接口,通过UIO或VFIO技术将PCI设备地址映射到用户空间,方便了应用程序调用,避免了网络协议栈和内核切换造成的处理延迟。另外,核心部件还包括创建适合报文处理的内存池、缓冲区分配管理、内存拷贝、以及定时器、环形缓冲区管理等。
- 平台相关模块:其内部模块主要包括KNI、能耗管理以及IVSHMEM接口。其中KNI模块主要通过kni.ko模块将数据报文从用户态传递给内核态协议栈处理,以便用户进程使用传统的socket接口对相关报文进行处理;能耗管理则提供了一些API,应用程序可以根据收包速率动态调整处理器频率或进入处理器的不同休眠状态;IVSHMEM模块提供了虚拟机与虚拟机之间,或者虚拟机与主机之间的零拷贝共享内存机制。当DPDK程序运行时,IVSHMEM模块会调用核心部件库API,把几个HugePage映射为一个IVSHMEM设备池,并通过参数传递给QEMU,这样,就实现了虚拟机之间的零拷贝内存共享。
- 轮询模式驱动模块:PMD相关API实现了在轮询方式下进行网卡报文收发,避免了常规报文处理方法中因采用中断方式造成的响应延迟,极大提升了网卡收发性能。此外,该模块还同时支持物理和虚拟化两种网络接口,从仅仅支持Intel网卡,发展到支持Cisco、Broadcom、Mellanox、Chelsio等整个行业生态系统,以及基于KVM、VMware、XEN等虚拟化网络接口的支持。
- DPDK还定义了大量API来抽象数据平面的转发应用,如ACL、QoS、流分类和负载均衡等。
- 除以太网接口外,DPDK还在定义用于加解密的软硬件加速接口(Extensions)。
DPDK报文收发原理
传统的报文接收方式中,当网卡接收到报文后会产生硬件中断,进而报文通过协议栈到达应用层,这个过程需要内核协议栈的处理。而DPDK改变了这一流程。应用层通过while死循环的方式,调用DPDK提供的接口(如rte_eth_rx_burst)轮询接收来自网卡的报文,这种方式绕过了内核协议栈,实现了内核旁路。通过轮询的方式,报文不经过内核,从而提高了网络转发性能,同时也降低了内核与用户态系统调用的开销。

- DPDK在网卡收到包后通过EAL旁路绕过内核协议栈直达用户空间。精简数据包从NIC到用户空间应用程序之间的移动路径。另外,从这个图中可以看到DPDK应用程序的大部分的生命活动周期处于用户态空间。
- EAL即环境抽象层,为应用提供了一个通用接口,隐藏了与底层库与设备打交道的相关细节。EAL实现了DPDK运行的初始化工作,基于大页表的内存分配,多核亲缘性设置,原子和锁操作,并将PCI设备地址映射到用户空间,方便应用程序访问。
- Buffer Manager API通过预先从EAL上分配固定大小的多个内存对象,避免了在运行过程中动态进行内存分配和回收来提高效率,常常用作数据包buffer来使用。
- Queue Manager API以高效的方式实现了无锁的FIFO环形队列,适合与一个生产者多个消费者、一个消费者多个生产者模型来避免等待,并且支持批量无锁的操作。
- Flow Classification API通过Intel SSE基于多元组实现了高效的hash算法,以便快速的将数据包进行分类处理。该API一般用于路由查找过程中的最长前缀匹配中,安全产品中根据Flow五元组来标记不同用户的场景也可以使用。
- PMD(NIC Poll Mode Library—nic轮询模式库)则实现了Intel 1GbE、10GbE和40GbE网卡下基于轮询收发包的工作模式,大大加速网卡收发包性能。
关于DPDK的更多信息请参见DPDK官方网站查看。