测来测去11:DPDK i40e X710 Flow Director Deep Dive(2)

同时添加一个TCP Flow Director规则

上一篇文章的基础上,添加一个TCP相关的Fdir操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct rte_eth_fdir_filter arg_tcpport = {
.soft_id = 3,
.input = {
.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
.flow = {
.tcp4_flow = {
.dst_port = 0x10,
},
},
},
.action = {
.rx_queue = 1,
.behavior = RTE_ETH_FDIR_ACCEPT,
.report_status = RTE_ETH_FDIR_REPORT_ID,
},
};

只填写了TCP目的端口匹配4096(0x1000)的一条匹配规则。

之后按照UDP的操作方法,配置一下先仅仅将TCP目的端口加入input_set

1
2
3
4
5
6
7
8
9
10
11
12
13

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_TCP;
info.info.input_set_conf.field[0] = RTE_ETH_INPUT_SET_L4_TCP_DST_PORT;
info.info.input_set_conf.inset_size = 1;
info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;

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_tcpport);

L3fwd跑一下:

./l3fwd -c 0x1ffff -- -p 0x3 -P --config="(0,0,1),(0,1,2),(0,2,2),(1,0,3),(1,1,4),(1,2,4)"

此时仅有目的端口号为4096的TCP报文可以进入Queue1

再给input_set加入一个源端口SRC_PORT:

1
2
3
4
5
6
7
8
9
10
11
12
13
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_TCP;
info.info.input_set_conf.field[0] = RTE_ETH_INPUT_SET_L4_TCP_DST_PORT;
info.info.input_set_conf.field[1] = RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT;
info.info.input_set_conf.inset_size = 2;
info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;

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_tcpport);

因为在arg_tcpport中没有配置具体的源端口号,所以此时只有目的端口是4096,且源端口号为默认值0的TCP报文能够进入Queue1。

当然也可以加上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct rte_eth_fdir_filter arg_tcpport = {
.soft_id = 3,
.input = {
.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
.flow = {
.tcp4_flow = {
.dst_port = 0x10,
.src_port = 1234, //1234=>0x04d2=>0xd204=>53764
},
},
},
.action = {
.rx_queue = 1,
.behavior = RTE_ETH_FDIR_ACCEPT,
.report_status = RTE_ETH_FDIR_REPORT_ID,
},
};

注意虽然.src_port填写了1234,但匹配的TCP源端口号是53764,具体的推导步骤见注释。

同时配置UDP掩码和TCP掩码

到此,可以以掩码匹配UDP报文,并且精确匹配TCP报文,那么TCP的Flow Director规则是否也可以添加掩码呢?

先仿照UDP的方式给TCP的目的端口添加一个掩码:

1
2
3
4
rte_pmd_i40e_inset_get(0, 33, &inset, INSET_FDIR); //tcp
inset.mask[0].field_idx = 30;
inset.mask[0].mask = 0x0fff;
ret = rte_pmd_i40e_inset_set(0, 33, &inset, INSET_FDIR);

此时源端口为53764,目的端口为4096-8191的TCP报文都可以进入Queue1。
同时UDP的匹配规则不受影响。

单独给TCP的源端口加一个掩码:

1
2
3
4
rte_pmd_i40e_inset_get(0, 33, &inset, INSET_FDIR); //tcp
inset.mask[0].field_idx = 29;
inset.mask[0].mask = 0x0fff;
ret = rte_pmd_i40e_inset_set(0, 33, &inset, INSET_FDIR);

当然按照上一篇介绍的规则,arg_tcpport也需要相应修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct rte_eth_fdir_filter arg_tcpport = {
.soft_id = 3,
.input = {
.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_TCP,
.flow = {
.tcp4_flow = {
.dst_port = 0x10,
.src_port = 0x20,
},
},
},
.action = {
.rx_queue = 1,
.behavior = RTE_ETH_FDIR_ACCEPT,
.report_status = RTE_ETH_FDIR_REPORT_ID,
},
};

此时源端口为8192-12287,目的端口为4096的TCP报文都可以进入Queue1。且不影响UDP的匹配规则。

设置两条掩码规则

给TCP的目标目的端口增加一个掩码:

1
2
3
4
5
6
7
8
9
rte_pmd_i40e_inset_get(0, 33, &inset, INSET_FDIR); //tcp
inset.mask[0].field_idx = 29;
inset.mask[0].mask = 0x0fff;
ret = rte_pmd_i40e_inset_set(0, 33, &inset, INSET_FDIR);

rte_pmd_i40e_inset_get(0, 33, &inset, INSET_FDIR); //tcp
inset.mask[1].field_idx = 30;
inset.mask[1].mask = 0x00ff;
ret = rte_pmd_i40e_inset_set(0, 33, &inset, INSET_FDIR);

注意,为了区别UDP的掩码(0x0FFF),给TCP目的端口使用的是0x00FF

此时源端口为8192-12287,且目的端口为4096-4351(0x10FF)的TCP报文均可进入Queue1。

为了验证针对UDP报文的规则不受TCP的Mask影响,发送目的端口为4352的UDP报文,仍可匹配UDP规则。证明不同pctype之间的配置不互相影响。

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