目录
- dpvs中 fdir 规则的形式与数量
- signature mode fdir 的冲突测试
- 思路
背景
fdir mode
fdir mode 分为 perfect mode, 和 signature mode。
perfect mode :完美匹配,即精确匹配。
signature mode: fuzzy match,模糊匹配。
我的理解:
- 网卡存储的规则:
下发 fdir rule,存储的是 全局的 各个item 的 mask,以及 每个 fdir 的 多个 item 的 value & mask 之后的值。 - 规则匹配:
数据包匹配时,从包中提取指定字段,然后和全局的mask 进行掩码操作;再逐个 item进行比较查找,直到所有 item 都匹配的 flow rule,即为查找到。
我的理解:
- 网卡存储的规则:
下发 fdir rule,存储的是 全局的 各个item 的 mask,基于 每个 fdir 的 多个 item 的 value & mask 之后的值 进行 计算 hash value,存储 hash vlaue。 这样可以节省硬件的内存空间,因为 ipv6 地址占用16个字节,只存储 hash value 占用内存小。 - 规则匹配:
数据包匹配时,从包中提取指定字段,然后和全局的mask 进行掩码操作,然后hash 得到hash_value;再基于 hash_valued 匹配某个 fdir规则。
简单看了下,ixgbe 没有检查底层是否存在某个 flow rule和要配置的flow rule 的冲突的检查。
具体实现查看:
ixgbe_flow_ops–> ixgbe_flow_validate --> ixgbe_parse_fdir_filter --> ixgbe_parse_fdir_filter_normal --> ixgbe_parse_fdir_act_attr
此中:存在ipv6 fdir rule 的检查(包含pattern,rule, attribute);
注:
ixgbe 没有实现 ixgbe_flow_query。
mlx5 驱动的实现参见:mlx5_flow_ops
其实现了 mlx5_flow_query。
问题
intel 82599 网卡不支持 ipv6 perfect mode的fdir 规则;ipv6_lip:slave_index fdir规则,只能以 signature 的形式下发。
但是有可能两个 signature fdir 的 hash 值相同,但是 action 是导流到不同的 queue。那么就只有一个signature fdir rule 会生效,可能插入第二个 fdir rule 时会失败。
即: hash key不同,但是 hash value 相同。但是由于存储的是 hash value, hash key 并不存储。
比如:
- signature_rule1:
dip== ip1, dport = port1;
pattern: hash(ip1, port1) = value1;
action: redirect to queue 1; - signature_rule2:
dip==ip1, dport == port2;
patthern: hash(ip1, port2) = value1;
action: redirect to queue 2;
先插入rule1, 再插入rule2,则失败,底层只存在rule1,不存在rule2。本来应该匹配到 rule2,导流到queue 2 的流量,只能匹配到 rule1, 导流到 queue 1。
另外,82599 的 fdir mode 是一个全局的配置,不可以基于 fdir rule 来设定。
另外 fnat44, fnat46, fnat66, fnat64 同时满足 需要 ipv4 fdir 和 ipv6 fdir 共存。但是由于 82599 对于 ipv6 fdir 的限制,只能使用 signature mode fdir。
dpvs中 fdir 规则的形式与数量
dstip = lip, mask = 255.255.255.255;
dstport = slave_lcore, mask = slave的个数向上2的N次方取整,然后-1;
lip_num * slave_num * proto_num;
比如:20个 lip,16个slave,proto为2*2(tcp/udp, ipv4/ipv6)
则 单机的 fdir 个数为:
N = 20 * 16 * 2 * 2 = 1280
signature mode fdir 的冲突测试
查看:
dpip -x link show lan | grep flow_
注:dpip -x link show 底层调用的是:rte_eth_xstats_get
(1)1个 ipv4-lip, 8个slave, signature mode, pballoc 128k;;
fdir个数: 1(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 16
# dpip -x link show lan | grep flow_
flow_director_added_filters: 16
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 114
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
----
(2)1个 ipv4-lip, 16个slave, signature mode, pballoc 128k;;
fdir个数: 1(lip_num) * 16(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 32
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 55
flow_director_missed_filters: 5
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
-----
(3)2个 ipv4-lip,8个slave, signature mode, pballoc 128k;
(lip: 192.21.2.14-15, 14即0E, 15即0F)
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 16
flow_director_removed_filters: 0
flow_director_filter_add_errors: 16
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 35
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
-----
(4) 2个 ipv4-lip, 8个slave, signature mode, pballoc 128k;
(lip: 192.21.2.15-16, 15即0F, 16即10)
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 32
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 25
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
总结:如上所示:
1》只有一个ipv4-lip,不会发生冲突。
2》多余一个ipv4-lip,感觉低4bit 不参与,只要其他的高28bit相同,则会发送冲突。
其他的高28bit不同,则不发送冲突。
3》冲突和 pballoc 不相关,和 status 不相关。
基于 82599 datasheet,64k pballoc 的情况下,支持 8k-2 个规则。
128k pballoc, 支持 16k -2 个 规则.
4》没有打流量时,也会有 matched_filters/missed_filters:
因为是 signature 模式,tcp/udp健康检查报文,dip=lip 也可能会匹配到 某个 fdir rule。但是对于 lan和lan-gw的ping报文,无法匹配到 fdir rule。
(1) 2个 ipv6-lip, 8个slave, signature mode, pballoc 128k;
(lip: 2402:5ec0:1001:3010:192:21:2:0b-0c)
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 16
flow_director_removed_filters: 0
flow_director_filter_add_errors: 16
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 24
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
----
(2)2个 ipv6-lip, 8个slave, signature mode, pballoc 128k;
lip: 2402:5ec0:1001:3010:192:21:2:0F-10
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 32
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 26
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
----
(3)12个ipv6-lip, 8个slave, signature mode, pballoc 128k;
lip: (2402:5ec0:1001:3010:192:21:2:0b-16)
fdir个数: 12(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 192
# dpip -x link show lan | grep flow_
flow_director_added_filters: 32
flow_director_removed_filters: 0
flow_director_filter_add_errors: 160
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 37
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
----
(4) 16个ipv6-lip, 8个slave, signature mode, pballoc 128k;
lip: (2402:5ec0:1001:3010:192:21:2:[0-F]F)
fdir个数: 16(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 256
# dpip -x link show lan | grep flow_
flow_director_added_filters: 256
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 29
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
总结:
如上所示:
1》只有一个ipv6-lip,不会发生冲突。
2》多余一个ipv6-lip,感觉低4bit 不参与,只要其他的高128-4=124bit相同,则会发送冲突。其他的高124bit不同,则不发送冲突。
(1)1个 ipv4-lip, 一个 ipv6-lip, 8个slave, signature mode, pballoc 128k;;
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
# dpip -x link show lan | grep flow_
flow_director_added_filters: 32
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 43
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
------
(2)6个 ipv4-lip, 6个 ipv6-lip, 8个slave, signature mode, pballoc 128k;
ipv4-lip: 192.21.2.[15,16,47,48,79,80] (15:0F, 16:10, 47:2F, 48:30, 79:4F, 80:50)
ipv6-lip: 2402:5ec0:1001:3010::192.21.2.[15,16,47,48,79,80]
fdir个数: 12(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 192
# dpip -x link show lan | grep flow_
flow_director_added_filters: 192
flow_director_removed_filters: 0
flow_director_filter_add_errors: 0
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 49
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
思路
减少冲突
像是lip的低4位无效,只要高28位(对于ipv6-lip,高124位)不同,基本不会冲突
- 更改 ixgbe pmd 的 signature hash算法,减少冲突
ixgbe pmd signature mode fdir 代码查看:
ixgbe_flow_create-->
ixgbe_fdir_filter_program-->
atr_compute_sig_hash_82599/fdir_add_signature_filter_82599
冲突时的解决方法
即使更改 signature hash算法,也不可以完全保证不冲突。如果发生冲突,需要保证流量通,则考虑使用下列的方法:
- soft perfect mode fdir rule
硬件 signature fdir 导流到不对的 lcore,然后soft 实现的 perfect fdir 再进行一次导流到正确的 lcore。此时相当于是 DPDK RTC 模式变成 Pipeline 模式。
- 保存 soft perfect fdir
1> 软件保存全局的 各个 item 的 mask;
2> 每个 perfect fdir rule 的 各个 item & 对应的mask,通过 hash 来保存 soft perfect fdir 。soft perfect fdir 的 action为 指定的 queue/线程id/core-id; - 匹配 soft perfect fdir:
在某个线程中查找不到资源「比如:conn」,并且如果报文的dip是接口上的某个ip,且存在sapool的情况下,则从报文中提取 item,和全局的mask进行与操作;然后在 hash 表中精确查找。查找到后,得到 指定的 queue/线程id/core-id,再从一个线程重定向到另外一个线程「可通过 rte_ring 来重定向报文」。
fdir 的增删只有在程序启动的时候才会设置,后续不会有增删操作,只有查找操作。
所以: soft perfect fdir 也只有程序启动的设置,后续不会再增删,只有查找。那么启动后,只有查找操作就不需要加锁「虽然是一个全局的配置」。
这个比查找全局的 redirect_conn 表,来决定redirect core 要好「需要加锁」。
(1) 配置
2个 ipv4-lip, 8个slave, signature mode, pballoc 128k;
lip: (192.21.2.14-15, 14即0E, 15即0F)
fdir个数: 2(lip_num) * 8(slave_num/port_base) * 2(tcp+udp) = 32
冲突查看:
# dpip -x link show lan | grep flow_
flow_director_added_filters: 16
flow_director_removed_filters: 0
flow_director_filter_add_errors: 16
flow_director_filter_remove_errors: 0
flow_director_matched_filters: 0
flow_director_missed_filters: 35
tx_flow_control_xon_packets: 0
rx_flow_control_xon_packets: 0
tx_flow_control_xoff_packets: 0
rx_flow_control_xoff_packets: 0
如上所示,先添加的是 192.21.2.14 lip 的 signature fdir rule,
再添加 192.21.2.15 lip 的 signature fdir rule 时,发生了冲突;
比如 hash值发生了冲突,此时会有 flow_director_filter_add_errors 计数器增加。
(2) 打流测试
for a in `seq 1 400`; do curl 10.1.1.22; done
注:vs: tcp:10.1.1.22:80
打了400条流,其中一条流中存在10个包(in方向6个包,out方向4个包);
那么400条流,in方向就是2400个包,out方向就是1600个包。
但是看匹配效果而言,其中有 808 个out方向的包都是走的是soft fdir「比例:808/1600=50.5%」,
大概和 filter_add_errorr 占 整个fdir_rule 的比例「16/32=50%」一致。
mlx 网卡
经过测试dpvs 使用 mlx cx4-lx(mlx5 pmd) 没有该问题。
直接在该网卡上配置 rte_flow 的规则,不需要配置 fdir_mode ,应该是不关注是 perfect 还是 signature,或者认为都是 perfect mode;
下发 ipv4/ipv6 的 rte_flow 规则,打流量,都是正常的。
参考