net/mlx5: support e-switch TCP-flags flow filter
authorMoti Haimovsky <motih@mellanox.com>
Thu, 11 Oct 2018 10:48:39 +0000 (10:48 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 11 Oct 2018 16:56:02 +0000 (18:56 +0200)
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>
drivers/net/mlx5/Makefile
drivers/net/mlx5/meson.build
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_flow_tcf.c
drivers/net/mlx5/mlx5_flow_verbs.c

index ca1de9f..9097456 100644 (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 \
index fd93ac1..f562f30 100644 (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',
index 6b2698a..bd70fce 100644 (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;
index fee05f0..47ab173 100644 (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,
index c9aa50f..a013201 100644 (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 :
index 91f6ef6..84e5393 100644 (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,
index ad8f7ac..65c849c 100644 (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 :