DPVS 82599 soft ipv6 fdir perfect mode 实现

背景

fdir mode

fdir mode 分为 perfect mode, 和 signature mode。
perfect mode :完美匹配,即精确匹配。
signature mode: fuzzy match,模糊匹配。

  • perfect mode fdir

我的理解:

  • 网卡存储的规则:
    下发 fdir rule,存储的是 全局的 各个item 的 mask,以及 每个 fdir 的 多个 item 的 value & mask 之后的值。
  • 规则匹配:
    数据包匹配时,从包中提取指定字段,然后和全局的mask 进行掩码操作;再逐个 item进行比较查找,直到所有 item 都匹配的 flow rule,即为查找到。
  • signature mode fdir

我的理解:

  • 网卡存储的规则:
    下发 fdir rule,存储的是 全局的 各个item 的 mask,基于 每个 fdir 的 多个 item 的 value & mask 之后的值 进行 计算 hash value,存储 hash vlaue。 这样可以节省硬件的内存空间,因为 ipv6 地址占用16个字节,只存储 hash value 占用内存小。
  • 规则匹配:
    数据包匹配时,从包中提取指定字段,然后和全局的mask 进行掩码操作,然后hash 得到hash_value;再基于 hash_valued 匹配某个 fdir规则。
  • dpdk 中 ixgbe 的 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 的冲突测试

  • ipv4 signature
查看:
dpip -x link show lan | grep flow_
注:dpip -x link show 底层调用的是:rte_eth_xstats_get

(11个 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

 ----21个 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

 -----32个 ipv4-lip,8个slave, signature mode, pballoc 128k;
 (lip: 192.21.2.14-15, 140E, 150F)
 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, 150F, 1610)
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。

在这里插入图片描述

  • ipv6 signature
12个 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
    
----22个 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
 
 ----312个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不同,则不发送冲突。
  • ipv4 + ipv6 signature
11个 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
    
  ------26个 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 不要连续,间隔16
像是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 的实现
  • 保存 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, 140E, 150F)
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 规则,打流量,都是正常的。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值