测来测去4:82599在DPDK下使用fdir

文档过期

近期有客户反馈82599的fdir(flow director)功能在DPDK环境下不生效,本想丢一个DPDK官网上的82599 fdir测试资料过去,但幸好我仔细看了一下测试流程,发现这个官方文档里使用的testpmd命令已经过期了(时间戳:Jan 3rd, 2019)….所以…我自己写一个吧。

Setup

1
2
3
4
DPDK Version: 17.11
NIC: 82599
DUT: test-pmd
Traffic Generator: scapy

其中DUT与Traffic Generator 10G接口直连。

Test Cases

首先测试对ipv4-tcp报文的支持

perfect mode

1
2
3
4
5
6
7
./testpmd -c 1ffff -w 02:00.0 -w 02:00.1 -n 4 -- -i --nb-cores=8 --rxq=4 --txq=4 --disable-rss --pkt-filter-mode=perfect --nb-ports=1
set verbose 1
set fwd rxonly

flow_director_filter 0 mode IP add flow ipv4-tcp src 172.16.182.82 20 dst 2.2.2.3 80 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 1

start

在Traffic Generator侧构造一个匹配的报文并发送:

1
2
p1=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.182.82", dst="2.2.2.3")/TCP(sport=20, dport=80)
sendp(p1, iface="ens785f0")

应该可以看到testpmd将该报文收到了Queue 1。

signature mode

1
./testpmd -c 1ffff -w 02:00.0 -w 02:00.1 -n 4 -- -i --nb-cores=8 --rxq=4 --txq=4 --disable-rss --pkt-filter-mode=signature --nb-ports=1

除在上面的命令行中--pkt-filter-mode=signature之外与前一个测试例完全一致。

ipv4-udp的测试也基本类似,不再赘述。

测试对ipv6-tcp报文的支持

Signature mode

82599 DPDK ixgbe驱动不支持IPv6报文flow director的perfect mode,所以只能用signature mode

1
2
3
4
5
6
7
./testpmd -c 1ffff -w 02:00.0 -w 02:00.1 -n 4 -- -i --nb-cores=8 --rxq=4 --txq=4 --disable-rss --pkt-filter-mode=signature --nb-ports=1
set verbose 1
set fwd rxonly

flow_director_filter 0 mode IP add flow ipv6-tcp src fcbd:dc01:1:222:0:0:0:3 8000 dst fcbd:dc01:1:222:0:0:0:12 1029 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 1

start

在Traffic Generator侧构造一个匹配的报文并发送:

1
2
p1=Ether(src=get_if_hwaddr("ens785f0"))/IPv6(src="fcbd:dc01:1:222:0:0:0:3",dst="fcbd:dc01:1:222:0:0:0:12")/TCP(sport=8000,dport=1029)
sendp(p1, iface="ens785f0")

应该可以看到testpmd将该报文收到了Queue 1。

ipv6-udp报文的支持也基本类似。

添加Mask

问题主要在对Mask的支持上,首先用ipv4-tcp举个栗子:

如果想mask掉(通配)全部的src ip

1
2
3
4
5
6
./testpmd -c 1ffff -w 02:00.0 -w 02:00.1 -n 4 -- -i --nb-cores=8 --rxq=4 --txq=4 --disable-rss --pkt-filter-mode=signature --nb-ports=1
set verbose 1
set fwd rxonly
port stop 0
flow_director_mask 0 mode IP vlan 0x0 src_mask 0.0.0.0 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0xFFFF dst_mask 255.255.255.255 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0xFFFF
port start 0

这个配mask的命令长得令人发指,同时必须要先stop port 0。通配的方式就是src_mask后写0.0.0.0
这时如果你希望所有源端口号是20,目的IP是2.2.2.3,目的端口号是80的报文都进入Queue 1,那么flow director的命令必须写成:

1
2
flow_director_filter 0 mode IP add flow ipv4-tcp src 0.0.0.0 20 dst 2.2.2.3 80 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 1
start

一般人的理解,设置了通配mask之后,src IP写成什么都无所谓了,但这里必须要写成0.0.0.0,不然匹配不到。

Traffic Generator侧构造任意src IP的且满足其他匹配条件的报文,并发送:

1
2
3
4
5
6
7
p1=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.182.82", dst="2.2.2.3")/TCP(sport=20, dport=80)
p2=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.182.8", dst="2.2.2.3")/TCP(sport=20, dport=80)
p3=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.18.82", dst="2.2.2.3")/TCP(sport=20, dport=80)

sendp(p1, iface="ens785f0")
sendp(p2, iface="ens785f0")
sendp(p3, iface="ens785f0")

可以在testpmd中看到三个报文均进入了Queue 1。

如果想mask掉(通配)全部的src ipscr port

与上一个类似,设置mask和fdir规则的命令分别为:

1
2
3
flow_director_mask 0 mode IP vlan 0x0 src_mask 0.0.0.0 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0x0 dst_mask 255.255.255.255 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0xFFFF

flow_director_filter 0 mode IP add flow ipv4-tcp src 0.0.0.0 0 dst 2.2.2.3 80 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 1

与之前一样,fdir规则中,src后面必须写0.0.0.0 0才能达到预期效果。

此时仅由目的IP和目的端口号决定报文的去向。

1
2
3
4
5
6
7
p1=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.182.82", dst="2.2.2.3")/TCP(sport=19, dport=80)
p2=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.182.8", dst="2.2.2.3")/TCP(sport=2, dport=80)
p3=Ether(src=get_if_hwaddr("ens785f0"))/IP(src="172.16.18.82", dst="2.2.2.3")/TCP(sport=21, dport=80)

sendp(p1, iface="ens785f0")
sendp(p2, iface="ens785f0")
sendp(p3, iface="ens785f0")

可以在testpmd中看到三个报文均进入了Queue 1。

IPv6的情况

如果想mask掉IPv6报文的src ip

1
2
3
port stop 0
flow_director_mask 0 mode IP vlan 0x0 src_mask 0.0.0.0 0:0:0:0:0:0:0:0 0x0 dst_mask 255.255.255.255 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0xFFFF
port start 0

同理,fdir规则中:

1
flow_director_filter 0 mode IP add flow ipv6-tcp src 0:0:0:0:0:0:0:0 0 dst fcbd:dc01:1:222:0:0:0:12 1029 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 1

ipv6-tcp src后必须写0:0:0:0:0:0:0:0 0以配合mask的设置。

关键就是如果mask中某字段中某bit为0,那么fdir规则中该字段对应的bit位也必须为0,82599网卡才能按预期的方式工作。

再举一个栗子,如果想将dst port的mask设置为0x00F0,对应的mask和fdir规则为:

1
2
3
flow_director_mask 0 mode IP vlan 0x0 src_mask 0.0.0.0 0:0:0:0:0:0:0:0 0x0 dst_mask 255.255.255.255 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 0x00F0

flow_director_filter 0 mode IP add flow ipv6-tcp src 0:0:0:0:0:0:0:0 0 dst fcbd:dc01:1:222:0:0:0:12 240 tos 0 ttl 0 vlan 0x0 flexbytes () fwd pf queue 1 fd_id 2

此时再发送目的端口号为240或241…的IPv6报文都可以匹配该fdir规则。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero