【DOCA有奖征文】NVIDIA BlueField-2 DPU快速入门指南

作者:markchen7788

接触NVIDIA网络产品和SDN、NFV技术差不多一年左右,从2021年8月开始接触的NVIDIA ConnectX-6 Dx(以下简称cx6),3个月后开始接触NVIDIA BlueField-2 DPU(以下简称bf2)。本文将结合自己的探索经历来介绍如何快速入门NVIDIA BlueField-2 DPU,主要包括:

1)如何使用SR_IOV+OVS构建自己的拓扑;

2)如何运行DOCA应用(DNS_Filter)。

cx6-dx 作为子模块集成到bf2中,所以本文会将两者进行一些比较。另外,bf2的许多功能需要运行在嵌入式模式(Embedded CPU Function Ownership Mode)下,因此接下来的操作我们默认在嵌入式模式下进行,DOCA 版本为DOCA_1.3.0。

一、关于BlueField-2 DPU的一些必要知识

1.嵌入式模式下的默认拓扑和流量走向

1)在arm中查看嵌入式模式下的默认拓扑

[attach]20042[/attach]

2)拓扑图和流量走向

[attach]20044[/attach]

备注:

(1)黄色口为代表口,不可以用内核协议栈来发包,粉色口可以配置IP用来发包;

(2)其中pf0、pf1为主机上的物理网口,pf0hpf、pf1hpf是它们在arm中的代表口;

(3)enp3s0f0s0、enp3s0f1s0为arm上的SF口,en3f0pf0sf0、en3f1pf1sf0为它们的代表口,很多文档都说到的实际上是代表口,进而让我忽略了实际网口,导致我很久才明白enp3s0f0s0、enp3s0f1s0这两个实际网口的作用。DOCA程序中收发报文用到的SF网口是enp3s0f0s0、enp3s0f1s0这两个网口,并不是代表口。这两个SF口和主机的物理口具有同样的作用,配置同一网段IP后支持发送各类报文(包括RDMA)并进行互通,两者互通的带宽可达100Gb/s左右。(从主机传送大量数据给arm时,除了可以使用tmfifo_net0这一管理端口,还可以使用sf,并且sf更快,使用RDMA协议传输文件体验更舒适。)

(4)tmfifo_net0、oob_net0为管理端口,tmfifo_net0通过rshim driver与主机互联通信,oob_net0通过1G以太网口通信。

(5)p0、p1为流量出口。

⑥流量走向:

pf0向远端设备发送流量:pf0—>pf0hpf—>ovsbr1—>p0—>以太网—>目的地

pf0向arm sf发送流量:pf0—>pf0hpf—>ovsbr1—>en3f0pf0sf0—>enp3s0f0s0

2.VF和SF

SF和VF类似,都是通过SR_IOV技术虚拟化出来的PCIE设备。VF出现在宿主机中,可提供给虚拟机使用;SF出现在arm中,主要作用就是构建网络拓扑,分离出流量提供给DOCA应用程序进行处理并将处理好的流量再次传入网络。常用的拓扑如下所示。

[attach]20043[/attach]

备注:

(1)pf0vf0是vf0在DPU上的代表口,连接到OVS后,可以将VM的流量送入DOCA APP进行处理。以此作为实例阐明一下SF、VF的区别;

(2)建议使用DOCA APP时,重新申请两个SF,一个连接宿主机端,一个连接远端。默认的两个SF(enp3s0f0s0、enp3s0f1s0)不在同一个PCIE设备上,且默认的SF标识无从所知,以此使用DOCA APP可能会出现问题,所以建议在同一个PCIE设备上重新申请两个SF,默认的SF用作通信;

3.cx6-dx和bf2的区别

(1)cx6-dx只卸载了数据平面到硬件中;

(2)bf2卸载了数据平面+控制平面,数据平面运行在硬件中,控制平面运行在DPU的arm核中;

(3)最直观的表现就是:插上cx6-dx时,vf的representor出现在host OS中;插上bf2时,vf的representor出现在DPU OS中(划重点),vm网络(VPC)的控制平面运行在arm上。更进一步说,当需要同时卸载控制平面和数据平面实现裸金属服务器时,只有bf2才能胜任。

二、构建拓扑

1.开启VF和SF的方式不做赘述,可参考如下链接,来源DOCA SDK文档:

  • 开启VF的参考链接:

[u]https://docs.nvidia.com/doca/sdk/virtual-functions/index.html[/u]

  • 开启SF的参考链接:

[u]https://docs.nvidia.com/doca/sdk/scalable-functions/index.html[/u]

  1. ovs的使用方式,可自行搜索进行学习,学会构建拓扑下发流表就足够了;

  2. 构建一个实例拓扑,用于接下来运行doca app:

①在pf0上申请两个sf:

/opt/mellanox/iproute2/sbin/mlxdevm port add pci/0000:03:00.0 flavour pcisf pfnum 0 sfnum 4

/opt/mellanox/iproute2/sbin/mlxdevm port add pci/0000:03:00.0 flavour pcisf pfnum 0 sfnum 5

/opt/mellanox/iproute2/sbin/mlxdevm port function set pci/0000:03:00.0/229409 hw_addr 02:25:f2:8d:a2:4c trust on state active

/opt/mellanox/iproute2/sbin/mlxdevm port function set pci/0000:03:00.0/229410 hw_addr 02:25:f2:8d:a2:5c trust on state active

echo mlx5_core.sf.4 > /sys/bus/auxiliary/drivers/mlx5_core.sf_cfg/unbind

echo mlx5_core.sf.4 > /sys/bus/auxiliary/drivers/mlx5_core.sf/bind

echo mlx5_core.sf.5 > /sys/bus/auxiliary/drivers/mlx5_core.sf_cfg/unbind

echo mlx5_core.sf.5 > /sys/bus/auxiliary/drivers/mlx5_core.sf/bind

②创建拓扑

/home/ubuntu/scripts# ovs-vsctl add-br ovs-test

/home/ubuntu/scripts# ovs-vsctl del-port p0

/home/ubuntu/scripts# ovs-vsctl del-port pf0hpf

/home/ubuntu/scripts# ovs-vsctl add-port ovs-test pf0hpf

/home/ubuntu/scripts# ovs-vsctl add-port ovs-test p0

/home/ubuntu/scripts# ovs-vsctl add-port ovs-test en3f0pf0sf4

/home/ubuntu/scripts# ovs-vsctl add-port ovs-test en3f0pf0sf5

③下发和检查流表

ovs-ofctl del-flows ovs-test

ovs-ofctl add-flow ovs-test “priority=1,in_port=pf0hpf,actions=output:p0”

ovs-ofctl add-flow ovs-test “priority=2,in_port=p0,actions=output:pf0hpf”

ovs-ofctl add-flow ovs-test “priority=3,in_port=pf0hpf,udp,tp_dst=53,actions=output:en3f0pf0sf4”

ovs-ofctl add-flow ovs-test “priority=3,in_port=en3f0pf0sf5,udp,tp_dst=53,actions=output:p0”

ovs-ofctl add-flow ovs-test “priority=4,in_port=p0,udp,tp_dst=53,actions=output:en3f0pf0sf5”

ovs-ofctl add-flow ovs-test “priority=4,in_port=en3f0pf0sf4,udp,tp_dst=53,actions=output:pf0hpf”

ovs-ofctl dump-flows ovs-test

拓扑图如下所示:

[attach]20045[/attach]

注意:

①ovs-test上的流表不能形成环路,DNS_Filter使用了hairpin队列将非DNS流量卸载转发,因此不删除“actions=NORMAL”这一表项可能会造成环路进而转发失败,可能产生的环路如下图所示:

[attach]20046[/attach]

②如果不设置好DNS_Filter处理过的DNS流量的走向,DNS流量也可能产生环路,可能产生的环路如下图所示:

[attach]20047[/attach]

  1. 其它值得注意的地方:

①arm 上的OVS默认开启了硬件卸载,会对流表执行自动卸载:

eg:利用iperf工具在宿主机上打流量,在arm上查看动态卸载的流表:

sudo ovs-appctl dpctl/dump-flows type=offloaded

[attach]20048[/attach]

②重启OVS命令如下,DPU OS文档中的命令有些许问题。重启DPU或者重启OVS,通过ovs-ofctl命令下发的流表都会消失,需要重新下发

sudo /etc/init.d/openvswitch-switch restart

③通过ovs-tcpdump 命令可以在arm上抓取代表口的流量。(roce v2的流量可以在pf0hpf上抓取,不过非常不建议这样做,会极大削弱RDMA的性能)[attach]20049[/attach]

三、运行DOCA程序(DNS_Filter为示例)

1.按照如下步骤,在二中建立好的拓扑上运行DNS_Filter实例

编译RXP过滤规则,DNS_Filter借助Regex Engine实现了DNS的白名单功能(不是黑名单哦!!!),写下域名的正则表达式规则并利用rxp_compiler进行编译。如下是本人编写的规则,允许符合以下四条规则的DNS流量通过。

                                                                                                   [attach]20050[/attach]

DNS过滤规则

①编译规则:

rxpc -f regex_rules.txt -p 0.01 -o /tmp/regex_rules

②申请大页,供DPDK使用

echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

③开启regex服务

systemctl start mlx-regex

④没有什么特殊要求,直接/opt/mellanox/doca/applications/DNS_Filter/bin/目录下的运行编译好的程序和并使用json配置文件的参数即可:

    ./doca_dns_filter --json ./DNS_Filter_params.json

2.验证

1)可以将pf0桥接给vm使用,从而跟物理机网络隔离,或者直接申请一个vf,利用vf-rep在arm中构建上述拓扑也行,最后务必将p0连接至公网。

2)清除一下主机上的DNS缓存,本人在vm中运行的是ubuntu kylin 20.4 OS,命令如下:

sudo systemd-resolve --flush-caches

1)用浏览器浏览域名在白名单中的网页,或者直接ping域名:

[attach]20051[/attach]

VM ping www.baidu.com

                                                                               [attach]20052[/attach] 

DNS_Filter运行结果

2)ping 非白名单中的域名:

                                                                                 [attach]20053[/attach]

VM ping 360.cn

3.为什么不使用官方实例中的拓扑的原因:

1)官方拓扑不需要配置任何流表,但是要在程序中通过建立hairpin队列来实现非DNS流量的卸载;

2)上述建立的拓扑通过ovs的命令将DNS流量分离给DOCA APP处理,可以不再需要hairpin队列,但是配置麻烦了一点;

3)个人觉得用ovs提前将目标流量分离出来更符合实际需求。特别是你需要运行多个doca app时,将流量提前用ovs分离出来更方便。

参考文档:

1)NVIDIA BlueField-2 Ethernet DPU User Guide(硬件文档):

[u]https://docs.nvidia.com/networking/display/BlueField2DPUENUG[/u]

2)NVIDIA BLUEFIELD DPU PLATFORM OPERATING SYSTEM v3.9.2 DOCUMENTATION(软件文档):[u]https://docs.nvidia.com/networking/display/BlueFieldDPUOSLatest[/u]

3)DOCA SDK文档:[u]https://docs.nvidia.com/doca/sdk/index.html[/u]