From patchwork Fri Nov 25 18:14:22 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: 17263 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 17B7AFA3F; Fri, 25 Nov 2016 19:15:42 +0100 (CET) Received: from mail-wj0-f181.google.com (mail-wj0-f181.google.com [209.85.210.181]) by dpdk.org (Postfix) with ESMTP id 6E1A4FA32 for ; Fri, 25 Nov 2016 19:14:49 +0100 (CET) Received: by mail-wj0-f181.google.com with SMTP id qp4so65197433wjc.3 for ; Fri, 25 Nov 2016 10:14:49 -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=pK1IhwRm7NMbgubhF8NvI77I2r/oo9/9a+zcl/yX0hM=; b=PQdkg0VY4BQijDZrezMbUhZ6F43mam3PvVZm4Qm4iuqoU3Ix1ZGx7zPKiTFdjQVS9T 4kFr4ki0MMZ0o5cIRww2injO+12Joug+KHVRMQk4X01UZMoSQepgGAmupMt4gRct57XR Wvgw6qUjlC75uArkQvahjmR57EBGOLLqT2az6AC7O1bkkDYWhaQFs4h7zWI9XFfC/Hk9 WniA8ljZjNSVIlEtcumWJBKP5hDMFl38zwylCfzUf/in9j+WlvVWWtTKPFK6qwqSkou1 i0aClIncx4x3bNsw4bdP94ktFK46WB3MTmSNywAO0Gc00va1qSqTvJ6YfmwarJQSlwmF rFug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=pK1IhwRm7NMbgubhF8NvI77I2r/oo9/9a+zcl/yX0hM=; b=EZxjRqAskO6kDRxMQcm598Hhk2HULiw87YPDTy8g9viWFfr8zN/ld9utxKhNk6tqtm aK+o1dI167e3mYej0t4IdxNGZ2KSex8R/M/42RgUZu4xMN41+L/Bz2bHaqtKN7p0n4jD BWCSApkQRXPKLXBAkfHZ/XMG9JKiYtx0yZxnSsyblRH6JdVoDsbtcdzIdKyeiwXQl/gO fdXN65EGOICf6d9I4lWBE9wuBTQUcid+27zGe0gXCtfCGpujoH5ClOmr2To43ODVqISq m9+mZXpFbIP3Fx+dRPbDIsb3PDnE/3UGlQqO+78Qyo4oarVB2X7hCZz/6gFK0Bt85OsU 59dQ== X-Gm-Message-State: AKaTC03Vapzl9bojsA1/6nwFN2KioIKr3748S5Ex7Lyap+EYakNXACgIB8Ei/SmEBO9cwUXm X-Received: by 10.194.85.107 with SMTP id g11mr8766058wjz.82.1480097689107; Fri, 25 Nov 2016 10:14:49 -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 135sm14610323wmh.14.2016.11.25.10.14.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 25 Nov 2016 10:14:48 -0800 (PST) From: Nelio Laranjeiro To: dev@dpdk.org Cc: Adrien Mazarguil Date: Fri, 25 Nov 2016 19:14:22 +0100 Message-Id: <351d1273612e100f44fc11bf7bcd6e372282bc38.1480096192.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 2/3] net/mlx5: add software support for rte_flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK 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 | 1 + drivers/net/mlx5/mlx5_flow.c | 196 ++++++++++++++++++++++++++++++++++------ drivers/net/mlx5/mlx5_trigger.c | 1 + 3 files changed, 169 insertions(+), 29 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 04f4eaa..df0e77c 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. */ }; diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index a514dff..54807ad 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -30,11 +30,125 @@ * 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; +}; + +/** + * 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; + const struct rte_flow_action *alast = 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) { + continue; + } else if ((actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) || + (actions->type == RTE_FLOW_ACTION_TYPE_DROP)) { + if (alast && + alast->type != actions->type) + goto exit_action_not_supported; + alast = actions; + } 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 +162,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 +184,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 +226,13 @@ 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; } /** @@ -113,10 +245,16 @@ 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); + while (!LIST_EMPTY(&priv->flows)) { + struct rte_flow *flow; + + flow = LIST_FIRST(&priv->flows); + priv_flow_destroy(priv, flow); + } + priv_unlock(priv); + return 0; } diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index d4dccd8..98a2803 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; }