From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id AB358A04AB; Wed, 6 Nov 2019 16:14:18 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CD6311C2EE; Wed, 6 Nov 2019 16:12:26 +0100 (CET) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 22D781C1C9 for ; Wed, 6 Nov 2019 16:12:01 +0100 (CET) From: Suanming Mou To: Matan Azrad , Shahaf Shuler , Viacheslav Ovsiienko Cc: dev@dpdk.org Date: Wed, 6 Nov 2019 17:11:25 +0200 Message-Id: <1573053090-179521-17-git-send-email-suanmingm@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1573053090-179521-1-git-send-email-suanmingm@mellanox.com> References: <1573053090-179521-1-git-send-email-suanmingm@mellanox.com> Subject: [dpdk-dev] [PATCH 16/19] net/mlx5: support meter flow action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add meter flow action support in flow validate and translate. Signed-off-by: Suanming Mou --- drivers/net/mlx5/mlx5_flow_dv.c | 95 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index ded492d..b553787 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3244,6 +3244,10 @@ struct field_modify_info modify_tcp[] = { RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have 2 fate actions in" " same flow"); + if (action_flags & MLX5_FLOW_ACTION_METER) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "jump with meter not support"); if (!action->conf) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF, @@ -3357,6 +3361,63 @@ struct field_modify_info modify_tcp[] = { return mlx5_flow_ext_mreg_supported(dev) ? MLX5_MODIFY_NUM : MLX5_MODIFY_NUM_NO_MREG; } + +/** + * Validate the meter action. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] action_flags + * Bit-fields that holds the actions detected until now. + * @param[in] action + * Pointer to the meter action. + * @param[in] attr + * Attributes of flow that includes this action. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +mlx5_flow_validate_action_meter(struct rte_eth_dev *dev, + uint64_t action_flags, + const struct rte_flow_action *action, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + const struct rte_flow_action_meter *am = action->conf; + struct mlx5_flow_meter *fm = mlx5_flow_meter_find(priv, am->mtr_id); + + if (action_flags & MLX5_FLOW_ACTION_METER) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "meter chaining not support"); + if (action_flags & MLX5_FLOW_ACTION_JUMP) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "meter with jump not support"); + if (!priv->mtr_en) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "meter action not supported"); + if (!fm) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "Meter not found"); + if (fm->ref_cnt && (!(fm->attr.transfer == attr->transfer || + (!fm->attr.ingress && !attr->ingress && attr->egress) || + (!fm->attr.egress && !attr->egress && attr->ingress)))) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "Flow attributes are either invalid " + "or have a conflict with current " + "meter attributes"); + return 0; +} + /** * Find existing modify-header resource or create and register a new one. * @@ -4703,6 +4764,16 @@ struct field_modify_info modify_tcp[] = { case MLX5_RTE_FLOW_ACTION_TYPE_MARK: case MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG: break; + case RTE_FLOW_ACTION_TYPE_METER: + ret = mlx5_flow_validate_action_meter(dev, + action_flags, + actions, attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_METER; + ++actions_n; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -6478,6 +6549,7 @@ struct field_modify_info modify_tcp[] = { const struct rte_flow_action_count *count = action->conf; const uint8_t *rss_key; const struct rte_flow_action_jump *jump_data; + const struct rte_flow_action_meter *mtr; struct mlx5_flow_dv_jump_tbl_resource jump_tbl_resource; struct mlx5_flow_tbl_resource *tbl; uint32_t port_id = 0; @@ -6844,6 +6916,25 @@ struct field_modify_info modify_tcp[] = { return -rte_errno; action_flags |= MLX5_FLOW_ACTION_SET_TAG; break; + case RTE_FLOW_ACTION_TYPE_METER: + mtr = actions->conf; + if (!flow->meter) { + flow->meter = mlx5_flow_meter_attach(priv, + mtr->mtr_id, attr, + error); + if (!flow->meter) + return rte_flow_error_set(error, + rte_errno, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "meter not found " + "or invalid parameters"); + } + /* Set the meter action. */ + dev_flow->dv.actions[actions_n++] = + flow->meter->mfts->meter_action; + action_flags |= MLX5_FLOW_ACTION_METER; + break; case RTE_FLOW_ACTION_TYPE_END: actions_end = true; if (mhdr_res.actions_num) { @@ -7445,6 +7536,10 @@ struct field_modify_info modify_tcp[] = { flow_dv_counter_release(dev, flow->counter); flow->counter = NULL; } + if (flow->meter) { + mlx5_flow_meter_detach(flow->meter); + flow->meter = NULL; + } while (!LIST_EMPTY(&flow->dev_flows)) { dev_flow = LIST_FIRST(&flow->dev_flows); LIST_REMOVE(dev_flow, next); -- 1.8.3.1