OVS-DPDK 硬件加速
配置 OVS-DPDK 硬件卸载
取消绑定 VF
echo
0000
:04
:00.2
> /sys/bus/pci/drivers/mlx5_core/unbind echo0000
:04
:00.3
> /sys/bus/pci/drivers/mlx5_core/unbind注意带有附加 VF 的 VM 必须关闭电源才能取消绑定 VF。
将 PF 设备上的 e-switch 模式从 legacy 更改为 switchdev(确保所有 VF 都已取消绑定)。这也会在主机操作系统中创建 VF representor 网络设备。
echo switchdev > /sys/
class
/net/enp4s0f0/compat/devlink/mode恢复到 SR-IOV legacy 模式
echo legacy > /sys/
class
/net/enp4s0f0/compat/devlink/mode注意此命令将删除 VF representor 网络设备。
绑定 VF
echo
0000
:04
:00.2
> /sys/bus/pci/drivers/mlx5_core/bind echo0000
:04
:00.3
> /sys/bus/pci/drivers/mlx5_core/bind运行 OVS 服务
systemctl start openvswitch
启用硬件卸载(默认禁用)
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=
true
ovs-vsctl set Open_vSwitch . other_config:hw-offload=true
配置 DPDK 白名单
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-extra=
"-a 0000:01:00.0,representor=[0],dv_flow_en=1,dv_esw_en=1,dv_xmeta_en=1"
其中
representor=[0-N]
。重启 OVS 服务
systemctl restart openvswitch
信息此步骤是硬件卸载更改生效所必需的。
创建 OVS-DPDK 网桥
ovs-vsctl --no-wait add-br br0-ovs -- set bridge br0-ovs datapath_type=netdev
将 PF 添加到 OVS
ovs-vsctl add-port br0-ovs pf -- set Interface pf type=dpdk options:dpdk-devargs=
0000
:88
:00.0
将 representor 添加到 OVS
ovs-vsctl add-port br0-ovs representor -- set Interface representor type=dpdk options:dpdk-devargs=
0000
:88
:00.0
,representor=[0
]其中
representor=[0-N]
。
用户空间中的 vSwitch 需要一个额外的网桥。此网桥的目的是允许使用内核网络堆栈进行路由和 ARP 解析。
数据路径必须查找路由表和 ARP 表,以准备隧道标头并将数据传输到输出端口。
配置 VXLAN 封装/解封装卸载
配置通过以下方式完成
PF 在 0000:03:00.0 PCIe 和 MAC 98:03:9b:cc:21:e8 上
本地 IP 56.56.67.1 – br-phy 接口配置为此 IP
远程 IP 56.56.68.1
配置 OVS-DPDK VXLAN
创建 br-phy 网桥
ovs-vsctl add-br br-phy -- set Bridge br-phy datapath_type=netdev -- br-set-external-id br-phy bridge-id br-phy -- set bridge br-phy fail-mode=standalone other_config:hwaddr=
98
:03
:9b:cc:21
:e8将 PF 接口附加到 br-phy 网桥
ovs-vsctl add-port br-phy p0 -- set Interface p0 type=dpdk options:dpdk-devargs=
0000
:03
:00.0
将 IP 配置到网桥
ip addr add
56.56
.67.1
/24
dev br-phy创建 br-ovs 网桥
ovs-vsctl add-br br-ovs -- set Bridge br-ovs datapath_type=netdev -- br-set-external-id br-ovs bridge-id br-ovs -- set bridge br-ovs fail-mode=standalone
将 representor 附加到 br-ovs
ovs-vsctl add-port br-ovs pf0vf0 -- set Interface pf0vf0 type=dpdk options:dpdk-devargs=
0000
:03
:00.0
,representor=[0
]为 VXLAN 隧道添加端口
ovs-vsctl add-port ovs-sriov vxlan0 -- set
interface
vxlan0 type=vxlan options:local_ip=56.56
.67.1
options:remote_ip=56.56
.68.1
options:key=45
options:dst_port=4789
CT 通过记录当前打开的连接来实现有状态数据包处理。使用 CT 的 OVS 流可以使用高级 NIC 通过卸载已建立的连接来加速。
查看卸载的连接,运行
ovs-appctl dpctl/offload-stats-show
配置 OVS-DPDK SR-IOV VF LAG
在 NIC 固件中启用 SR-IOV
// It is recommended to query the parameters first to determine if change is needed, to save unnecessary reboot
mst start mlxconfig -d <mst device> -y set PF_NUM_OF_VF_VALID=0
SRIOV_EN=1
NUM_OF_VFS=8
如果配置发生更改,除非 NIC 是 BlueField DPU 模式,否则请对服务器操作系统执行暖重启。否则,请执行 BlueField 系统级重置。
为每个端口分配所需的 VF 数量
echo $n > /sys/
class
/net/<net name>/device/sriov_numvfs取消绑定所有 VF
echo <VF PCI> >/sys/bus/pci/drivers/mlx5_core/unbind
将两个设备的模式都更改为 switchdev
devlink dev eswitch set pci/<PCI> mode switchdev
使用内核模块创建 Linux bonding
modprobe bonding mode=<desired mode>
信息可以在此处添加其他 bonding 参数。支持的 bond 模式为:Active-backup、XOR 和 LACP。
关闭所有 PF 和 VF
ip link set <PF/VF> down
将两个 PF 都附加到 bond
ip link set <PF> master bond0
要将 VF-LAG 与 OVS-DPDK 一起使用,请将 bond master (PF) 添加到网桥
ovs-vsctl add-port br-phy p0 -- set Interface p0 type=dpdk options:dpdk-devargs=
0000
:03
:00.0
options:dpdk-lsc-interrupt=true
将 PF0 或 PF1 的 representor
$N
添加到网桥ovs-vsctl add-port br-phy rep$N -- set Interface rep$N type=dpdk options:dpdk-devargs=<PF0 PCI>,representor=pf0vf$N
或
ovs-vsctl add-port br-phy rep$N -- set Interface rep$N type=dpdk options:dpdk-devargs=<PF0 PCI>,representor=pf1vf$N
硬件 vDPA 默认启用。如果您的硬件不支持 vDPA,驱动程序将回退到软件 vDPA。
要检查您的驱动程序上激活了哪种 vDPA 模式,请运行:ovs-ofctl -O OpenFlow14 dump-ports br0-ovs
并查找 hw-mode
标志。
此功能尚未被 OVS-DPDK 上游接受,使其 API 可能会发生更改。
在用户空间中,与访客 (VM) 通信主要有两种方法,通过 SR-IOV 或 virtio。
PHY 端口 (SR-IOV) 允许使用端口 representor,它附加到 OVS,并且通过直通为访客提供匹配的 VF。硬件规则可以处理来自上行链路的数据包,并将它们定向到 VF,而无需通过软件 (OVS)。因此,使用 SR-IOV 可以实现最佳性能。
但是,SR-IOV 架构要求访客使用特定于底层硬件的驱动程序。特定的硬件驱动程序有两个主要缺点
在某种程度上破坏了虚拟化(访客知道硬件)。它也可能限制支持的映像类型。
为实时迁移提供不太自然的支持。
使用 virtio 端口解决了这两个问题,但是,它降低了性能并导致一些功能丢失,例如,对于某些硬件卸载,直接使用 virtio。netdev 类型 dpdkvdpa 解决了此冲突,因为它类似于常规 DPDK netdev,但引入了几个附加功能。
dpdkvdpa 在 PHY 端口和 virtio 端口之间进行转换。它从 Rx 队列中获取数据包并将它们发送到合适的 Tx 队列,并允许将数据包从 virtio 访客 (VM) 传输到 VF,反之亦然,从而受益于 SR-IOV 和 virtio。
添加 vDPA 端口
ovs-vsctl add-port br0 vdpa0 -- set Interface vdpa0 type=dpdkvdpa \
options:vdpa-socket-path=<sock path> \
options:vdpa-accelerator-devargs=<vf pci id> \
options:dpdk-devargs=<pf pci id>,representor=[id] \
options: vdpa-max-queues =<num queues> \
options: vdpa-sw=<true
/false
>
vdpa-max-queues
是一个可选字段。当用户想要配置 32 个 vDPA 端口时,最大队列数限制为 8 个。
OVS-DPDK 模式下的 vDPA 配置
在 OVS-DPDK 模式下配置 vDPA 之前,请执行以下操作
生成 VF
echo
0
> /sys/class
/net/enp175s0f0/device/sriov_numvfs echo4
> /sys/class
/net/enp175s0f0/device/sriov_numvfs取消绑定每个 VF
echo <pci> > /sys/bus/pci/drivers/mlx5_core/unbind
切换到 switchdev 模式
echo switchdev >> /sys/
class
/net/enp175s0f0/compat/devlink/mode绑定每个 VF
echo <pci> > /sys/bus/pci/drivers/mlx5_core/bind
初始化 OVS
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=
true
ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true
在 OVS-DPDK 模式下配置 vDPA
OVS 配置
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-extra=
"-a 0000:01:00.0,representor=[0],dv_flow_en=1,dv_esw_en=1,dv_xmeta_en=1"
/usr/share/openvswitch/scripts/ovs-ctl restart创建 OVS-DPDK 网桥
ovs-vsctl add-br br0-ovs -- set bridge br0-ovs datapath_type=netdev ovs-vsctl add-port br0-ovs pf -- set Interface pf type=dpdk options:dpdk-devargs=
0000
:01
:00.0
创建 vDPA 端口作为 OVS-DPDK 网桥的一部分
ovs-vsctl add-port br0-ovs vdpa0 -- set Interface vdpa0 type=dpdkvdpa options:vdpa-socket-path=/var/run/virtio-forwarder/sock0 options:vdpa-accelerator-devargs=
0000
:01
:00.2
options:dpdk-devargs=0000
:01
:00.0
,representor=[0
] options: vdpa-max-queues=8
要在 BlueField DPU 上以 OVS-DPDK 模式配置 vDPA,请使用软件或硬件 vDPA 端口设置网桥
在 Arm 侧创建 OVS-DPDK 网桥
ovs-vsctl add-br br0-ovs -- set bridge br0-ovs datapath_type=netdev ovs-vsctl add-port br0-ovs pf -- set Interface pf type=dpdk options:dpdk-devargs=
0000
:af:00.0
ovs-vsctl add-port br0-ovs rep-- set Interface rep type=dpdk options:dpdk-devargs=0000
:af:00.0
,representor=[0
]在主机侧创建 OVS-DPDK 网桥
ovs-vsctl add-br br1-ovs -- set bridge br1-ovs datapath_type=netdev protocols=OpenFlow14 ovs-vsctl add-port br0-ovs vdpa0 -- set Interface vdpa0 type=dpdkvdpa options:vdpa-socket-path=/var/run/virtio-forwarder/sock0 options:vdpa-accelerator-devargs=
0000
:af:00.2
注意要配置 SW vDPA,请将
options:vdpa-sw=true
添加到命令。
OVS-Kernel 模式下的软件 vDPA 配置
软件 vDPA 也可用于通过 TC 而不是 DPDK 完成硬件卸载的配置中。
OVS 配置
ovs-vsctl set Open_vSwitch . other_config:dpdk-extra=
"-a 0000:01:00.0,representor=[0],dv_flow_en=1,dv_esw_en=0,idv_xmeta_en=0,isolated_mode=1"
/usr/share/openvswitch/scripts/ovs-ctl restart创建 OVS-DPDK 网桥
ovs-vsctl add-br br0-ovs -- set bridge br0-ovs datapath_type=netdev
创建 vDPA 端口作为 OVS-DPDK 网桥的一部分
ovs-vsctl add-port br0-ovs vdpa0 -- set Interface vdpa0 type=dpdkvdpa options:vdpa-socket-path=/var/run/virtio-forwarder/sock0 options:vdpa-accelerator-devargs=
0000
:01
:00.2
options:dpdk-devargs=0000
:01
:00.0
,representor=[0
] options: vdpa-max-queues=8
创建内核网桥
ovs-vsctl add-br br-kernel
将 representor 添加到内核网桥
ovs-vsctl add-port br-kernel enp1s0f0_0 ovs-vsctl add-port br-kernel enp1s0f0
配置 MTU/巨型帧
验证 VM 上的内核版本是否为 4.14 或更高版本
cat /etc/redhat-release
在主机中的两个物理接口上设置 MTU
ifconfig ens4f0 mtu
9216
发送一个大型数据包并验证它是否已正确发送和接收
tcpdump -i ens4f0 -nev icmp & ping
11.100
.126.1
-s9188
-Mdo
-c1
在 XML 中启用
host_mtu
并添加以下值host_mtu=
9216
,csum=on,guest_csum=on,host_tso4=on,host_tso6=on示例
<qemu:commandline> <qemu:arg value=
'-chardev'
/> <qemu:arg value='socket,id=charnet1,path=/tmp/sock0,server'
/> <qemu:arg value='-netdev'
/> <qemu:arg value='vhost-user,chardev=charnet1,queues=16,id=hostnet1'
/> <qemu:arg value='-device'
/> <qemu:arg value='virtio-net-pci,mq=on,vectors=34,netdev=hostnet1,id=net1,mac=00:21:21:24:02:01,bus=pci.0,addr=0xC,page-per-vq=on,rx_queue_size=1024,tx_queue_size=1024,host_mtu=9216,csum=on,guest_csum=on,host_tso4=on,host_tso6=on'
/> </qemu:commandline>将
mtu_request=9216
选项添加到容器内的 OVS 端口并重启 OVSovs-vsctl add-port br0-ovs pf -- set Interface pf type=dpdk options:dpdk-devargs=
0000
:c4:00.0
mtu_request=9216
或
ovs-vsctl add-port br0-ovs vdpa0 -- set Interface vdpa0 type=dpdkvdpa options:vdpa-socket-path=/tmp/sock0 options:vdpa-accelerator-devargs=
0000
:c4:00.2
options:dpdk-devargs=0000
:c4:00.0
,representor=[0
] mtu_request=9216
/usr/share/openvswitch/scripts/ovs-ctl restart启动 VM 并在 VM 上配置 MTU
ifconfig eth0
11.100
.124.2
/16
up ifconfig eth0 mtu9216
ping11.100
.126.1
-s9188
-Mdo
-c1
此功能在 beta 级别受支持。
OVS 卸载规则基于多表架构。E2E 缓存可以将多表流匹配和操作合并为一个联合流。
当检测到完全匹配时,这可以通过使用单表来提高 CT 性能。
设置 E2E 缓存大小(默认为 4k)
ovs-vsctl set open_vswitch . other_config:e2e-size=<size>
systemctl restart openvswitch
启用 E2E 缓存(默认禁用)
ovs-vsctl set open_vswitch . other_config:e2e-enable=true
systemctl restart openvswitch
运行 E2E 缓存统计信息
ovs-appctl dpctl/dump-e2e-stats
运行 E2E 缓存流
ovs-appctl dpctl/dump-e2e-flows
Geneve 隧道卸载支持包括匹配扩展标头。
配置 OVS-DPDK Geneve 封装/解封装
创建 br-phy 网桥
ovs-vsctl --may-exist add-br br-phy -- set Bridge br-phy datapath_type=netdev -- br-set-external-id br-phy bridge-id br-phy -- set bridge br-phy fail-mode=standalone
将 PF 接口附加到 br-phy 网桥
ovs-vsctl add-port br-phy pf -- set Interface pf type=dpdk options:dpdk-devargs=<PF PCI>
将 IP 配置到网桥
ifconfig br-phy <$local_ip_1> up
创建 br-int 网桥
ovs-vsctl --may-exist add-br br-
int
-- set Bridge br-int
datapath_type=netdev -- br-set-external-id br-int
bridge-id br-int
-- set bridge br-int
fail-mode=standalone将 representor 附加到 br-int
ovs-vsctl add-port br-
int
rep$x -- set Interface rep$x type=dpdk options:dpdk-devargs=<PF PCI>,representor=[$x]为 Geneve 隧道添加端口
ovs-vsctl add-port br-
int
geneve0 -- setinterface
geneve0 type=geneve options:key=<VNI> options:remote_ip=<$remote_ip_1> options:local_ip=<$local_ip_1>
OVS-DPDK 支持并行插入和删除卸载(流和 CT)。虽然支持多个线程(默认情况下仅使用一个)。
配置多个线程
ovs-vsctl set Open_vSwitch . other_config:n-offload-threads=3
systemctl restart openvswitch
有关更多信息,请参阅 OVS 用户手册。
sFlow
sFlow 允许使用 sFlow 收集器监视同一主机上两个 VM 之间发送的流量。
要对 OVS 网桥上的所有流量进行采样,请运行以下命令
# ovs-vsctl -- --id=@sflow
create sflow agent=\"$SFLOW_AGENT\" \
target=\"$SFLOW_TARGET:$SFLOW_HEADER\" \
header=$SFLOW_HEADER \
sampling=$SFLOW_SAMPLING polling=10
\
-- set bridge sflow=@sflow
参数 | 描述 |
| 指示 sFlow 代理应从 |
| sFlow 收集器的远程 IP 地址 |
| sFlow 收集器的远程 IP 目标端口 |
| 要采样的数据包标头大小(以字节为单位) |
| 采样率 |
要清除 sFlow 配置,请运行
# ovs-vsctl clear bridge br-vxlan mirrors
当前,OVS-DPDK 的 sFlow 在没有 CT 的情况下受支持。
要在 OVS-DPDK 中启用 ct-ct-nat 卸载(默认禁用),请运行
ovs-vsctl set open_vswitch . other_config:ct-action-on-nat-conns=true
如果禁用,则 ct-ct-nat 配置不会完全卸载,从而提高其他情况(ct 和 ct-nat)的连接卸载率。
如果启用,则 ct-ct-nat 配置将完全卸载,但 ct 和 ct-nat 卸载的创建速度会较慢。
OVS 中的 OpenFlow meters 根据 RFC 2697(单速率三色标记—srTCM)实现。
srTCM 计量 IP 数据包流,并将其数据包标记为绿色、黄色或红色。颜色由承诺信息速率 (CIR) 和两个相关的突发大小(承诺突发大小 (CBS) 和超额突发大小 (EBS))决定。
如果数据包未超过 CBS,则标记为绿色;如果超过 CBS 但未超过 EBS,则标记为黄色;否则标记为红色。
绿色数据包的量应始终不小于 CIR。
在 OVS 中配置 meter
要在某个网桥上创建 meter,请运行
ovs-ofctl -O openflow13 add-meter $bridge meter=$id,$pktps/$kbps,band=type=drop,rate=$rate,[burst,burst_size=$burst_size]
参数
参数
描述
bridge
应在其上应用 meter 的网桥名称。
id
唯一 meter ID(32 位),用作 meter 的标识符。
pktps
/kbps
指示 meter 应根据数据包还是每秒千比特工作。
rate
允许数据传输的
pktps
/kbps
速率。burst
如果设置,则通过
burst_size
参数启用 meter 带宽的突发支持。burst_size
如果为 meter 条目指定了 burst,则根据指定了
kbps
还是pktps
,配置频带允许的最大突发大小(以千比特/数据包为单位)。如果未指定,则交换机可以根据其配置自由选择一些合理的值。目前,如果未指定 burst,则burst_size
参数设置为与rate
相同。将 meter 添加到某个 OpenFlow 规则。例如
ovs-ofctl -O openflow13 add-flow $bridge
"table=0,actions=meter:$id,normal"
查看 meter 统计信息
ovs-ofctl -O openflow13 meter-stats $bridge meter=$id
有关更多信息,请参阅 官方 OVS 文档。