前段时间有哥们在vpp群里分享了基于VPP的src/plugins/linux-cp/插件复制的一个临时插件lcpng,作者做了很多方面的验证和修改,并且后期计划合入到vpp主分支上去。本文主要基于ubuntu20.4.3lts系统搭建环境,验证一下基于lcpng插件和frr bgpd配合测试。
lcpng github库:https://github.com/pimvanpelt/lcpng 作者的blog:https://ipng.ch/s/articles/ --记录了lcpng插件的验证和改动过程。
lcpng插件是临时插件,由vpp的插件src/plugins/linux-cp复制而来,最初是由以下作者提交的:
Signed-off-by: Neale Ranns nranns@cisco.com Signed-off-by: Matthew Smith mgsmith@netgate.com Signed-off-by: Jon Loeliger jdl@netgate.com Signed-off-by: Pim van Pelt pim@ipng.nl Signed-off-by: Neale Ranns neale@graphiant.com
作者针对vpp现有linux cp插件接口及netlink同步插件进行的验证和重写,在作者的blog中记录修改记录和验证过程,使Linux cp插件更加的完善,可以将vpp配置复制到linux内核接口,也可以讲linux配置复制到vpp,实现linux和vpp之间的双向通信管道。这个插件可以在更高级别的控制平面上工作,比如开源项目FRR和bird。当前插件支持以下功能,具体如下:
在作者blog中《VPP Linux CP - Part7》文章中作者使用isolcpus来提升vpp性能,具体描述如下:在安装完成后,对Linux系统引导程序/etc/default/grub进行了设置,设置cpu隔离及串口信息等。
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8 isolcpus=1,2,3,5,6,7"
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
# Followed by a gratuitous install and update
grub-install /dev/sda
update-grub
需要注意的是isolcpus是一个非常巧妙的技巧,它告诉linux系统在任务调度程序时避免在这些cpu上调度任务工作负载。因为 Xeon-D1518 有4个内核(0、1、2、3)和4个额外的超线程(4、5、6、7),这个设置有效地使内核1、2、3 对 Linux系统程序化不可用,只留下内核0和它的超线程4可用。这意味着我们的控制平面将有2个CPU可用于运行 Bird、SNMP、SSH 等,而 CPU 1、2、3 上的超线程基本上关闭,将这些内核完全交给 VPP来使用。以这种方式关闭超线程:超线程共享CPU指令和数据缓存。VPP的前提是一个vector(a list)数据包将同时通过相同的例程(如ethernet-input或ip4-lookup)。在这样的计算模型中,VPP 利用 i-cache 和 d-cache 让后续数据包使用来自其先前的预热缓存,而不必使用(相对而言慢得多)主内存。 所以:禁止linux系统在1、2、3 及其对应的超线程 5、6、7上进行调度并限制VPP仅在 lcore 1、2、3 上运行将从本质上最大限度地提高VPP的CPU缓存命中率,从而大大提高性能。
namespace最初由TNSR提出,它是VPP的Netgate 商业产品,在单独的 Linux 网络命名空间中运行VPP及其控制平面是一个好主意 。网络命名空间在逻辑上是网络堆栈的另一个副本,具有自己的路由、防火墙规则和网络设备。本文也是以FRR/bgpd程序运行在名称为dataplane的namespace空间,来验证lcpng插件的基本功能。
验证环境使用vmware虚拟机创建2个ubuntu20.4.3 lts系统,然后下载vpp、frr最新代码在ubuntu系统上安装部署。vmware网络接口使用e1000网卡。
配置环境分为三个步骤: 1、虚拟机创建一个名称为dataplane的namespace,这里也是参考lcpng指导文档来说明,如果不需要可以不用创建。在vpp中创建lcp create应该不指定netns即可(本文未验证)。 2、配置frr bgpd环境。 3、配置vpp。
ip netns add dataplane
这里需要注意的是,如果需要使用namespace,必须在lcp create之前在linux系统创建好namespace,否则无法配置成功,报错tap接口创建失败。
Ubuntu20.4系统安装frr可以参考frr官方文档进行安装,本文不再说明,主要说一下配置的。frr bgpd启动在namespace需要进行如下的设置。frr官方文档提供了2种方式,本文按照第一种简单方式进行配置。
#启用ospfd服务
bgpd=yes
#设置ospfd配置文件
bgpd_options=" -A 127.0.0.1 -f /etc/frr/bgpd.conf"
#设置frr启动在namespace,
watchfrr_options="--netns=dataplane"
frr设置namespace是参考frr的用户指导书,链接如下。https://docs.frrouting.org/en/latest/setup.html
vpp1虚拟机配置frr如下:
#基本配置
learning_vpp1# configure terminal
learning_vpp1(config)# router bgp 6632
learning_vpp1(config-router)# bgp router-id 200.1.1.1
learning_vpp1(config-router)# neighbor 200.1.1.2 remote-as 6632
#发布子网
learning_vpp1(config-router)# network 201.1.1.0/24
vpp2设备FRR/BGP配置
learning_vpp2# configure terminal
learning_vpp2(config)# router bgp 6632
learning_vpp2(config-router)# bgp router-id 200.1.1.2
learning_vpp2(config-router)# neighbor 200.1.1.1 remote-as 6632
learning_vpp2(config-router)# network 202.1.1.0/24
lcpng编译配置,是在vpp的插件目录下创建一个超链接,编译vpp的时候会自动编译lcpng程序。
mkdir ~/src
cd ~/src
git clone https://github.com/pimvanpelt/lcpng.git
ln -s ~src/lcpng ~/src/vpp/src/plugins/lcpng
vpp 启动配置文件startup.conf直接参考lcpng开源插件库进行设置。
#lcpng插件默认不会加载,需要手动指导加载。
plugins {
path ~/src/vpp/build-root/install-vpp_debug-native/vpp/lib/vpp_plugins
plugin lcpng_if_plugin.so { enable }#使能lcpng插件
plugin lcpng_nl_plugin.so { enable }
plugin linux_cp_plugin.so { disable }#关闭原始linux cp插件
}
#设置logging信息
logging {
default-log-level info
default-syslog-log-level crit
## Set per-class configuration
class linux-cp/if { rate-limit 10000 level debug syslog-level debug }
class linux-cp/nl { rate-limit 10000 level debug syslog-level debug }
}
#配置lcpng
lcpng {
default netns dataplane #设置缺省namespace
lcp-sync #允许vpp和linux内核信息自动同步
lcp-auto-subint #允许vpp和linux 子接口创建和删除自动同步
}
vpp1虚拟机的基本配置,vpp2配置通vpp1这里就省略了,
#vpp的配置如下,
set interface state GigabitEthernet2/2/0 up
set interface ip address GigabitEthernet2/2/0 200.1.1.1/24
set interface state GigabitEthernet2/3/0 up
set interface ip address GigabitEthernet2/3/0 201.1.1.1/24
#创建vpp和linux同步接口,默认创建完会在内核namespace空间生成ge220接口
lcp create 1 host-if ge220 netns dataplane
查询lcp create 创建信息
DBGvpp# show lcp
lcp default netns dataplane
lcp lcp-auto-subint on
lcp lcp-sync on
itf-pair: [0] GigabitEthernet2/2/0 tap1 ge220 21 type tap netns dataplane
将GigabitEthernet2/3/0接口加入到dataplane的namespace中
ip link set ens36 netns dataplane
查询namespace接口信息如下:
root@learningvpp1:/home/jinsh# ip netns exec dataplane ifconfig
ens36: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 201.1.1.2 netmask 255.255.255.0 broadcast 201.1.1.255
inet6 fe80::20c:29ff:fede:afe1 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:de:af:e1 txqueuelen 1000 (Ethernet)
RX packets 386 bytes 122418 (122.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 374 bytes 116660 (116.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ge220: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000
inet 200.1.1.1 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::20c:29ff:fede:afcd prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:de:af:cd txqueuelen 1000 (Ethernet)
RX packets 307 bytes 23285 (23.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 370 bytes 26033 (26.0 KB)
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
前几天也有同学在vpp群里也遇到了此问题,网卡绑定igb_uio时dmesg打印中“PCI INTX mask not supported”,会导致网卡无法工作。此问题是dpdk已知问题,有相关的patch文件,但是并未合入到dpdk-kmod库中。具体patch修改如下:
#可以查询链接:http://mails.dpdk.org/archives/dev/2016-March/036094.html
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index d1ca26e..c46a00f 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -505,14 +505,11 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
}
/* fall back to INTX */
case RTE_INTR_MODE_LEGACY:
- if (pci_intx_mask_supported(dev)) {
- dev_dbg(&dev->dev, "using INTX");
- udev->info.irq_flags = IRQF_SHARED;
- udev->info.irq = dev->irq;
- udev->mode = RTE_INTR_MODE_LEGACY;
- break;
- }
- dev_notice(&dev->dev, "PCI INTX mask not supported\n");
+ dev_dbg(&dev->dev, "using INTX");
+ udev->info.irq_flags = IRQF_SHARED;
+ udev->info.irq = dev->irq;
+ udev->mode = RTE_INTR_MODE_LEGACY;
+ break;
/* fall back to no IRQ */
case RTE_INTR_MODE_NONE:
udev->mode = RTE_INTR_MODE_NONE;
另外网上也有人建议网卡驱动类型将e1000修改为vmxnet3,可以解决此问题。vmxnet3性能优于e1000。可能操作系统并没有自带vmxnet3驱动程序,需要自己手动来安装vmware-tools。具体性能测试情况可以参考链接:https://www.yisu.com/zixun/72226.html
建议使用vmxnet3。 E1000是千兆网路卡,而VMXNET3是万兆网路卡; E1000的性能相对较低,而VMXNET3的性能相对较高; VMXNET3支持TCP/IP Offload Engine,E1000不支持; VMXNET3可以直接和vmkernel通讯,执行内部数据处理;
原因默认配置文件指定使用了vpp用户组,需要手动添加vpp用户组
groupadd -f -r vpp
表示tap接口创建失败,在vpp配置文件中,默认设置default netns dataplane,当时linux系统中并没有创建dataplane。手动创建之后,lcp 添加成功。
本文分享自 DPDK VPP源码分析 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!