From 92378c2b7fdf45f378783e2ba8b298bef797e6a9 Mon Sep 17 00:00:00 2001 From: Moti Haimovsky Date: Thu, 11 Oct 2018 10:48:39 +0000 Subject: [PATCH] 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 --- drivers/net/mlx5/Makefile | 10 ++++++++++ drivers/net/mlx5/meson.build | 4 ++++ drivers/net/mlx5/mlx5_flow.c | 6 +++++- drivers/net/mlx5/mlx5_flow.h | 1 + drivers/net/mlx5/mlx5_flow_dv.c | 7 +++++-- drivers/net/mlx5/mlx5_flow_tcf.c | 26 ++++++++++++++++++++++++-- drivers/net/mlx5/mlx5_flow_verbs.c | 7 +++++-- 7 files changed, 54 insertions(+), 7 deletions(-) diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index ca1de9f210..9097456817 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -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 \ diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index fd93ac1625..f562f30d71 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -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', diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 6b2698a745..bd70fce248 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -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; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index fee05f0e38..47ab173379 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -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, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index c9aa50f405..a013201eab 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -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 : diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 91f6ef6786..84e5393668 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -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, diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index ad8f7aca6b..65c849ce0f 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -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 : -- 2.20.1