OVS-Kernel 硬件加速
OVS-Kernel 是 NVIDIA 设备上默认启用的 OVS 版本。

取消绑定 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 的虚拟机必须关机才能取消绑定 VF。
将 PF 设备上的 eSwitch 模式从 legacy 更改为 switchdev
# devlink dev eswitch set pci/
0000
:3b:00.0
mode switchdev这也会在主机操作系统中创建 VF representor 网络设备。
注意在更改模式之前,请确保所有 VF 都已取消绑定。
信息要返回到 SR-IOV legacy 模式,请运行
# devlink dev eswitch set pci/
0000
:3b:00.0
mode legacy这也将删除 VF representor 网络设备。
在不支持 devlink 的操作系统或内核上,可以使用 sysfs 完成移动到 switchdev 模式
# echo switchdev > /sys/
class
/net/enp4s0f0/compat/devlink/mode在此阶段,已创建 VF representor。要将 representor 映射到其 VF,请确保通过运行以下命令获取 representor 的
switchid
和portname
# ip -d link show eth4
41
: enp0s8f0_1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu1500
qdisc mq state UP mode DEFAULT groupdefault
qlen1000
link/ether ba:e6:21
:37
:bc:d4 brd ff:ff:ff:ff:ff:ff promiscuity0
addrgenmode eui64 numtxqueues10
numrxqueues10
gso_max_size65536
gso_max_segs65535
portname pf0vf1 switchid f4ab580003a1420c其中
switchid
– 用于将 representor 映射到设备,两个设备 PF 具有相同的switchid
portname
– 用于将 representor 映射到 PF 和 VF。返回的值为pf<X>vf<Y>
,其中X
是 PF 编号,Y
是 VF 编号。
绑定 VF
echo
0000
:04
:00.2
> /sys/bus/pci/drivers/mlx5_core/bind echo0000
:04
:00.3
> /sys/bus/pci/drivers/mlx5_core/bind
Switchdev 调优可提高其性能。
Steering 模式
OVS-kernel 支持两种 steering 模式,用于将规则插入到硬件中
SMFS(软件管理流 steering)– 默认模式;规则由软件(驱动程序)直接插入到硬件中。此模式针对规则插入进行了优化。
DMFS(设备管理流 steering)– 规则插入使用固件命令完成。此模式针对吞吐量进行了优化,系统中的规则数量较少。
steering 模式可以通过 sysfs 或 devlink API 在支持它的内核中进行配置
对于 sysfs
echo <smfs|dmfs> > /sys/
class
/net/<pf-netdev>/compat/devlink/steering_mode对于 devlink
devlink dev param set pci/
0000
:00
:08.0
name flow_steering_mode value"<smfs|dmfs>"
cmode runtime
注意
该模式应在移动到 switchdev 之前设置,方法是回显到 sysfs 或调用 devlink 命令。
只有在移动到 switchdev 时,驱动程序才会使用配置的模式。
移动到 switchdev 后,模式无法更改。
steering 模式仅适用于 switchdev 模式(即,它不影响 legacy SR-IOV 或其他配置)。
SMFS 故障排除
mlx5 debugfs 支持呈现软件 Steering 资源。dr_domain
包括其表、matcher 和规则。该接口是只读的。
在创建转储时,无法插入/删除新的 steering 规则,
steering 信息以 CSV 格式转储,格式如下:<object_type>,<object_ID>, <object_info>,...,<object_info>
。
可以在以下路径读取此数据:/sys/kernel/debug/mlx5/<BDF>/steering/fdb/<domain_handle>
。
示例
# cat /sys/kernel/debug/mlx5/0000
:82
:00.0
/steering/fdb/dmn_000018644
3100
,0x55caa4621c50
,0xee802
,4
,65533
3101
,0x55caa4621c50
,0xe0100008
然后,您可以使用 steering 转储解析器使输出更易于阅读。
解析器可以在此 GitHub 存储库中找到。
vPort 匹配模式
OVS-kernel 支持两种模式,用于定义规则如何在 vport 上匹配。
模式 | 描述 |
元数据 | 规则匹配元数据而不是 vport 编号(默认模式)。 此模式用于支持 SR-IOV 实时迁移和双端口 RoCE。 注意
匹配元数据可能会对性能产生影响。 |
Legacy | 规则匹配 vport 编号。 在此模式下,与元数据相比,性能可能更高。它只能在启用/使用 SR-IOV 实时迁移或双端口 RoCE 时使用。 |
vPort 匹配模式可以通过 sysfs 控制
设置 legacy
echo legacy > /sys/
class
/net/<PF netdev>/compat/devlink/vport_match_mode设置元数据
echo metadata > /sys/
class
/net/<PF netdev>/compat/devlink/vport_match_mode
此模式必须在移动到 switchdev 之前设置。
流表大组号
卸载的流(包括连接跟踪 (CT))被添加到虚拟交换机转发数据库 (FDB) 流表中。FDB 表有一组流组,其中每个流组保存相同的流量模式流。例如,对于 CT 卸载流,TCP 和 UDP 是不同的流量模式,最终会进入两个不同的流组。
一个流组具有保存流条目的有限大小。默认情况下,驱动程序有 15 个大型 FDB 流组。这些大型流组中的每一个最多可以保存 4M/(15+1)=256k 个不同的 5 元组流条目。对于具有超过 15 种流量模式的场景,驱动程序提供了一个模块参数 (num_of_groups
) 以允许自定义和性能调优。
该模式可以通过模块参数或 devlink API 在支持它的内核中进行控制
模块参数
echo <num_of_groups> > /sys/module/mlx5_core/parameters/num_of_groups
Devlink
devlink dev param set pci/
0000
:82
:00.0
name fdb_large_groups cmode driverinit value20
如果没有流在 FDB 表中(没有流量运行并且所有卸载的流都已老化),则更改会立即生效。并且可以在不重新加载驱动程序的情况下动态更改它。如果在更改此参数时仍有卸载的流,则在所有流都老化后才会生效。
OVS 配置是带有 switchdev 的简单 OVS 网桥配置。
运行 OVS 服务
systemctl start openvswitch
创建 OVS 网桥(此处命名为
ovs-sriov
)ovs-vsctl add-br ovs-sriov
启用硬件卸载(默认禁用)
ovs-vsctl set Open_vSwitch . other_config:hw-offload=
true
重启 OVS 服务
systemctl restart openvswitch
此步骤是硬件卸载更改生效所必需的。
将 PF 和 VF representor 网络设备添加为 OVS 端口
ovs-vsctl add-port ovs-sriov enp4s0f0 ovs-vsctl add-port ovs-sriov enp4s0f0_0 ovs-vsctl add-port ovs-sriov enp4s0f0_1
确保启动 PF 和 representor 网络设备
ip link set dev enp4s0f0 up ip link set dev enp4s0f0_0 up ip link set dev enp4s0f0_1 up
PF 代表上行链路(线路)
# ovs-dpctl show system
@ovs
-system: lookups: hit:0
missed:192
lost:1
flows:2
masks: hit:384
total:2
hit/pkt:2.00
port0
: ovs-system (internal) port1
: ovs-sriov (internal) port2
: enp4s0f0 port3
: enp4s0f0_0 port4
: enp4s0f0_1从 VF 运行流量并观察添加到 OVS 数据路径的规则
# ovs-dpctl dump-flows recirc_id(
0
),in_port(3
),eth(src=e4:11
:22
:33
:44
:50
,dst=e4:1d:2d:a5:f3:9d), eth_type(0x0800
),ipv4(frag=no), packets:33
, bytes:3234
, used:1
.196s, actions:2
recirc_id(0
),in_port(2
),eth(src=e4:1d:2d:a5:f3:9d,dst=e4:11
:22
:33
:44
:50
), eth_type(0x0800
),ipv4(frag=no), packets:34
, bytes:3332
, used:1
.196s, actions:3
在此示例中,ping 从 VF0(OVS 端口 3)发起,到外部节点(OVS 端口 2),其中 VF MAC 为
e4:11:22:33:44:50
,外部节点 MAC 为e4:1d:2d:a5:f3:9d
。如前所示,添加了两个 OVS 规则,每个方向一个。注意用户还可以通过向命令添加
type=offloaded
来验证卸载的数据包。例如ovs-appctl dpctl/dump-flows type=offloaded
流老化
OVS 的老化超时以毫秒为单位给出,可以通过运行以下命令进行控制
ovs-vsctl set Open_vSwitch . other_config:max-idle=30000
TC 策略
指定用于硬件卸载的策略
none
– 向软件和硬件添加 TC 规则(默认)skip_sw
– 仅向硬件添加 TC 规则skip_hw
– 仅向软件添加 TC 规则
示例
ovs-vsctl set Open_vSwitch . other_config:tc-policy=skip_sw
TC 策略仅应用于调试目的。
max-revalidator
指定重新验证器线程在执行流重新验证之前等待内核统计信息的最长时间(以毫秒为单位)。
ovs-vsctl set Open_vSwitch . other_config:max-revalidator=10000
n-handler-threads
指定软件数据路径用于处理新流的线程数。
ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=4
默认值是在线 CPU 核心数减去重新验证器的数量。
n-revalidator-threads
指定软件数据路径用于重新验证数据路径中流的线程数。
ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=4
vlan-limit
限制可以匹配到指定数量的 VLAN 标头的数量。
ovs-vsctl set Open_vSwitch . other_config:vlan-limit=2
卸载规则也可以直接添加,而不仅仅是通过 OVS,使用 tc
实用程序。
要使用 TC 创建卸载规则
为您希望在其中添加规则的每个接口创建一个入口 qdisc(排队规则)
tc qdisc add dev enp4s0f0 ingress tc qdisc add dev enp4s0f0_0 ingress tc qdisc add dev enp4s0f0_1 ingress
使用以下格式通过 flower 分类器添加 TC 规则
tc filter add dev NETDEVICE ingress protocol PROTOCOL prio PRIORITY [chain CHAIN] flower [MATCH_LIST] [action ACTION_SPEC]
注意支持的匹配(规范)和操作列表可以在“分类字段(匹配)”部分找到。
使用以下格式通过 flower 分类器转储现有的
tc
规则tc [-s] filter show dev NETDEVICE ingress
SR-IOV VF LAG 允许 NIC 的物理功能 (PF) 获取 OVS 尝试卸载到 bond 网络设备的规则,并将它们卸载到硬件 e-switch。
支持的 bond 模式如下
Active-backup
XOR
LACP
SR-IOV VF LAG 实现了 LAG 功能到硬件的完全卸载。绑定创建一个单独的绑定 PF 端口。来自上行链路的数据包可以从任何物理端口到达,并转发到 bond 设备。
当使用硬件卸载时,来自两个端口的数据包都可以转发到任何 VF。来自 VF 的流量可以根据绑定状态转发到两个端口。这意味着当处于 active-backup 模式时,只有一个 PF 处于活动状态,并且来自任何 VF 的流量都通过此 PF。当处于 XOR 或 LACP 模式时,如果两个 PF 都处于活动状态,则来自任何 VF 的流量将在这两个 PF 之间分配。
ASAP2 上 SR-IOV VF LAG 配置
要启用 SR-IOV VF LAG,必须首先将 NIC 的两个物理功能配置为 SR-IOV switchdev 模式,然后才能绑定上行链路 representor。
以下示例显示了在两个 PF 上创建 bond 接口
加载 bond 设备并从属上行链路 representor(当前为 PF)网络设备
modprobe bonding mode=
802
.3ad Ifup bond0 (make sure ifcfg file is present with desired bond configuration) ip link set enp4s0f0 master bond0 ip link set enp4s0f1 master bond0将 VF representor 网络设备添加为 OVS 端口。如果未使用隧道,也添加 bond 设备。
ovs-vsctl add-port ovs-sriov bond0 ovs-vsctl add-port ovs-sriov enp4s0f0_0 ovs-vsctl add-port ovs-sriov enp4s0f1_0
启动 PF 和 representor 网络设备
ip link set dev bond0 up ip link set dev enp4s0f0_0 up ip link set dev enp4s0f1_0 up
配置 SR-IOV VF LAG 后,两个 PF 的所有 VF 都将成为 bond 的一部分,并按上述方式运行。
将 TC 与 VF LAG 结合使用
可以使用或不使用共享块添加这两个规则
使用共享块(内核 4.16 和 RHEL/CentOS 7.7 及更高版本支持)
tc qdisc add dev bond0 ingress_block
22
ingress tc qdisc add dev ens4p0 ingress_block22
ingress tc qdisc add dev ens4p1 ingress_block22
ingress添加丢弃规则
# tc filter add block
22
protocol arp parent ffff: prio3
\ flower \ dst_mac e4:11
:22
:11
:4a:51
\ action drop添加从 bond 到 representor 的重定向规则
# tc filter add block
22
protocol arp parent ffff: prio3
\ flower \ dst_mac e4:11
:22
:11
:4a:50
\ action mirred egress redirect dev ens4f0_0添加从 representor 到 bond 的重定向规则
# tc filter add dev ens4f0_0 protocol arp parent ffff: prio
3
\ flower \ dst_mac ec:0d:9a:8a:28
:42
\ action mirred egress redirect dev bond0
不使用共享块(内核 4.15 及更低版本支持)
添加从 bond 到 representor 的重定向规则
# tc filter add dev bond0 protocol arp parent ffff: prio
1
\ flower \ dst_mac e4:11
:22
:11
:4a:50
\ action mirred egress redirect dev ens4f0_0添加从 representor 到 bond 的重定向规则
# tc filter add dev ens4f0_0 protocol arp parent ffff: prio
3
\ flower \ dst_mac ec:0d:9a:8a:28
:42
\ action mirred egress redirect dev bond0
OVS-Kernel 支持多种分类字段,数据包可以完全或部分匹配。
以太网 Layer 2
目标 MAC
源 MAC
Ethertype
所有内核都支持。
在 OVS 转储流中
skb_priority(0
/0
),skb_mark(0
/0
),in_port(eth6),eth(src=00
:02
:10
:40
:10
:0d,dst=68
:54
:ed:00
:af:de),eth_type(0x8100
), packets:1981
, bytes:206024
, used:0
.440s, dp:tc, actions:eth7
使用 TC 规则
tc filter add dev $rep parent ffff: protocol arp pref 1
\
flower \
dst_mac e4:1d:2d:5d:25
:35
\
src_mac e4:1d:2d:5d:25
:34
\
action mirred egress redirect dev $NIC
IPv4/IPv6
源地址
目标地址
协议
TCP/UDP/ICMP/ICMPv6
TOS
TTL (HLIMIT)
所有内核都支持。
在 OVS 转储流中
Ipv4:
ipv4(src=0.0
.0.0
/0.0
.0.0
,dst=0.0
.0.0
/0.0
.0.0
,proto=17
,tos=0
/0
,ttl=0
/0
,frag=no)
Ipv6:
ipv6(src=::/::,dst=1
:1
:1
::3
:1040
:1008
,label=0
/0
,proto=58
,tclass=0
/0x3
,hlimit=64
),
使用 TC 规则
IPv4:
tc filter add dev $rep parent ffff: protocol ip pref 1
\
flower \
dst_ip 1.1
.1.1
\
src_ip 1.1
.1.2
\
ip_proto TCP \
ip_tos 0x3
\
ip_ttl 63
\
action mirred egress redirect dev $NIC
IPv6:
tc filter add dev $rep parent ffff: protocol ipv6 pref 1
\
flower \
dst_ip 1
:1
:1
::3
:1040
:1009
\
src_ip 1
:1
:1
::3
:1040
:1008
\
ip_proto TCP \
ip_tos 0x3
\
ip_ttl 63
\
action mirred egress redirect dev $NIC
TCP/UDP 源和目标端口以及 TCP 标志
TCP/UDP 源和目标端口
TCP 标志
内核 >4.13 和 RHEL >7.5 支持。
在 OVS 转储流中
TCP: tcp(src=0
/0
,dst=32768
/0x8000
),
UDP: udp(src=0
/0
,dst=32768
/0x8000
),
TCP flags: tcp_flags(0
/0
)
使用 TC 规则
tc filter add dev $rep parent ffff: protocol ip pref 1
\
flower \
ip_proto TCP \
dst_port 100
\
src_port 500
\
tcp_flags 0x4
/0x7
\
action mirred egress redirect dev $NIC
VLAN
ID
优先级
内部 vlan ID 和优先级
支持的内核:全部(QinQ:内核 4.19 及更高版本,以及 RHEL 7.7 及更高版本)。
在 OVS 转储流中
eth_type(0x8100
),vlan(vid=2347
,pcp=0
),
使用 TC 规则
tc filter add dev $rep parent ffff: protocol 802
.1Q pref 1
\
flower \
vlan_ethtype 0x800
\
vlan_id 100
\
vlan_prio 0
\
action mirred egress redirect dev $NIC
QinQ:
tc filter add dev $rep parent ffff: protocol 802
.1Q pref 1
\
flower \
vlan_ethtype 0x8100
\
vlan_id 100
\
vlan_prio 0
\
cvlan_id 20
\
cvlan_prio 0
\
cvlan_ethtype 0x800
\
action mirred egress redirect dev $NIC
隧道
ID(键)
源 IP 地址
目标 IP 地址
目标端口
TOS(内核 4.19 及更高版本和 RHEL 7.7 及更高版本支持)
TTL(内核 4.19 及更高版本和 RHEL 7.7 及更高版本支持)
隧道选项 (Geneve)
支持的内核
VXLAN:全部
GRE:内核 >5.0,RHEL 7.7 及更高版本
Geneve:内核 >5.0,RHEL 7.7 及更高版本
在 OVS 转储流中
tunnel(tun_id=0x5
,src=121.9
.1.1
,dst=131.10
.1.1
,ttl=0
/0
,tp_dst=4789
,flags(+key))
使用 TC 规则
# tc filter add dev $rep protocol 802
.1Q parent ffff: pref 1
flower \
vlan_ethtype 0x800
\
vlan_id 100
\
vlan_prio 0
\
action mirred egress redirect dev $NIC
QinQ:
# tc filter add dev vxlan100 protocol ip parent ffff: \
flower \
skip_sw \
dst_mac e4:11
:22
:11
:4a:51
\
src_mac e4+:11
:22
:11
:4a:50
\
enc_src_ip 20.1
.11.1
\
enc_dst_ip 20.1
.12.1
\
enc_key_id 100
\
enc_dst_port 4789
\
action tunnel_key unset \
action mirred egress redirect dev ens4f0_0
转发
转发操作允许数据包重定向
从 VF 到线路
线路到 VF
VF 到 VF
所有内核都支持。
在 OVS 转储流中
skb_priority(0
/0
),skb_mark(0
/0
),in_port(eth6),eth(src=00
:02
:10
:40
:10
:0d,dst=68
:54
:ed:00
:af:de),eth_type(0x8100
), packets:1981
, bytes:206024
, used:0
.440s, dp:tc, actions:eth7
使用 TC 规则
tc filter add dev $rep parent ffff: protocol arp pref 1
\
flower \
dst_mac e4:1d:2d:5d:25
:35
\
src_mac e4:1d:2d:5d:25
:34
\
action mirred egress redirect dev $NIC
丢弃
丢弃操作允许丢弃传入的数据包。
所有内核都支持。
在 OVS 转储流中
skb_priority(0
/0
),skb_mark(0
/0
),in_port(eth6),eth(src=00
:02
:10
:40
:10
:0d,dst=68
:54
:ed:00
:af:de),eth_type(0x8100
), packets:1981
, bytes:206024
, used:0
.440s, dp:tc, actions:drop
使用 TC 规则
tc filter add dev $rep parent ffff: protocol arp pref 1
\
flower \
dst_mac e4:1d:2d:5d:25
:35
\
src_mac e4:1d:2d:5d:25
:34
\
action drop
统计信息
默认情况下,每个流收集以下统计信息
数据包 – 命中流的数据包数量
字节 – 命中流的总字节数
上次使用 – 自上次数据包命中流以来经过的时间
所有内核都支持。
在 OVS 转储流中
skb_priority(0
/0
),skb_mark(0
/0
),in_port(eth6),eth(src=00
:02
:10
:40
:10
:0d,dst=68
:54
:ed:00
:af:de),eth_type(0x8100
), packets:1981
, bytes:206024
, used:0
.440s, dp:tc, actions:drop
使用 TC 规则
#tc -s filter show dev $rep ingress
filter protocol ip pref 2
flower chain 0
filter protocol ip pref 2
flower chain 0
handle 0x2
eth_type ipv4
ip_proto tcp
src_ip 192.168
.140.100
src_port 80
skip_sw
in_hw
action order 1
: mirred (Egress Redirect to device p0v11_r) stolen
index 34
ref 1
bind 1
installed 144
sec used 0
sec
Action statistics:
Sent 388344
bytes 2942
pkt (dropped 0
, overlimits 0
requeues 0
)
backlog 0b 0p requeues 0
隧道:封装/解封装
OVS-kernel 支持使用封装和解封装操作卸载隧道。
封装 – 在 Tx 上支持推送隧道标头
解封装 – 在 Rx 上支持弹出隧道标头
支持的隧道
VXLAN (IPv4/IPv6) – 所有内核都支持
GRE (IPv4/IPv6) – 内核 5.0 及更高版本和 RHEL 7.6 及更高版本支持
Geneve (IPv4/IPv6) – 内核 5.0 及更高版本和 RHEL 7.6 及更高版本支持
OVS 配置
在卸载隧道的情况下,PF/bond 不应作为端口添加到 OVS 数据路径中。它应该分配用于封装的 IP 地址。
以下示例显示了两个主机 (PF),IP 分别为 1.1.1.177 和 1.1.1.75,其中两个主机上的 PF 设备均为 enp4s0f0,并且 VXLAN 隧道设置为 VNID 98
在第一台主机上
# ip addr add
1.1
.1.177
/24
dev enp4s0f1 # ovs-vsctl add-port ovs-sriov vxlan0 -- setinterface
vxlan0 type=vxlan options:local_ip=1.1
.1.177
options:remote_ip=1.1
.1.75
options:key=98
在第二台主机上
# ip addr add
1.1
.1.75
/24
dev enp4s0f1 # ovs-vsctl add-port ovs-sriov vxlan0 -- setinterface
vxlan0 type=vxlan options:local_ip=1.1
.1.75
options:remote_ip=1.1
.1.177
options:key=98
信息对于 GRE IPv4 隧道,请使用
type=gre
。对于 GRE IPv6 隧道,请使用type=ip6gre
。对于 Geneve 隧道,请使用type=geneve
。
当封装访客流量时,必须减小 VF 的设备 MTU,以允许主机/硬件添加封装标头,而不会分片生成的数据包。因此,对于 IPv4,VF 的 MTU 必须比上行链路 MTU 低 50 字节,对于 IPv6,则低 70 字节。
使用 TC 规则卸载隧道
Encapsulation:
# tc filter add dev ens4f0_0 protocol 0x806
parent ffff: \
flower \
skip_sw \
dst_mac e4:11
:22
:11
:4a:51
\
src_mac e4:11
:22
:11
:4a:50
\
action tunnel_key set \
src_ip 20.1
.12.1
\
dst_ip 20.1
.11.1
\
id 100
\
action mirred egress redirect dev vxlan100
Decapsulation:
# tc filter add dev vxlan100 protocol 0x806
parent ffff: \
flower \
skip_sw \
dst_mac e4:11
:22
:11
:4a:51
\
src_mac e4:11
:22
:11
:4a:50
\
enc_src_ip 20.1
.11.1
\
enc_dst_ip 20.1
.12.1
\
enc_key_id 100
\
enc_dst_port 4789
\
action tunnel_key unset \
action mirred egress redirect dev ens4f0_0
VLAN 推送/弹出
OVS-kernel 支持卸载 VLAN 标头推送/弹出操作
推送 – 在 Tx 上支持推送 VLAN 标头
弹出 – 在 Rx 上支持弹出隧道标头
OVS 配置
为添加 representor 端口的 OVS 命令行添加 tag=$TAG 部分。例如,此处使用 VLAN ID 52。
# ovs-vsctl add-port ovs-sriov enp4s0f0
# ovs-vsctl add-port ovs-sriov enp4s0f0_0 tag=52
# ovs-vsctl add-port ovs-sriov enp4s0f0_1 tag=52
PF 端口不应附加 VLAN。这将导致 OVS 在管理这些 VF 的流量时添加 VLAN 推送/弹出操作。
转储流示例
recirc_id(0
),in_port(3
),eth(src=e4:11
:22
:33
:44
:50
,dst=00
:02
:c9:e9:bb:b2),eth_type(0x0800
),ipv4(frag=no), \
packets:0
, bytes:0
, used:never, actions:push_vlan(vid=52
,pcp=0
),2
recirc_id(0
),in_port(2
),eth(src=00
:02
:c9:e9:bb:b2,dst=e4:11
:22
:33
:44
:50
),eth_type(0x8100
), \
vlan(vid=52
,pcp=0
),encap(eth_type(0x0800
),ipv4(frag=no)), packets:0
, bytes:0
, used:never, actions:pop_vlan,3
使用 TC 规则的 VLAN 卸载示例
# tc filter add dev ens4f0_0 protocol ip parent ffff: \
flower \
skip_sw \
dst_mac e4:11
:22
:11
:4a:51
\
src_mac e4:11
:22
:11
:4a:50
\
action vlan push id 100
\
action mirred egress redirect dev ens4f0
# tc filter add dev ens4f0 protocol 802
.1Q parent ffff: \
flower \
skip_sw \
dst_mac e4:11
:22
:11
:4a:51
\
src_mac e4:11
:22
:11
:4a:50
\
vlan_ethtype 0x800
\
vlan_id 100
\
vlan_prio 0
\
action vlan pop \
action mirred egress redirect dev ens4f0_0
TC 配置
使用 TC 规则在 Tx 上弹出标头并在 Rx 上推送的 VLAN 卸载示例
# tc filter add dev ens4f0_0 ingress protocol 802
.1Q parent ffff: \
flower \
vlan_id 100
\
action vlan pop \
action tunnel_key set \
src_ip 4.4
.4.1
\
dst_ip 4.4
.4.2
\
dst_port 4789
\
id 42
\
action mirred egress redirect dev vxlan0
# tc filter add dev vxlan0 ingress protocol all parent ffff: \
flower \
enc_dst_ip 4.4
.4.1
\
enc_src_ip 4.4
.4.2
\
enc_dst_port 4789
\
enc_key_id 42
\
action tunnel_key unset \
action vlan push id 100
\
action mirred egress redirect dev ens4f0_0
报头重写
此操作允许修改数据包字段。
以太网 Layer 2
目标 MAC
源 MAC
支持的内核
内核 4.14 及更高版本
RHEL 7.5 及更高版本
在 OVS 转储流中
skb_priority(0
/0
),skb_mark(0
/0
),in_port(eth6),eth(src=00
:02
:10
:40
:10
:0d,dst=68
:54
:ed:00
:af:de),eth_type(0x8100
), packets:1981
, bytes:206024
, used:0
.440s, dp:tc, actions: set(eth(src=68
:54
:ed:00
:f4:ab,dst=fa:16
:3e:dd:69
:c4)),eth7
使用 TC 规则
tc filter add dev $rep parent ffff: protocol arp pref 1
\
flower \
dst_mac e4:1d:2d:5d:25
:35
\
src_mac e4:1d:2d:5d:25
:34
\
action pedit ex \
munge eth dst set 20
:22
:33
:44
:55
:66
\
munge eth src set aa:ba:cc:dd:ee:fe \
action mirred egress redirect dev $NIC
IPv4/IPv6
源地址
目标地址
协议
TOS
TTL (HLIMIT)
支持的内核
内核 4.14 及更高版本
RHEL 7.5 及更高版本
在 OVS 转储流中
Ipv4:
set(eth(src=de:e8:ef:27
:5e:45
,dst=00
:00
:01
:01
:01
:01
)),
set(ipv4(src=10.10
.0.111
,dst=10.20
.0.122
,ttl=63
))
Ipv6:
set(ipv6(dst=2001
:1
:6
::92eb:fcbe:f1c8,hlimit=63
)),
使用 TC 规则
IPv4:
tc filter add dev $rep parent ffff: protocol ip pref 1
\
flower \
dst_ip 1.1
.1.1
\
src_ip 1.1
.1.2
\
ip_proto TCP \
ip_tos 0x3
\
ip_ttl 63
\
pedit ex \
munge ip src set 2.2
.2.1
\
munge ip dst set 2.2
.2.2
\
munge ip tos set 0
\
munge ip ttl dec \
action mirred egress redirect dev $NIC
IPv6:
tc filter add dev $rep parent ffff: protocol ipv6 pref 1
\
flower \
dst_ip 1
:1
:1
::3
:1040
:1009
\
src_ip 1
:1
:1
::3
:1040
:1008
\
ip_proto tcp \
ip_tos 0x3
\
ip_ttl 63
\
pedit ex \
munge ipv6 src set 2
:2
:2
::3
:1040
:1009
\
munge ipv6 dst set 2
:2
:2
::3
:1040
:1008
\
munge ipv6 hlimit dec \
action mirred egress redirect dev $NIC
IPv4 和 IPv6 报头重写仅支持匹配 UDP/TCP/ICMP 协议。
TCP/UDP 源和目标端口
TCP/UDP 源和目标端口
支持的内核
内核 4.16 及更高版本
RHEL 7.6 及更高版本
在 OVS 转储流中
TCP:
set(tcp(src= 32768
/0xffff
,dst=32768
/0xffff
)),
UDP:
set(udp(src= 32768
/0xffff
,dst=32768
/0xffff
)),
使用 TC 规则
TCP:
tc filter add dev $rep parent ffff: protocol ip pref 1
\
flower \
dst_ip 1.1
.1.1
\
src_ip 1.1
.1.2
\
ip_proto tcp \
ip_tos 0x3
\
ip_ttl 63
\
pedit ex \
pedit ex munge ip tcp sport set 200
pedit ex munge ip tcp dport set 200
action mirred egress redirect dev $NIC
UDP:
tc filter add dev $rep parent ffff: protocol ip pref 1
\
flower \
dst_ip 1.1
.1.1
\
src_ip 1.1
.1.2
\
ip_proto udp \
ip_tos 0x3
\
ip_ttl 63
\
pedit ex \
pedit ex munge ip udp sport set 200
pedit ex munge ip udp dport set 200
action mirred egress redirect dev $NIC
VLAN
ID
所有内核都支持。
在 OVS 转储流中
Set(vlan(vid=2347
,pcp=0
/0
)),
使用 TC 规则
tc filter add dev $rep parent ffff: protocol 802
.1Q pref 1
\
flower \
vlan_ethtype 0x800
\
vlan_id 100
\
vlan_prio 0
\
action vlan modify id 11
pipe
action mirred egress redirect dev $NIC
连接跟踪
TC 连接跟踪 (CT) 操作通过将数据包发送到 netfilter conntrack 模块来执行 CT 查找。新添加的连接可以通过 ct commit
操作与 32 位标记、128 位标签和源/目标 NAT 值关联。
以下示例允许从上行链路 representor 到 vf1_rep
的入口 TCP 流量,同时确保仅允许来自 vf1_rep
的出口流量在已建立的连接上。此外,还应用了标记和源 IP NAT。
在 OVS 转储流中
ct(zone=2
,nat)
ct_state(+est+trk)
actions:ct(commit,zone=2
,mark=0x4
/0xffffffff
,nat(src=5.5
.5.5
))
使用 TC 规则
# tc filter add dev $uplink_rep ingress chain 0
prio 1
proto ip \
flower \
ip_proto tcp \
ct_state -trk \
action ct zone 2
nat pipe
action goto
chain 2
# tc filter add dev $uplink_rep ingress chain 2
prio 1
proto ip \
flower \
ct_state +trk+new
\
action ct zone 2
commit mark 0xbb
nat src addr 5.5
.5.7
pipe \
action mirred egress redirect dev $vf1_rep
# tc filter add dev $uplink_rep ingress chain 2
prio 1
proto ip \
flower \
ct_zone 2
\
ct_mark 0xbb
\
ct_state +trk+est \
action mirred egress redirect dev $vf1_rep
// Setup filters on $vf1_rep, allowing only established connections of zone 2 through, and reverse nat (dst nat in this case)
# tc filter add dev $vf1_rep ingress chain 0
prio 1
proto ip \
flower \
ip_proto tcp \
ct_state -trk \
action ct zone 2
nat pipe \
action goto
chain 1
# tc filter add dev $vf1_rep ingress chain 1
prio 1
proto ip \
flower \
ct_zone 2
\
ct_mark 0xbb
\
ct_state +trk+est \
action mirred egress redirect dev eth0
CT 性能调优
最大卸载连接数 – 指定卸载连接数的限制。示例
devlink dev param set pci/${pci_dev} name ct_max_offloaded_conns value $max cmode runtime
允许混合 NAT/非 NAT CT – 允许卸载以下场景
• cookie=
0x0
, duration=21
.843s, table=0
, n_packets=4838718
, n_bytes=241958846
, ct_state=-trk,ip,in_port=enp8s0f0 actions=ct(table=1
,zone=2
) • cookie=0x0
, duration=21
.823s, table=1
, n_packets=15363
, n_bytes=773526
, ct_state=+new
+trk,ip,in_port=enp8s0f0 actions=ct(commit,zone=2
,nat(dst=11.11
.11.11
)),output:"enp8s0f0_1"
• cookie=0x0
, duration=21
.806s, table=1
, n_packets=4767594
, n_bytes=238401190
, ct_state=+est+trk,ip,in_port=enp8s0f0 actions=ct(zone=2
,nat),output:"enp8s0f0_1"
示例
echo enable > /sys/
class
/net/<device>/compat/devlink/ct_action_on_nat_conns
转发到链 (仅限 TC)
TC 接口支持在不同链上添加流。默认情况下仅访问链 0。访问其他链需要使用 goto
操作。
在此示例中,在链 1 上创建了一个没有匹配项的流,并重定向到线路。
第二个流在链 0 上创建,并匹配源 MAC 和操作 goto
链 1。
此示例模拟简单的 MAC 欺骗
#tc filter add dev $rep parent ffff: protocol all chain 1
pref 1
\
flower \
action mirred egress redirect dev $NIC
#tc filter add dev $rep parent ffff: protocol all chain 1
pref 1
\
flower \
src_mac aa:bb:cc:aa:bb:cc \
action goto
chain 1
与半虚拟化配置不同,当 VM 流量通过 SR-IOV VF 卸载到硬件时,主机端管理员无法侦听流量(例如,用于监控)。
ASAP² 使用 OVS 和 TC 中现有的镜像支持以及驱动程序中卸载逻辑的增强功能,以允许将 VF 流量镜像到另一个 VF。
镜像 VF 可用于运行流量分析器(例如,tcpdump、wireshark 等)并观察被镜像的 VF 的流量。
以下示例显示了在以下配置上创建端口镜像
# ovs-vsctl show
09d8a574-9c39-465c-9f16-47d81c12f88a
Bridge br-vxlan
Port "enp4s0f0_1"
Interface "enp4s0f0_1"
Port "vxlan0"
Interface "vxlan0"
type: vxlan
options: {key="100"
, remote_ip="192.168.1.14"
}
Port "enp4s0f0_0"
Interface "enp4s0f0_0"
Port "enp4s0f0_2"
Interface "enp4s0f0_2"
Port br-vxlan
Interface br-vxlan
type: internal
ovs_version: "2.14.1"
要将
enp4s0f0_0
设置为镜像端口并镜像所有流量# ovs-vsctl -- --id=
@p
get port enp4s0f0_0 \ -- --id=@m
create mirror name=m0 select-all=true
output-port=@p
\ -- set bridge br-vxlan mirrors=@m
要将
enp4s0f0_0
设置为镜像端口,仅镜像流量,并将enp4s0f0_1
设置为目标端口# ovs-vsctl -- --id=
@p1
get port enp4s0f0_0 \ -- --id=@p2
get port enp4s0f0_1 \ -- --id=@m
create mirror name=m0 select-dst-port=@p2
output-port=@p1
\ -- set bridge br-vxlan mirrors=@m
要将
enp4s0f0_0
设置为镜像端口,仅镜像流量,并将enp4s0f0_1
设置为源端口# ovs-vsctl -- --id=
@p1
get port enp4s0f0_0 \ -- --id=@p2
get port enp4s0f0_1 \ -- --id=@m
create mirror name=m0 select-src-port=@p2
output-port=@p1
\ -- set bridge br-vxlan mirrors=@m
要将
enp4s0f0_0
设置为镜像端口并镜像enp4s0f0_1
上的所有流量# ovs-vsctl -- --id=
@p1
get port enp4s0f0_0 \ -- --id=@p2
get port enp4s0f0_1 \ -- --id=@m
create mirror name=m0 select-dst-port=@p2
select-src-port=@p2
output-port=@p1
\ -- set bridge br-vxlan mirrors=@m
要清除镜像端口
ovs-vsctl clear bridge br-vxlan mirrors
使用 TC 镜像
镜像到 VF
tc filter add dev $rep parent ffff: protocol arp pref
1
\ flower \ dst_mac e4:1d:2d:5d:25
:35
\ src_mac e4:1d:2d:5d:25
:34
\ action mirred egress mirror dev $mirror_rep pipe \ action mirred egress redirect dev $NIC镜像到隧道
tc filter add dev $rep parent ffff: protocol arp pref
1
\ flower \ dst_mac e4:1d:2d:5d:25
:35
\ src_mac e4:1d:2d:5d:25
:34
\ action tunnel_key set \ src_ip1.1
.1.1
\ dst_ip1.1
.1.2
\ dst_port4789
\ id768
\ pipe \ action mirred egress mirror dev vxlan100 pipe \ action mirred egress redirect dev $NIC
使用 TC 支持转发到最多 32 个目标(representor 和隧道)
示例 1 – 转发到 32 个 VF
tc filter add dev $NIC parent ffff: protocol arp pref
1
\ flower \ dst_mac e4:1d:2d:5d:25
:35
\ src_mac e4:1d:2d:5d:25
:34
\ action mirred egress mirror dev $rep0 pipe \ action mirred egress mirror dev $rep1 pipe \ ... action mirred egress mirror dev $rep30 pipe \ action mirred egress redirect dev $rep31示例 2 – 转发到 16 个隧道
tc filter add dev $rep parent ffff: protocol arp pref
1
\ flower \ dst_mac e4:1d:2d:5d:25
:35
\ src_mac e4:1d:2d:5d:25
:34
\ action tunnel_key set src_ip $ip_src dst_ip $ip_dst \ dst_port4789
id0
nocsum \ pipe action mirred egress mirror dev vxlan0 pipe \ action tunnel_key set src_ip $ip_src dst_ip $ip_dst \ dst_port4789
id1
nocsum \ pipe action mirred egress mirror dev vxlan0 pipe \ ... action tunnel_key set src_ip $ip_src dst_ip $ip_dst \ dst_port4789
id15
nocsum \ pipe action mirred egress redirect dev vxlan0
TC 最多支持 32 个操作。
如果使用报头重写,则所有目标应具有相同的报头重写。
如果使用 VLAN 推送/弹出,则所有目标应具有相同的 VLAN ID 和操作。
sFlow 允许使用 sFlow 收集器监控在同一主机上的两个 VM 之间发送的流量。
以下示例假定环境已按稍后描述的方式配置。
# ovs-vsctl show
09d8a574-9c39-465c-9f16-47d81c12f88a
Bridge br-vxlan
Port "enp4s0f0_1"
Interface "enp4s0f0_1"
Port "vxlan0"
Interface "vxlan0"
type: vxlan
options: {key="100"
, remote_ip="192.168.1.14"
}
Port "enp4s0f0_0"
Interface "enp4s0f0_0"
Port "enp4s0f0_2"
Interface "enp4s0f0_2"
Port br-vxlan
Interface br-vxlan
type: internal
ovs_version: "2.14.1"
要采样 OVS 网桥上的所有流量
# ovs-vsctl -- --id=@sflow
create sflow agent=\"$SFLOW_AGENT\" \
target=\"$SFLOW_TARGET:$SFLOW_PORT\" \
header=$SFLOW_HEADER \
sampling=$SFLOW_SAMPLING polling=10
\
-- set bridge br-vxlan sflow=@sflow
参数 | 描述 |
| 指示 sFlow 代理应从 |
| sFlow 收集器的远程 IP 地址 |
| 要采样的数据包标头大小(以字节为单位) |
| 采样率 |
要清除 sFlow 配置
# ovs-vsctl clear bridge br-vxlan sflow
要列出 sFlow 配置
# ovs-vsctl list sflow
使用 TC 的 sFlow
Sample to VF
tc filter add dev $rep parent ffff: protocol arp pref 1
\
flower \
dst_mac e4:1d:2d:5d:25
:35
\
src_mac e4:1d:2d:5d:25
:34
\
action sample rate 10
group 5
trunc 96
\
action mirred egress redirect dev $NIC
需要一个用户空间应用程序来处理来自内核的采样数据包。示例可在Github上找到。
OVS-kernel 支持使用 OVS 配置和 TC 卸载 VF 速率限制。
以下示例将与 representor eth0
相关的 VF 的速率限制设置为 10Mb/s
OVS
ovs-vsctl set
interface
eth0 ingress_policing_rate=10000
TC
tc_filter add dev eth0 root prio
1
protocol ip matchall skip_sw action police rate 10mbit burst 20k
应启用此内核配置以支持 switchdev 卸载。
CONFIG_NET_ACT_CSUM
– action csum 所需CONFIG_NET_ACT_PEDIT
– 报头重写所需CONFIG_NET_ACT_MIRRED
– 基本转发所需CONFIG_NET_ACT_CT
– CT 所需(内核 5.6 及更高版本支持)CONFIG_NET_ACT_VLAN
– action vlan push/pop 所需CONFIG_NET_ACT_GACT
CONFIG_NET_CLS_FLOWER
CONFIG_NET_CLS_ACT
CONFIG_NET_SWITCHDEV
CONFIG_NET_TC_SKB_EXT
– CT 所需(内核 5.6 及更高版本支持)CONFIG_NET_ACT_CT
– CT 所需(内核 5.6 及更高版本支持)CONFIG_NFT_FLOW_OFFLOAD
CONFIG_NET_ACT_TUNNEL_KEY
CONFIG_NF_FLOW_TABLE
– CT 所需(内核 5.6 及更高版本支持)CONFIG_SKB_EXTENSIONS
– CT 所需(内核 5.6 及更高版本支持)CONFIG_NET_CLS_MATCHALL
CONFIG_NET_ACT_POLICE
CONFIG_MLX5_ESWITCH
OVS-kernel 支持使用 sysfs 卸载 VF 计量(TX 和 RX)。支持计量每秒数据包数 (PPS) 和每秒字节数 (BPS)。
以下示例在 VF 0 上设置 Rx meter,值为 10Mb/s BPS
echo 10000000
> /sys/class
/net/enp4s0f0/device/sriov/0
/meters/rx/bps/rate
echo 65536
> /sys/class
/net/enp4s0f0/device/sriov/0
/meters/rx/bps/burst
以下示例在 VF 0 上设置 Tx meter,值为 1000 PPS
echo 1000
> /sys/class
/net/enp4s0f0/device/sriov/0
/meters/tx/pps/rate
echo 100
> /sys/class
/net/enp4s0f0/device/sriov/0
/meters/tx/pps/burst
rate
和 burst
都不能为零,并且可能需要根据要求调整 burst
。
以下计数器可用于查询丢弃的数据包/字节数
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/rx/pps/packets_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/rx/pps/bytes_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/rx/bps/packets_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/rx/bps/bytes_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/tx/pps/packets_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/tx/pps/bytes_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/tx/bps/packets_dropped
cat /sys/class
/net/enp8s0f0/device/sriov/0
/meters/tx/bps/bytes_dropped
支持上行链路和 VF representor 流量的计量。
流向 representor 设备的流量可能是嵌入式交换机 (eSwitch) FDB 表中未命中的结果。这意味着从该 representor 到达 eSwitch 的数据包与硬件 FDB 表中的现有规则不匹配,必须转发到软件进行处理,因此转发到原始 representor 设备驱动程序。
meter 允许为流向 representor 驱动程序的流量配置最大速率 [每秒数据包数] 和最大突发 [数据包]。任何超过用户提供的值的流量都将在硬件中丢弃。有统计信息显示丢弃的数据包数。
representor 计量的配置通过 miss_rl_cfg
完成。
miss_rl_cfg
参数的完整路径:/sys/class/net//rep_config/miss_rl_cfg
用法:
echo "<rate> <burst>" > /sys/class/net//rep_config/miss_rl_cfg
。rate
是此 representor 允许的最大数据包速率(以数据包/秒为单位)burst
是此 representor 允许的最大突发大小(以数据包为单位)必须指定这两个值。它们的默认值均为 0,表示速率和突发不受限制。
要查看由于流量超过用户提供的速率和突发而丢弃的数据包和字节数,可以使用两个只读 sysfs 统计信息
/sys/class/net//rep_config/miss_rl_dropped_bytes
– 计数由于达到未命中限制而丢弃的 FDB 未命中字节数/sys/class/net//rep_config/miss_rl_dropped_packets
– 计数由于达到未命中限制而丢弃的 FDB 未命中数据包数
meter 有两种类型,kpps(千比特每秒)和 pktps(数据包每秒)。OVS-Kernel 支持卸载这两种 meter。
以下示例是卸载 kpps meter。
创建具有目标速率的 OVS meter
ovs-ofctl -O OpenFlow13 add-meter ovs-sriov meter=
1
,kbps,band=type=drop,rate=204800
删除默认规则
ovs-ofctl del-flows ovs-sriov
配置 OpenFlow 规则
ovs-ofctl -O OpenFlow13 add-flow ovs-sriov
'ip,dl_dst=e4:11:22:33:44:50,actions= meter:1,output:enp4s0f0_0'
ovs-ofctl -O OpenFlow13 add-flow ovs-sriov'ip,dl_src=e4:11:22:33:44:50,actions= output:enp4s0f0'
ovs-ofctl -O OpenFlow13 add-flow ovs-sriov'arp,actions=normal'
在这里,接收端的 VF 带宽受到步骤 1 中配置的速率的限制。
运行 iperf 服务器并准备好接收 UDP 流量。在外部节点上,运行 iperf 客户端以将 UDP 流量发送到此 VF。流量开始后,检查卸载的 meter 规则
ovs-appctl dpctl/dump-flows --names type=offloaded recirc_id(
0
),in_port(enp4s0f0),eth(dst=e4:11
:22
:33
:44
:50
),eth_type(0x0800
),ipv4(frag=no), packets:11626587
, bytes:17625889188
, used:0
.470s, actions:meter(0
),enp4s0f0_0
要验证计量,iperf 客户端应将目标带宽设置为大于配置的 meter 速率的数字。然后,应该明显的是,数据包以服务器端受限的速率接收,而额外的数据包被硬件丢弃。
多端口 eswitch 模式允许在 VF representor 上添加规则,该规则的操作是将数据包转发到物理功能的物理端口。这可以用于实现故障转移或根据外部信息(例如路由成本)转发数据包。
要配置多端口 eswitch 模式,必须设置 nvconfig 参数
LAG_RESOURCE_ALLOCATION
。驱动程序加载后,为每个 PF 配置多端口 eSwitch,其中
enp8s0f0
和enp8s0f1
代表 PF 的网络设备echo multiport_esw > /sys/
class
/net/enp8s0f0/compat/devlink/lag_port_select_mode echo multiport_esw > /sys/class
/net/enp8s0f1/compat/devlink/lag_port_select_mode在两个 PF 上进入 switchdev 模式后,该模式即可运行。
规则示例
tc filter add dev enp8s0f0_0 prot ip root flower dst_ip 7.7
.7.7
action mirred egress redirect dev enp8s0f1