net/mlx5: fix default context in flow age action
[dpdk.git] / drivers / net / mlx5 / mlx5_flow.c
index 528ce3e..8d4b4a8 100644 (file)
@@ -50,6 +50,7 @@ flow_tunnel_add_default_miss(struct rte_eth_dev *dev,
                             const struct rte_flow_attr *attr,
                             const struct rte_flow_action *app_actions,
                             uint32_t flow_idx,
+                            const struct mlx5_flow_tunnel *tunnel,
                             struct tunnel_default_miss_ctx *ctx,
                             struct rte_flow_error *error);
 static struct mlx5_flow_tunnel *
@@ -99,6 +100,8 @@ struct mlx5_flow_expand_node {
         * RSS types bit-field associated with this node
         * (see ETH_RSS_* definitions).
         */
+       uint8_t optional;
+       /**< optional expand field. Default 0 to expand, 1 not go deeper. */
 };
 
 /** Object returned by mlx5_flow_expand_rss(). */
@@ -212,7 +215,7 @@ mlx5_flow_expand_rss_item_complete(const struct rte_flow_item *item)
        return ret;
 }
 
-#define MLX5_RSS_EXP_ELT_N 8
+#define MLX5_RSS_EXP_ELT_N 16
 
 /**
  * Expand RSS flows into several possible flows according to the RSS hash
@@ -366,7 +369,7 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
                        }
                }
                /* Go deeper. */
-               if (node->next) {
+               if (!node->optional && node->next) {
                        next_node = node->next;
                        if (stack_pos++ == MLX5_RSS_EXP_ELT_N) {
                                rte_errno = E2BIG;
@@ -405,6 +408,8 @@ enum mlx5_expansion {
        MLX5_EXPANSION_VXLAN,
        MLX5_EXPANSION_VXLAN_GPE,
        MLX5_EXPANSION_GRE,
+       MLX5_EXPANSION_NVGRE,
+       MLX5_EXPANSION_GRE_KEY,
        MLX5_EXPANSION_MPLS,
        MLX5_EXPANSION_ETH,
        MLX5_EXPANSION_ETH_VLAN,
@@ -462,6 +467,7 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
                        (MLX5_EXPANSION_OUTER_IPV4_UDP,
                         MLX5_EXPANSION_OUTER_IPV4_TCP,
                         MLX5_EXPANSION_GRE,
+                        MLX5_EXPANSION_NVGRE,
                         MLX5_EXPANSION_IPV4,
                         MLX5_EXPANSION_IPV6),
                .type = RTE_FLOW_ITEM_TYPE_IPV4,
@@ -484,7 +490,8 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
                         MLX5_EXPANSION_OUTER_IPV6_TCP,
                         MLX5_EXPANSION_IPV4,
                         MLX5_EXPANSION_IPV6,
-                        MLX5_EXPANSION_GRE),
+                        MLX5_EXPANSION_GRE,
+                        MLX5_EXPANSION_NVGRE),
                .type = RTE_FLOW_ITEM_TYPE_IPV6,
                .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
                        ETH_RSS_NONFRAG_IPV6_OTHER,
@@ -513,9 +520,20 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
        },
        [MLX5_EXPANSION_GRE] = {
                .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
-                                                 MLX5_EXPANSION_IPV6),
+                                                 MLX5_EXPANSION_IPV6,
+                                                 MLX5_EXPANSION_GRE_KEY),
                .type = RTE_FLOW_ITEM_TYPE_GRE,
        },
+       [MLX5_EXPANSION_GRE_KEY] = {
+               .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
+                                                 MLX5_EXPANSION_IPV6),
+               .type = RTE_FLOW_ITEM_TYPE_GRE_KEY,
+               .optional = 1,
+       },
+       [MLX5_EXPANSION_NVGRE] = {
+               .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH),
+               .type = RTE_FLOW_ITEM_TYPE_NVGRE,
+       },
        [MLX5_EXPANSION_MPLS] = {
                .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
                                                  MLX5_EXPANSION_IPV6),
@@ -1687,6 +1705,37 @@ mlx5_flow_validate_action_count(struct rte_eth_dev *dev __rte_unused,
        return 0;
 }
 
+/*
+ * Validate the ASO CT action.
+ *
+ * @param[in] dev
+ *   Pointer to the Ethernet device structure.
+ * @param[in] conntrack
+ *   Pointer to the CT action profile.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_validate_action_ct(struct rte_eth_dev *dev,
+                       const struct rte_flow_action_conntrack *conntrack,
+                       struct rte_flow_error *error)
+{
+       RTE_SET_USED(dev);
+
+       if (conntrack->state > RTE_FLOW_CONNTRACK_STATE_TIME_WAIT)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                         "Invalid CT state");
+       if (conntrack->last_index > RTE_FLOW_CONNTRACK_FLAG_RST)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                         "Invalid last TCP packet flag");
+       return 0;
+}
+
 /**
  * Verify the @p attributes will be correctly understood by the NIC and store
  * them in the @p flow if everything is correct.
@@ -5094,6 +5143,7 @@ flow_check_match_action(const struct rte_flow_action actions[],
                case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
                case RTE_FLOW_ACTION_TYPE_RAW_DECAP:
                case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD:
+               case RTE_FLOW_ACTION_TYPE_METER:
                        if (fdb_mirror)
                                *modify_after_mirror = 1;
                        break;
@@ -5927,22 +5977,14 @@ flow_create_split_outer(struct rte_eth_dev *dev,
        return ret;
 }
 
-static struct mlx5_flow_tunnel *
-flow_tunnel_from_rule(struct rte_eth_dev *dev,
-                     const struct rte_flow_attr *attr,
-                     const struct rte_flow_item items[],
-                     const struct rte_flow_action actions[])
+static inline struct mlx5_flow_tunnel *
+flow_tunnel_from_rule(const struct mlx5_flow *flow)
 {
        struct mlx5_flow_tunnel *tunnel;
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wcast-qual"
-       if (is_flow_tunnel_match_rule(dev, attr, items, actions))
-               tunnel = (struct mlx5_flow_tunnel *)items[0].spec;
-       else if (is_flow_tunnel_steer_rule(dev, attr, items, actions))
-               tunnel = (struct mlx5_flow_tunnel *)actions[0].conf;
-       else
-               tunnel = NULL;
+       tunnel = (typeof(tunnel))flow->tunnel;
 #pragma GCC diagnostic pop
 
        return tunnel;
@@ -6137,12 +6179,11 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
                                              error);
                if (ret < 0)
                        goto error;
-               if (is_flow_tunnel_steer_rule(dev, attr,
-                                             buf->entry[i].pattern,
-                                             p_actions_rx)) {
+               if (is_flow_tunnel_steer_rule(wks->flows[0].tof_type)) {
                        ret = flow_tunnel_add_default_miss(dev, flow, attr,
                                                           p_actions_rx,
                                                           idx,
+                                                          wks->flows[0].tunnel,
                                                           &default_miss_ctx,
                                                           error);
                        if (ret < 0) {
@@ -6206,7 +6247,7 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
        }
        flow_rxq_flags_set(dev, flow);
        rte_free(translated_actions);
-       tunnel = flow_tunnel_from_rule(dev, attr, items, actions);
+       tunnel = flow_tunnel_from_rule(wks->flows);
        if (tunnel) {
                flow->tunnel = 1;
                flow->tunnel_id = tunnel->tunnel_id;
@@ -7347,14 +7388,11 @@ mlx5_flow_create_counter_stat_mem_mng(struct mlx5_dev_ctx_shared *sh)
                mlx5_free(mem);
                return -rte_errno;
        }
+       memset(&mkey_attr, 0, sizeof(mkey_attr));
        mkey_attr.addr = (uintptr_t)mem;
        mkey_attr.size = size;
        mkey_attr.umem_id = mlx5_os_get_umem_id(mem_mng->umem);
        mkey_attr.pd = sh->pdn;
-       mkey_attr.log_entity_size = 0;
-       mkey_attr.pg_access = 0;
-       mkey_attr.klm_array = NULL;
-       mkey_attr.klm_num = 0;
        mkey_attr.relaxed_ordering_write = sh->cmng.relaxed_ordering_write;
        mkey_attr.relaxed_ordering_read = sh->cmng.relaxed_ordering_read;
        mem_mng->dm = mlx5_devx_cmd_mkey_create(sh->ctx, &mkey_attr);
@@ -8121,6 +8159,28 @@ int rte_pmd_mlx5_sync_flow(uint16_t port_id, uint32_t domains)
        return ret;
 }
 
+const struct mlx5_flow_tunnel *
+mlx5_get_tof(const struct rte_flow_item *item,
+            const struct rte_flow_action *action,
+            enum mlx5_tof_rule_type *rule_type)
+{
+       for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
+               if (item->type == (typeof(item->type))
+                                 MLX5_RTE_FLOW_ITEM_TYPE_TUNNEL) {
+                       *rule_type = MLX5_TUNNEL_OFFLOAD_MATCH_RULE;
+                       return flow_items_to_tunnel(item);
+               }
+       }
+       for (; action->conf != RTE_FLOW_ACTION_TYPE_END; action++) {
+               if (action->type == (typeof(action->type))
+                                   MLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET) {
+                       *rule_type = MLX5_TUNNEL_OFFLOAD_SET_RULE;
+                       return flow_actions_to_tunnel(action);
+               }
+       }
+       return NULL;
+}
+
 /**
  * tunnel offload functionalilty is defined for DV environment only
  */
@@ -8151,13 +8211,13 @@ flow_tunnel_add_default_miss(struct rte_eth_dev *dev,
                             const struct rte_flow_attr *attr,
                             const struct rte_flow_action *app_actions,
                             uint32_t flow_idx,
+                            const struct mlx5_flow_tunnel *tunnel,
                             struct tunnel_default_miss_ctx *ctx,
                             struct rte_flow_error *error)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow *dev_flow;
        struct rte_flow_attr miss_attr = *attr;
-       const struct mlx5_flow_tunnel *tunnel = app_actions[0].conf;
        const struct rte_flow_item miss_items[2] = {
                {
                        .type = RTE_FLOW_ITEM_TYPE_ETH,
@@ -8243,6 +8303,7 @@ flow_tunnel_add_default_miss(struct rte_eth_dev *dev,
        dev_flow->flow = flow;
        dev_flow->external = true;
        dev_flow->tunnel = tunnel;
+       dev_flow->tof_type = MLX5_TUNNEL_OFFLOAD_MISS_RULE;
        /* Subflow object was created, we must include one in the list. */
        SILIST_INSERT(&flow->dev_handles, dev_flow->handle_idx,
                      dev_flow->handle, next);
@@ -8856,6 +8917,7 @@ flow_tunnel_add_default_miss(__rte_unused struct rte_eth_dev *dev,
                             __rte_unused const struct rte_flow_attr *attr,
                             __rte_unused const struct rte_flow_action *actions,
                             __rte_unused uint32_t flow_idx,
+                            __rte_unused const struct mlx5_flow_tunnel *tunnel,
                             __rte_unused struct tunnel_default_miss_ctx *ctx,
                             __rte_unused struct rte_flow_error *error)
 {