From patchwork Wed Dec 21 10:01:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?N=C3=A9lio_Laranjeiro?= X-Patchwork-Id: 18351 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 925A910BF8; Wed, 21 Dec 2016 11:01:43 +0100 (CET) Received: from mail-wm0-f45.google.com (mail-wm0-f45.google.com [74.125.82.45]) by dpdk.org (Postfix) with ESMTP id E1FF010BEE for ; Wed, 21 Dec 2016 11:01:36 +0100 (CET) Received: by mail-wm0-f45.google.com with SMTP id u144so39781148wmu.1 for ; Wed, 21 Dec 2016 02:01:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=91wCuihXm3Cpu4X/u0dk69/Himg0/d6egnF+FEdS+MY=; b=lSfKkuVhyus78zHGLXQmJ59MxDqtm5QlcwOL+H3F+iHMIBORBWlTrFJY3A0t8ltqfN hTGfbK72gHs00g9xsKBQvC11RRS6EZa5wyXka9tHxZmyt/yFnw8ZSrYponYmopx9ew34 e5/HfJgNiLWeKWWnwQf/keT1KebveYc7VkvGb0RGk5yXWwjJsfdcb1b1YCOuWCteYSru 3T/pTityePEln0saO2Ko2O3oN8Ycc0h3LghRa4RSTE6K8k78ycxFCUYwRkt1wi8Qc+jN 2qXqT8BedoWaMUb1ATr4kD4ZXm2O9sDz5EcivwIhMTDmIaufAvYo4n2C9QSRE9PHv5OS Y0Ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=91wCuihXm3Cpu4X/u0dk69/Himg0/d6egnF+FEdS+MY=; b=p+3cw02yKEla6/JRC2a4L7klJm6tR65Q4rnlQZ3H4tmmjxKnbrFWX/caYL/IRm6EXp xP4iaZwDxAxftGjqR7f9oo7Uwk680LjBLIQMzcB6jS1cktHhab8T6I+p4s8n5PSUgh// 1jEzt/1H0od0Qew60vHMkTMvjEOfxW1yq56d06VovpaJontzQA0lLEnoXqpYlW4oHkEn 4AJWQ3Y8hMlohgybM1F+nS56ubNyvN2Yj0el8H6b4tI4H3sptPx6Sm/cuk8CSwKjlRVk 18lVMU7yd82klHuy85RZACqQ3BwFo2z3s0Hp4zRgsWm5y9LjJ1v16uwo0OPnHbrM8kco /pWA== X-Gm-Message-State: AIkVDXIomObd5mQjT0iQgrXW0WV6vY2PYP0X3fnFGWZE8AD36tT6nmZXiUF1dGj/P85sXtIw X-Received: by 10.28.218.129 with SMTP id r123mr5769060wmg.137.1482314496329; Wed, 21 Dec 2016 02:01:36 -0800 (PST) Received: from ping.vm.6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by smtp.gmail.com with ESMTPSA id up5sm29615714wjc.12.2016.12.21.02.01.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Dec 2016 02:01:35 -0800 (PST) From: Nelio Laranjeiro To: dev@dpdk.org Cc: Adrien Mazarguil Date: Wed, 21 Dec 2016 11:01:12 +0100 Message-Id: <7a1cba99e80ec1a1ce429856dd91987f7e9b68fb.1482314020.git.nelio.laranjeiro@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v2 2/4] net/mlx5: add software support for rte_flow 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" Introduce initial software validation for rte_flow rules. Signed-off-by: Nelio Laranjeiro --- drivers/net/mlx5/mlx5.h | 2 + drivers/net/mlx5/mlx5_flow.c | 202 ++++++++++++++++++++++++++++++++++------ drivers/net/mlx5/mlx5_trigger.c | 2 + 3 files changed, 177 insertions(+), 29 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 04f4eaa..ac995a0 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -136,6 +136,7 @@ struct priv { unsigned int reta_idx_n; /* RETA index size. */ struct fdir_filter_list *fdir_filter_list; /* Flow director rules. */ struct fdir_queue *fdir_drop_queue; /* Flow director drop queue. */ + LIST_HEAD(mlx5_flows, rte_flow) flows; /* RTE Flow rules. */ uint32_t link_speed_capa; /* Link speed capabilities. */ rte_spinlock_t lock; /* Lock for control functions. */ }; @@ -283,5 +284,6 @@ struct rte_flow *mlx5_flow_create(struct rte_eth_dev *, int mlx5_flow_destroy(struct rte_eth_dev *, struct rte_flow *, struct rte_flow_error *); int mlx5_flow_flush(struct rte_eth_dev *, struct rte_flow_error *); +void priv_flow_flush(struct priv *); #endif /* RTE_PMD_MLX5_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index a514dff..3e5098a 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -30,11 +30,119 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include #include #include +#include + #include "mlx5.h" +struct rte_flow { + LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure. */ +}; + +/** + * Validate a flow supported by the NIC. + * + * @param priv + * Pointer to private structure. + * @param[in] attr + * Flow rule attributes. + * @param[in] pattern + * Pattern specification (list terminated by the END pattern item). + * @param[in] actions + * Associated actions (list terminated by the END action). + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +priv_flow_validate(struct priv *priv, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + (void)priv; + const struct rte_flow_item *ilast = NULL; + + if (attr->group) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, + NULL, + "groups are not supported"); + return -rte_errno; + } + if (attr->priority) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + NULL, + "priorities are not supported"); + return -rte_errno; + } + if (attr->egress) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, + NULL, + "egress is not supported"); + return -rte_errno; + } + if (!attr->ingress) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "only ingress is supported"); + return -rte_errno; + } + for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) { + if (items->type == RTE_FLOW_ITEM_TYPE_VOID) { + continue; + } else if (items->type == RTE_FLOW_ITEM_TYPE_ETH) { + if (ilast) + goto exit_item_not_supported; + ilast = items; + } else if ((items->type == RTE_FLOW_ITEM_TYPE_IPV4) || + (items->type == RTE_FLOW_ITEM_TYPE_IPV6)) { + if (!ilast) + goto exit_item_not_supported; + else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH) + goto exit_item_not_supported; + ilast = items; + } else if ((items->type == RTE_FLOW_ITEM_TYPE_UDP) || + (items->type == RTE_FLOW_ITEM_TYPE_TCP)) { + if (!ilast) + goto exit_item_not_supported; + else if ((ilast->type != RTE_FLOW_ITEM_TYPE_IPV4) && + (ilast->type != RTE_FLOW_ITEM_TYPE_IPV6)) + goto exit_item_not_supported; + ilast = items; + } else { + goto exit_item_not_supported; + } + } + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; ++actions) { + if (actions->type == RTE_FLOW_ACTION_TYPE_VOID || + actions->type == RTE_FLOW_ACTION_TYPE_QUEUE || + actions->type == RTE_FLOW_ACTION_TYPE_DROP) + continue; + else + goto exit_action_not_supported; + } + return 0; +exit_item_not_supported: + rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, + items, "item not supported"); + return -rte_errno; +exit_action_not_supported: + rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + actions, "action not supported"); + return -rte_errno; +} + /** * Validate a flow supported by the NIC. * @@ -48,15 +156,13 @@ mlx5_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { - (void)dev; - (void)attr; - (void)items; - (void)actions; - (void)error; - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_NONE, - NULL, "not implemented yet"); - return -rte_errno; + struct priv *priv = dev->data->dev_private; + int ret; + + priv_lock(priv); + ret = priv_flow_validate(priv, attr, items, actions, error); + priv_unlock(priv); + return ret; } /** @@ -72,15 +178,35 @@ mlx5_flow_create(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { - (void)dev; - (void)attr; - (void)items; - (void)actions; - (void)error; - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_NONE, - NULL, "not implemented yet"); - return NULL; + struct priv *priv = dev->data->dev_private; + struct rte_flow *flow; + + priv_lock(priv); + if (priv_flow_validate(priv, attr, items, actions, error)) { + priv_unlock(priv); + return NULL; + } + flow = rte_malloc(__func__, sizeof(struct rte_flow), 0); + LIST_INSERT_HEAD(&priv->flows, flow, next); + priv_unlock(priv); + return flow; +} + +/** + * Destroy a flow. + * + * @param priv + * Pointer to private structure. + * @param[in] flow + * Pointer to the flow to destroy. + */ +static void +priv_flow_destroy(struct priv *priv, + struct rte_flow *flow) +{ + (void)priv; + LIST_REMOVE(flow, next); + rte_free(flow); } /** @@ -94,13 +220,30 @@ mlx5_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error) { - (void)dev; - (void)flow; + struct priv *priv = dev->data->dev_private; + (void)error; - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_NONE, - NULL, "not implemented yet"); - return -rte_errno; + priv_lock(priv); + priv_flow_destroy(priv, flow); + priv_unlock(priv); + return 0; +} + +/** + * Destroy all flows. + * + * @param priv + * Pointer to private structure. + */ +void +priv_flow_flush(struct priv *priv) +{ + while (!LIST_EMPTY(&priv->flows)) { + struct rte_flow *flow; + + flow = LIST_FIRST(&priv->flows); + priv_flow_destroy(priv, flow); + } } /** @@ -113,10 +256,11 @@ int mlx5_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) { - (void)dev; + struct priv *priv = dev->data->dev_private; + (void)error; - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_NONE, - NULL, "not implemented yet"); - return -rte_errno; + priv_lock(priv); + priv_flow_flush(priv); + priv_unlock(priv); + return 0; } diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index d4dccd8..4a359d7 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -90,6 +90,7 @@ mlx5_dev_start(struct rte_eth_dev *dev) if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE) priv_fdir_enable(priv); priv_dev_interrupt_handler_install(priv, dev); + LIST_INIT(&priv->flows); priv_unlock(priv); return -err; } @@ -120,6 +121,7 @@ mlx5_dev_stop(struct rte_eth_dev *dev) priv_mac_addrs_disable(priv); priv_destroy_hash_rxqs(priv); priv_fdir_disable(priv); + priv_flow_flush(priv); priv_dev_interrupt_handler_uninstall(priv, dev); priv->started = 0; priv_unlock(priv);