测来测去9:DPDK i40e XXV710 Flow Director Mask Configuration

Flow Director

最常见的Flow Director使用方式就是将匹配某个五元组的报文送到一个特定的队列里去。但精确匹配有时候并不能满足全部需求,需要给一些特定的字段加Mask。

配置方式

修改dpdk-18.05.1/example/l3fwd/main.c

目的是给UDP的DST Port添加一个0XF000的掩码。

首先用i40e提供的私有接口加持一下:

1
#include <rte_pmd_i40e.h>

这里面都是偷偷夹带的私货,可以关注一下。

然后加一个”中规中矩“的FDIR规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
.ignore_offload_bitfield = 1,
.offloads = (DEV_RX_OFFLOAD_CRC_STRIP |
DEV_RX_OFFLOAD_CHECKSUM),
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
.rss_hf = ETH_RSS_IP,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
.fdir_conf = { //jma fdir
.mode = RTE_FDIR_MODE_PERFECT,
.pballoc = RTE_FDIR_PBALLOC_64K,
.status = RTE_FDIR_REPORT_STATUS,
.drop_queue = 127,
.mask = {
.vlan_tci_mask = 0,
.ipv4_mask = {
.src_ip = 0xffffffff,
.dst_ip = 0xffffffff,
},
.src_port_mask = 0xffff,
//ori .dst_port_mask = 0xffff,
.dst_port_mask = 0xff00,
},
},

};

不过其实mask不起作用,这里主要做一下错误示范。然后在main函数里加一下配置代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct rte_eth_fdir_filter_info info;
struct rte_pmd_i40e_inset inset;

memset(&info, 0, sizeof(info));
info.info_type = RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT;
info.info.input_set_conf.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_UDP;
info.info.input_set_conf.field[0] = RTE_ETH_INPUT_SET_L4_UDP_DST_PORT;
info.info.input_set_conf.inset_size = 1;
info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;

struct rte_eth_fdir_filter arg_udpport = {
.soft_id = 1,
.input = {
.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_UDP,
.flow = {
.udp4_flow = {
.dst_port = 0x2e06, //5678=>0x162e
},
},
},
.action = {
.rx_queue = 2,
.behavior = RTE_ETH_FDIR_ACCEPT,
.report_status = RTE_ETH_FDIR_REPORT_ID,
},
};

这里定义了一个Flow Director规则:”目的端口为5678的UDP报文进入队列2”。

那么如何加掩码呢?

在启动转发程序(rte_eal_mp_remote_launch())之前加上:

1
2
3
4
5
6
7
8
ret = rte_eth_dev_filter_ctrl(0,
RTE_ETH_FILTER_FDIR,RTE_ETH_FILTER_SET,&info);
ret = rte_eth_dev_filter_ctrl(0,
RTE_ETH_FILTER_FDIR,RTE_ETH_FILTER_ADD, &arg_udpport);
rte_pmd_i40e_inset_get(0, 31,&inset, INSET_FDIR); //udp
inset.mask[0].field_idx = 30;
inset.mask[0].mask = 0xf000;
ret = rte_pmd_i40e_inset_set(0, 31,&inset, INSET_FDIR);

这里面需要关注几个数值,一个是rte_pmd_i40e_inset_get/set参数里的31。这个是pctype的编号。可以查看x710 datasheet的Table 7-5。31号对应的是NonF IPv4, UDP,正好是我们需要的。

另外一个是inset.mask[0].field_idx给出的30。这个30出自datasheet中的Table 7-12。其中提到29:32这两个word在UDP协议下代表的是First 8 bytes of the UDP header。在UDP header中,前两个Byte是SRC port,对应29;第三第四个Byte是DST port,对应30。这就是30的来历。

至此就完成了最初的目的。

Future Work

X710在这方面的配置方法总体来说还是非常隐晦的。在未来还有很多可以验证的工作,比如是否可以针对不同的pctype设置不同的mask,比如mask是否仅限于两个字段等等。

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