Skip to main content

DPDK

一、DPDK介绍

DPDK 是英文 Data Plane Development Kit 的简写,中文的意思为数据平面开发套件,DPDK的主要目的是在数据平面应用中为快速的数据包处理提供一个简单而完善的架构。在理解此工具集之后,开发人员可以以此为基础进行新的原型设计,或简单地为我所用

二、UIO

UIO(Userspace I/O)是运行在用户空间的I/O技术。Linux系统中一般的驱动设备都是运行在内核空间,而在用户空间用应用程序调用即可,而UIO则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能!使用UIO可以避免设备的驱动程序需要随着内核的更新而更新的问题。 UIO驱动在Linux内核版本2.6.18及以上的版本中被引入。使用UIO驱动可以对硬件进行快速的数据传输和处理,并且可以通过用户空间的应用程序来控制设备

三、IGB_UIO

igb_uio.ko 是UIO的一个实例化,主要使用在DPDK项目上

四、DPDK的环境要求

1.多队列网卡

1)如何查看网卡是否支持多队列

cat /proc/interrupts | grep eth0

如果只有一条结果则不是多队列网卡,如果支持如下图:

2)虚拟机配置多队列网卡

找到虚拟机的vmx文件,该文件记录虚拟机一切信息,包括网卡信息,按照下图修改

2.大页内存支持

1)修改Grub系统启动时预留大页内存

vim /etc/default/grub

在GRUP_CMDLINE_LINUX后面加 default_hugepagesz=1G hungepagesz=1G hugepages=1 hugepagesz=2M hugepages=1024

sudo update-grub 更新grup
reboot 重启

可以使用如下命令查看预留大页内存

cat /proc/meminfo | grep Huge 

2)挂载大页内存

mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge

刚挂载完时/mnt/huge目录是空的,里面没有一个文件,直到有进程使用共享内存方式使用了这个大页系统为止,才会在这个目录下创建大页文件,不挂在也能运行Hello World(不明白) 例如

int main (int argc, char **argv)
{
int fd;
UINT64 addr;

fd = open("/mnt/huge/test_1", O_RDWR | O_CREAT);
if (fd < 0) {
printf("open failed!\n");
return -1;
}

addr = mmap(NULL, 2048, PROT_READ | PROT_WRITE, MAP_SHARED,fd , 0);

printf("addr = %p\n", addr);
return 0;
}

五、编译DPDK

本文用的DPDK版本时20.11.10稳定版本,编译需要使用meson ninja 可以在这里下载 https://core.dpdk.org/download/ 这里选择了20.11.10 系统使用的 Ubuntu 20.04.6 LTS

tar xvf dpdk-20.11.10.tar.xz
make gcc g++ gdb python libnuma-dev meson ninja-build cmake libbsd-dev libpcap-dev libjansson-dev libelf-dev
cd dpdk-stable-20.11.10
meson build
cd build
ninja
ninja install

可以使用如下命令检查是否安装成功

pkg-config --modversion libdpdk

也许需要配置

export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig

六、编译igb_uio

20.11版本以后DPDK将igb_uio代码移除。可以从 https://git.dpdk.org/dpdk-kmods/ 下载编译安装

git clone git://dpdk.org/dpdk-kmods
cd dpdk-kmods/linux/igb_uio
make

编译完成之后将会生成 igb_uio.ko 驱动文件

七、加载驱动

modprobe uio
insmod igb_uio.ko
lsmod | grep uio //查看是否加载成功

八、绑定网卡

绑定网卡需要先关闭网卡

cd dpdk-stable-20.11.10 进入DPDK目录
sudo ifconfig ens160 down 关闭网卡
sudo python3 ./usertools/dpdk-devbind.py --bind=igb_uio ens160 //或者使用ID0000:03:00.0
sudo python3 ./usertools/dpdk-devbind.py --status 查看状态

运行 Example(Hello World)

参数

  -c mask 核心的掩码,如果使用0号CPU 掩码为0x01 使用0号和1号CPU 掩码为0x11,依次类推
-n mask NUMA的ID 暂时没弄明白

可以直接执行,也会自己探测需要使用root权限,不挂载大页目录也可以运行

运行 App dpdk_testpmd

命令行解释

--:此为EAL参数和testpmd自有参数的分隔符,--前面为EAL参数,--后面为testpmd应用程序自身的参数
-i: -i 或者 --interactive 运行dpdk_testpmd在交互模式下

最简单的启动方式为

sudo ./build/app/dpdk-testpmd -- -i

带参数的启动:–l 选项指定了逻辑核 -n 选项用于指定系统的内存通道数

sudo ./build/app/dpdk-testpmd -l 0,1 -n 4 -- -i

进入命令行之后的交互命令

显示某个端口的收发状态

show port stats 0 

显示某个端口的信息

show port info 0 

设置转发模式

set fwd io  IO模式
set fwd rxonly
set fwd txonly

查看转发模式

show config fwd

查看端口的转发状态

show port stats all

转发模式

  • io mode(输入/输出模式):通常也被称为 IO 模式,是最常用的转发模式,也是 TestPMD 启动时的默认模式。在该模式下,CPU 从一个端口接收数据包(Rx),并将其发送到另一个端口(Tx)。如果需要的话,一个端口可同时用于接收和发送。
  • rxonly mode(收包模式):在此模式下,TestPMD 会轮询 Rx 端口的数据包,然后直接释放而不发送,以这种方式充当数据包接收器。
  • txonly mode(发包模式):在此模式下,TestPMD 生成 64Byte 的 IP 数据包,并从 Tx 端口发送出去。不接收数据包,仅作为数据包的发送源。
  • mac mode:在转发报文前修改报文的 src MAC 地址和 dst MAC 地址。默认的行为是将 src MAC 地址设置为转发接口的 MAC 地址,将 dst MAC 地址设置为预设的 MAC 地址,可以通过 eth-peer 或 - eth-peers-configfile 命令参数,在程序启动时配置预设 MAC 地址。目前还不支持对 src MAC 地址进行预设。
  • macswap mode:MAC 交换转发模式,在转发报文之前交换报文的 src MAC 地址和 dst MAC 地址。
  • flowgen mode:多数据流生成模式,根据不同的 dst IP 地址生成一组数据流,同时终结接收到的流量。
  • csum mode:根据报文的 offload 标记,通过硬件或软件方法修改报文的 checksum 字段。
  • icmpecho mode:接收一组报文,查找是否有 ICMP echo 请求,如果有,就回应 ICMP echo reply。
  • ieee1588 mode:演示对 Rx 和 Tx 基于 L2 IEEE1588 V2 PTP 时间同步特性,需要配置 CONFIG_RTE_LIBRTE_IEEE1588=y。
  • softnic mode:演示软网卡的转发操作,在此模式下,报文转发和 I/O 模式相似,区别在于实际上报文只在 loopback 软网卡接口上转发。因此,portmask 参数只能设置为软网卡端口。各种基于 softnic 固件(DPDK packet framework script)指定的自定义 NIC 软件网卡可以在此模式下进行测试,除此之外,还可以通过 CLI 使能,生成 5 级的 QoS 调度器作为默认的选项。用户可以修改默认的调度器或者通过 CLI 指定新的 QoS 调度器,此模式需要配置 CONFIG_RTE_LIBRTE_PMD_SOFTNIC=y。
  • noisy mode:噪音环境模拟,模拟多个真实客户机器的行为,接收和发送 VNF(Virtual Network Function)报文

程序开发