net/mlx5: support e-switch TCP-flags flow filter

This patch adds support for offloading flow rules with TCP-flags
filter to mlx5 eswitch Hardwrae.

With mlx5 it is possible to offload a limited set of flow rules to
the mlxsw (or e-switch) using the DPDK flow commands using the
"transfer" attribute. This set of flow rules also supports filtering
according to the values found in the TCP flags.
This patch implements this offload capability in the mlx5 PMD under
transfer attribute.

Signed-off-by: Moti Haimovsky <motih@mellanox.com>
This commit is contained in:
Moti Haimovsky 2018-10-11 10:48:39 +00:00 committed by Ferruh Yigit
parent 3e9fa07908
commit 92378c2b7f
7 changed files with 54 additions and 7 deletions

View File

@ -341,6 +341,16 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
linux/pkt_cls.h \
enum TCA_FLOWER_KEY_VLAN_ETH_TYPE \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
HAVE_TCA_FLOWER_KEY_TCP_FLAGS \
linux/pkt_cls.h \
enum TCA_FLOWER_KEY_TCP_FLAGS \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
HAVE_TCA_FLOWER_KEY_TCP_FLAGS_MASK \
linux/pkt_cls.h \
enum TCA_FLOWER_KEY_TCP_FLAGS_MASK \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
HAVE_TC_ACT_VLAN \
linux/tc_act/tc_vlan.h \

View File

@ -180,6 +180,10 @@ if build
'TCA_FLOWER_KEY_VLAN_PRIO' ],
[ 'HAVE_TCA_FLOWER_KEY_VLAN_ETH_TYPE', 'linux/pkt_cls.h',
'TCA_FLOWER_KEY_VLAN_ETH_TYPE' ],
[ 'HAVE_TCA_FLOWER_KEY_TCP_FLAGS', 'linux/pkt_cls.h',
'TCA_FLOWER_KEY_TCP_FLAGS' ],
[ 'HAVE_TCA_FLOWER_KEY_TCP_FLAGS_MASK', 'linux/pkt_cls.h',
'TCA_FLOWER_KEY_TCP_FLAGS_MASK' ],
[ 'HAVE_TC_ACT_VLAN', 'linux/tc_act/tc_vlan.h',
'TCA_VLAN_PUSH_VLAN_PRIORITY' ],
[ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h',

View File

@ -1223,6 +1223,8 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
* Bit-fields that holds the items detected until now.
* @param[in] target_protocol
* The next protocol in the previous item.
* @param[in] flow_mask
* mlx5 flow-specific (TCF, DV, verbs, etc.) supported header fields mask.
* @param[out] error
* Pointer to error structure.
*
@ -1284,12 +1286,14 @@ int
mlx5_flow_validate_item_tcp(const struct rte_flow_item *item,
uint64_t item_flags,
uint8_t target_protocol,
const struct rte_flow_item_tcp *flow_mask,
struct rte_flow_error *error)
{
const struct rte_flow_item_tcp *mask = item->mask;
const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
int ret;
assert(flow_mask);
if (target_protocol != 0xff && target_protocol != IPPROTO_TCP)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, item,
@ -1309,7 +1313,7 @@ mlx5_flow_validate_item_tcp(const struct rte_flow_item *item,
mask = &rte_flow_item_tcp_mask;
ret = mlx5_flow_item_acceptable
(item, (const uint8_t *)mask,
(const uint8_t *)&rte_flow_item_tcp_mask,
(const uint8_t *)flow_mask,
sizeof(struct rte_flow_item_tcp), error);
if (ret < 0)
return ret;

View File

@ -320,6 +320,7 @@ int mlx5_flow_validate_item_mpls(const struct rte_flow_item *item,
int mlx5_flow_validate_item_tcp(const struct rte_flow_item *item,
uint64_t item_flags,
uint8_t target_protocol,
const struct rte_flow_item_tcp *flow_mask,
struct rte_flow_error *error);
int mlx5_flow_validate_item_udp(const struct rte_flow_item *item,
uint64_t item_flags,

View File

@ -174,8 +174,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
MLX5_FLOW_LAYER_OUTER_L4_UDP;
break;
case RTE_FLOW_ITEM_TYPE_TCP:
ret = mlx5_flow_validate_item_tcp(items, item_flags,
next_protocol, error);
ret = mlx5_flow_validate_item_tcp
(items, item_flags,
next_protocol,
&rte_flow_item_tcp_mask,
error);
if (ret < 0)
return ret;
item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :

View File

@ -148,6 +148,12 @@ struct tc_vlan {
#ifndef HAVE_TCA_FLOWER_KEY_VLAN_ETH_TYPE
#define TCA_FLOWER_KEY_VLAN_ETH_TYPE 25
#endif
#ifndef HAVE_TCA_FLOWER_KEY_TCP_FLAGS
#define TCA_FLOWER_KEY_TCP_FLAGS 71
#endif
#ifndef HAVE_TCA_FLOWER_KEY_TCP_FLAGS_MASK
#define TCA_FLOWER_KEY_TCP_FLAGS_MASK 72
#endif
#ifndef IPV6_ADDR_LEN
#define IPV6_ADDR_LEN 16
@ -204,6 +210,7 @@ static const struct {
.tcp.hdr = {
.src_port = RTE_BE16(0xffff),
.dst_port = RTE_BE16(0xffff),
.tcp_flags = 0xff,
},
.udp.hdr = {
.src_port = RTE_BE16(0xffff),
@ -626,8 +633,11 @@ flow_tcf_validate(struct rte_eth_dev *dev,
return -rte_errno;
break;
case RTE_FLOW_ITEM_TYPE_TCP:
ret = mlx5_flow_validate_item_tcp(items, item_flags,
next_protocol, error);
ret = mlx5_flow_validate_item_tcp
(items, item_flags,
next_protocol,
&flow_tcf_mask_supported.tcp,
error);
if (ret < 0)
return ret;
item_flags |= MLX5_FLOW_LAYER_OUTER_L4_TCP;
@ -1289,6 +1299,18 @@ flow_tcf_translate(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow,
TCA_FLOWER_KEY_TCP_DST_MASK,
mask.tcp->hdr.dst_port);
}
if (mask.tcp->hdr.tcp_flags) {
mnl_attr_put_u16
(nlh,
TCA_FLOWER_KEY_TCP_FLAGS,
rte_cpu_to_be_16
(spec.tcp->hdr.tcp_flags));
mnl_attr_put_u16
(nlh,
TCA_FLOWER_KEY_TCP_FLAGS_MASK,
rte_cpu_to_be_16
(mask.tcp->hdr.tcp_flags));
}
break;
default:
return rte_flow_error_set(error, ENOTSUP,

View File

@ -1056,8 +1056,11 @@ flow_verbs_validate(struct rte_eth_dev *dev,
MLX5_FLOW_LAYER_OUTER_L4_UDP;
break;
case RTE_FLOW_ITEM_TYPE_TCP:
ret = mlx5_flow_validate_item_tcp(items, item_flags,
next_protocol, error);
ret = mlx5_flow_validate_item_tcp
(items, item_flags,
next_protocol,
&rte_flow_item_tcp_mask,
error);
if (ret < 0)
return ret;
item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :