使用pktgen-dpdk和l2fwd测试RFC2544

前言

由于现在5G网络的到来,运营商对云平台网络能力的要求越来越苛刻。在这种环境下NFV架构应运而生,然而如何检测一个营平台基础设施的网络能力成为了验收平台的技术指标关键。RFC2544的转发测试则成为了比较公认的验收标准。这里说转发主要是因为NFV技术场景下二层网络主要是为上层网络应用服务的。而上层的业务主要是是以转发为主,所以测试二层网络转发性能显得尤为重要。

RFC2544的简介这里就不做过多介绍了,简介可以参考我转发的一篇博文:
https://blog.csdn.net/minxihou/article/details/85039842

测试工具

pktgen-dpdk可以理解为启用了dpdk的pktgen网络测试工具。该工具可以产生特定的流量(指定包的源mac地址,源IP,目的mac地址,目的IP,特定包长)并发送到指定的mac,IP上。
l2fwd是在编译好dpdk后,编译目录下example的目录中有的一个测试软件。它主要负责将主机上特定端口的包收到之后进行源链路转发。这两个工具具体的作用会在下面测试模型中说道

测试模型

一般测试模型随着上层逻辑业务场景不同而有所不同这里介绍一种最为简单的测试模型。同时本篇测试用例中也会使用该测试模型进行测试。
在这里插入图片描述

该测试模型是在vhost方式下使用virtio-ovs转发虚机的东西向流量。同时neutron组件启用了iptables安全组。在网络测试中该模型为单网口单条单向流的转发速率测试。在进行openstack虚拟层二层网络性能测试时本模型模拟了同物理主机ovs网桥下流量转发测试。由于不考虑物理网络链路的影响并且虚拟机在同虚拟网段,所以测试的转发性能会是比较接近OVS的理论极限场景。如果两台虚拟机分别在两个计算节点则此测试模型就会进一步考虑到物理网络链路的影响。熟悉网络测试的童鞋可能都知道在启用了dpdk之后ovs的转发性能相比于非dpdk的ovs网络性能有了十倍的提升。这也就是当前很多产商将dpdk引入到自己云产品基础架构的一个原因。

vm1启用了pktgen-dpdk制造特定三层包的流量,目的IP和目的mac地址是vm2 eth1的mac和IP地址。vm2启用了l2fwd,在eth1网卡上接收到了vm1发送的包之后将流量从eth1网卡进行转发,发送到vm1的eth1端口。pktgen-dpdk通过统计发送包的数量和收到包的数量来计算丢包率。在满足设定丢包率(默认pktgen-dpdk的丢包率是0,但是这个非常不好用很容易导致测试的数据不稳定)下得出当前发送包长字节的转发速率。原本RFC2544可以在没有IP的二层包情况下测试,但是pktgen-dpdk指定发送的是三层包,所以在rfc2544_tput_test.lua中会要求写明源IP和目的IP,否则可能无法通过ovs网桥。下面我们用两个虚机来模拟该测试模型。

测试环境配置

vm1将网卡eth1加载dpdk驱动之后通过pktgen-dpdk发送测试包给vm2。vm2虚拟机eth1加入dpdk驱动之后,开启l2fwd程序将vm1的流量回转给vm1。这里建议将ovs的安全组关闭,以防止安全组屏蔽掉l2fwd转发回vm1的流量。
在这里插入图片描述

虚机网络配置

vm1 IP:192.168.21.24
mac:fa:16:3e:d2:4c:04

vm2 IP:192.168.21.25
mac:fa:16:3e:11:f4:27

vm1 配置

pktgen-dpdk配置
当你完成pktgen-dpdk的编译之后,在scripts中有一个适用于rfc2544的测试脚本名为“rfc2544_tput_test.lua”。我们主要对该脚本进行参数配置。

  9 -- define packet sizes to test
 10 local pkt_sizes         = { 64, 128, 256, 512, 1024, 1280, 1518 };#这里定义了要运行发送包的字长,默认就按照2544的定义包长写好了
 11 
 12 -- Time in seconds to transmit for
 13 local duration          = 10000;#表明每轮测试执行的时间
 14 local confirmDuration   = 60000;#表明该轮测试得到的速率确认时间,当程序以某个速率发包得到低于丢包率的收包情况下,pktgen-dpdk会以该速率持续的发包用以确认该速率是否可以持续稳定的低于设定的丢包率。
 15 local pauseTime         = 1000;#本轮测试执行完成之后到下轮测试开始之前的暂停时间
 16 
 17 -- define the ports in use
 18 local sendport          = "0";#设定pktgen-dpdk的发包端口
 19 local recvport          = "0";#设定pktgen-dpdk的收包端口
 20 
 21 -- ip addresses to use
 22 local dstip             = "192.168.21.25";#设定pktgen-dpdk的发包目的IP地址
 23 local srcip             = "192.168.21.24";#设定pktgen-dpdk的源IP地址
 24 local netmask           = "/24";#子网掩码长度
 25 
 26 local initialRate       = 50 ;#初始速率,pktgen-dpdk也是以二分法来递增和递减速率的,建议初始速率以50%开始。
 27 
 28 local function setupTraffic()
 29         pktgen.set_ipaddr(sendport, "dst", dstip);
 30         pktgen.set_ipaddr(sendport, "src", srcip..netmask);
 31         pktgen.set_mac(sendport, "fa:16:3e:11:f4:27");#新增方法,表明pktgen-dpdk对端l2fwd接收端口的mac地址。这里增加这个主要为了避免安全组直接把测试流过滤。
 32         
 33         pktgen.set_ipaddr(recvport, "dst", srcip);
 34         pktgen.set_ipaddr(recvport, "src", dstip..netmask);
 35         
 36         pktgen.set_proto(sendport..","..recvport, "udp");
 37         -- set Pktgen to send continuous stream of traffic
 38         pktgen.set(sendport, "count", 0);
 39 end

dpdk配置
因为pktgen-dpdk是启用了dpdk来进行网络测试的,所以这里也需要将vm1的发包网卡启用dpdk。到dpdk编译完成的路径下执行以下命令让系统加载igb驱动,同时让eth1网卡加载igb驱动。

#modprobe uio
#insmod x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
#insmod x86_64-native-linuxapp-gcc/kmod/rte_kni.ko

使用dpdk-devbind.py脚本检查是否加载成功,当uio成功加载是网卡状态中unused会出现igb_uio的网卡驱动。
./usertools/dpdk-devbind.py --status

Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device 1000' if=eth0 drv=virtio-pci unused=virtio_pci,igb_uio *Active*
0000:00:04.0 'Virtio network device 1000' if=eth1 drv=virtio-pci unused=virtio_pci,igb_uio *Active*

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

将eth1启用dpdk驱动:
# ./usertools/dpdk-devbind.py --force -b igb_uio 0000:00:04.0 #0000:00:04.0表示该网卡的pci序列号
# ./usertools/dpdk-devbind.py --status #检查eth1已经启用了igb_uio,此时ifconfig无法发现该网卡。

Network devices using DPDK-compatible driver
============================================
0000:00:04.0 'Virtio network device 1000' drv=igb_uio unused=virtio_pci

Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device 1000' if=eth0 drv=virtio-pci unused=virtio_pci,igb_uio *Active*

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.111.143  netmask 255.255.255.0  broadcast 192.168.111.255
        inet6 fe80::f816:3eff:fe76:d647  prefixlen 64  scopeid 0x20<link>
        ether fa:16:3e:76:d6:47  txqueuelen 1000  (Ethernet)
        RX packets 3277  bytes 315387 (307.9 KiB)
        RX errors 0  dropped 1  overruns 0  frame 0
        TX packets 2311  bytes 306019 (298.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vm2配置

到dpdk编译完成的路径下执行以下命令让系统加载igb驱动,同时让eth1网卡加载igb驱动。

# modprobe uio
# insmod x86_64-native-linuxapp-gcc/kmod/igb_uio.ko 
# insmod x86_64-native-linuxapp-gcc/kmod/rte_kni.ko

查看网卡状态检查驱动是否成功加载
 ./usertools/dpdk-devbind.py --status

Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device 1000' if=eth0 drv=virtio-pci unused=virtio_pci,igb_uio *Active*
0000:00:06.0 'Virtio network device 1000' if=eth1 drv=virtio-pci unused=virtio_pci,igb_uio *Active*

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
============================

将eth1网卡加载igb_uio驱动同时查看是否加载成功
# ./usertools/dpdk-devbind.py --force -b igb_uio 0000:00:06.0
# ./usertools/dpdk-devbind.py --status

Network devices using DPDK-compatible driver
============================================
0000:00:06.0 'Virtio network device 1000' drv=igb_uio unused=virtio_pci

Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device 1000' if=eth0 drv=virtio-pci unused=virtio_pci,igb_uio *Active*

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

运行RFC2544测试

VM2启动l2fwd

考虑到pktgen-dpdk直接启动之后会直接发送流量,这里需要首先启动vm2的l2fwd测试脚本保证一轮测试的完整性。进入到dpdk安装路径下,编译l2fwd脚本让后运行(注意此时已经将该虚拟机分配了大页内存):

cd ../dpdk/examples/l2fwd
make
./dpdk/examples/l2fwd/build/l2fwd  -c 0x1 -n 2  -- -p 0x1 -q 10 -T 1
运行完成之后会持续打印该端口的收发包数量。
Port statistics ====================================
Statistics for port 0 ------------------------------
Packets sent:                        5
Packets received:                    5
Packets dropped:                     0
Aggregate statistics ===============================
Total packets sent:                  5
Total packets received:              5
Total packets dropped:               0
====================================================

l2fwd参数解释如下:

l2fwd [EAL options] -- -p PORTMASK [-q NQ -T t]
EAL options

DPDK EAL的默认参数,必须参数为-c COREMASK -n NUM。
COREMASK:一个十六进制位掩码表示分配的逻辑内核数量。
NUM:一个十进制整数表示内存通道数量。
-p PORTMASK
PORTMASK:一个十六进制位掩码表示分配的端口数量。

-q NQ
NQ:表示分配给每个逻辑内核的收发队列数量。

-T t
t: 表示打印统计数据到屏幕上的时间间隔,默认为10秒。

VM1启动pktgen-dpdk

在vm1上pktgen-dpdk目录中运行pktgen脚本使之执行RFC2544测试。

在这里考虑到虚机vm1时2核4G内存,所以要将vm1虚机上pci设备映射为单核收发包,pktgen-dpdk命令如下:

./app/x86_64-native-linuxapp-gcc/pktgen -l 0-1 -n 3 -w 0000:00:04.0 --proc-type auto -- -P -m "1.0"  -f scripts/rfc2544_tput_test.lua

pktgen的命令提结构如下,详细的命令解释可以在官网查询到,这里不做过多讲解:

./app/app/``$(target}``/pktgen [EAL options] -- \
                             [-h] [-P] [-G] [-T] [-f cmd_file] \
                             [-l log_file] [-s P:PCAP_file] [-m <string>]

这里简要说明下使用的参数:
-l 0-1 表明选择使用的CPU,pktgen会默认使用系统0号cpu负责页面文本交互输出,并且0号CPU不负责端口的收发包。 
-n 表示开启的内存通道数
-w 表示添加受信任的pci白名单,这就相当于端口绑定。如果想使用一个端口进行收发包则只需要绑定该网卡的pci地址杰克。
--proc-type auto pktgen进程类型,一般默认选auto
-P 开启网卡混杂模式
-m 矩阵端口映射到逻辑的核心.
-f 选择要运行的脚本

这里附上官网针对EAL参数和pktgen参数(也就是“–”之后的参数)详解地址:
EAL命令参数:https://pktgen-dpdk.readthedocs.io/en/latest/usage_eal.html#usage-eal
pktgen命令参数:https://pktgen-dpdk.readthedocs.io/en/latest/usage_pktgen.html#usage-pktgen

在vm1执行完pktgen之后会生成一个文本框,输出当前测试状态和实时的测试结果。可以看到当有收发包(RX,TX个数)和对端l2fwd有收发包个数时,整个测试流量已经跑成功。

简要说明pktgen-dpdk运行时面板的参数。
在这里插入图片描述

查看vm2端l2fwd运行状态,可以看到有大量的收发包。
在这里插入图片描述

安全组问题诊断

当然在跑RFC2544的时候不可能什么事情都是一番风顺的,要都一番风顺了这玩意也就没有必要花我这么多时间写一篇博客了。很多时候我们遇到的情况更多的如下。明明有了发包速率但是为什么一个收包都没有。
在这里插入图片描述

1.首先检查完rfc2544测试脚本中的参数是否填入正确。
2.在确保rfc2544测试脚本参数正确之后,查看l2fwd端转发是否正常,收发包的个数是否在同一数量级。
3.在ovs流表上抓取两个虚机端口的流表情况,查看RX和TX是否符合预期,是否有drop的包。
4.查看安全组设置。其实在测试openstack的OVS,出现RT=0的情况,一般都先要确认安全组是否开启。流表是否将测试流给drop掉。

如果出现如下情况说明安全组连拦截掉了包(本文中使用neutron iptables安全组,如果是ovs安全组则在流表中对应流规则会有大量丢包)。

在这里插入图片描述

这里主要原因是因为l2fwd转发的包,是将测试流转发回pktgen-dpdk的发送端。但是测试包中源mac地址,源IP地址,目的IP地址,目的mac地址并不会做调换。意味着当测试流到了安全组时,安全组会检查包内容从而直接发现报文内容不合理从而丢弃。

这种情况下可以考虑通过neutron命令给测试虚机添加address-pair来规避掉安全组隔离。在neutron中给vm1的eth1网卡添加vm2的eth1IP地址,但是mac地址仍然是vm1的eth1的mac地址。同理在vm2的eth1网卡上添加vm1的eth1的IP地址,但是mac地址仍然是vm2的eth1的mac地址。

具体方法可参考如下:
查看vm1和vm2的端口uuid
在这里插入图片描述

在这里插入图片描述

添加address pair
在这里插入图片描述

如果是ovs安全组,此时可以考虑添加回环流表来规避。在确认了虚机所在br-int上的端口之后,可以写入回环流。这里我们将这条流写到表0中,这样可以避免其他流规则的干扰。当然OVS作为被测物来说并不建议修改流表,因为这会直接影响查表速率。这里只是当作方法给出。

ovs-ofctl  add-flow br-int "table=0,idle_timeout=0,priority=600,in_port=11,action=output:12"
ovs-ofctl  add-flow br-int "table=0,idle_timeout=0,priority=600,in_port=12,action=output:11"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值