From patchwork Wed Oct 10 08:35:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 46466 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0F6C31B429; Wed, 10 Oct 2018 10:35:45 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id A0CC71B192 for ; Wed, 10 Oct 2018 10:35:41 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Oct 2018 10:40:29 +0200 Received: from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx [10.128.130.87]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w9A8ZbOv011577; Wed, 10 Oct 2018 11:35:39 +0300 From: Dekel Peled To: yskoh@mellanox.com, shahafs@mellanox.com Cc: dev@dpdk.org, orika@mellanox.com Date: Wed, 10 Oct 2018 11:35:28 +0300 Message-Id: <1539160531-27953-2-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> References: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH v4 1/4] net/mlx5: add flow action functions to glue 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" This patch adds glue functions for operations: - Create packet reformat (encap/decap) flow action. - Destroy flow action. The new operations depend on HAVE_IBV_FLOW_ACTION_DV_SUPPORT. Signed-off-by: Dekel Peled --- drivers/net/mlx5/Makefile | 5 +++++ drivers/net/mlx5/meson.build | 2 ++ drivers/net/mlx5/mlx5_glue.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_glue.h | 13 +++++++++++++ 4 files changed, 58 insertions(+) diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 92bae9d..474ad42 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -142,6 +142,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum MLX5DV_FLOW_ACTION_TAG \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_IBV_FLOW_ACTION_DV_SUPPORT \ + infiniband/mlx5dv.h \ + func mlx5dv_create_flow_action_packet_reformat \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_ETHTOOL_LINK_MODE_25G \ /usr/include/linux/ethtool.h \ enum ETHTOOL_LINK_MODE_25000baseCR_Full_BIT \ diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index 6966248..d555c3c 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -96,6 +96,8 @@ if build 'MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP' ], [ 'HAVE_IBV_FLOW_DV_SUPPORT', 'infiniband/mlx5dv.h', 'MLX5DV_FLOW_ACTION_TAG' ], + [ 'HAVE_IBV_FLOW_ACTION_DV_SUPPORT', 'infiniband/mlx5dv.h', + 'mlx5dv_create_flow_action_packet_reformat' ], [ 'HAVE_IBV_DEVICE_MPLS_SUPPORT', 'infiniband/verbs.h', 'IBV_FLOW_SPEC_MPLS' ], [ 'HAVE_IBV_WQ_FLAG_RX_END_PADDING', 'infiniband/verbs.h', diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c index 48590df..c9b747e 100644 --- a/drivers/net/mlx5/mlx5_glue.c +++ b/drivers/net/mlx5/mlx5_glue.c @@ -174,6 +174,17 @@ return ibv_destroy_flow(flow_id); } +static int +mlx5_glue_destroy_flow_action(struct ibv_flow_action *action) +{ +#ifdef HAVE_IBV_FLOW_ACTION_DV_SUPPORT + return ibv_destroy_flow_action(action); +#else + (void)action; + return ENOTSUP; +#endif +} + static struct ibv_qp * mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) { @@ -388,6 +399,30 @@ #endif } +static struct ibv_flow_action * +mlx5_glue_dv_create_flow_action_packet_reformat + (struct ibv_context *ctx, + size_t data_sz, + void *data, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type) +{ +#ifdef HAVE_IBV_FLOW_ACTION_DV_SUPPORT + return mlx5dv_create_flow_action_packet_reformat(ctx, + data_sz, + data, + reformat_type, + ft_type); +#else + (void)ctx; + (void)data_sz; + (void)data; + (void)reformat_type; + (void)ft_type; + return NULL; +#endif +} + alignas(RTE_CACHE_LINE_SIZE) const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ .version = MLX5_GLUE_VERSION, @@ -414,6 +449,7 @@ .modify_wq = mlx5_glue_modify_wq, .create_flow = mlx5_glue_create_flow, .destroy_flow = mlx5_glue_destroy_flow, + .destroy_flow_action = mlx5_glue_destroy_flow_action, .create_qp = mlx5_glue_create_qp, .create_qp_ex = mlx5_glue_create_qp_ex, .destroy_qp = mlx5_glue_destroy_qp, @@ -437,4 +473,6 @@ .dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher, .dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher, .dv_create_flow = mlx5_glue_dv_create_flow, + .dv_create_flow_action_packet_reformat = + mlx5_glue_dv_create_flow_action_packet_reformat, }; diff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h index f6e4e38..dce6bb4 100644 --- a/drivers/net/mlx5/mlx5_glue.h +++ b/drivers/net/mlx5/mlx5_glue.h @@ -46,6 +46,12 @@ struct mlx5dv_flow_match_parameters; #endif +#ifndef HAVE_IBV_FLOW_ACTION_DV_SUPPORT +struct ibv_flow_action; +enum mlx5dv_flow_action_packet_reformat_type { packet_reformat_type = 0, }; +enum mlx5dv_flow_table_type { flow_table_type = 0, }; +#endif + /* LIB_GLUE_VERSION must be updated every time this structure is modified. */ struct mlx5_glue { const char *version; @@ -85,6 +91,7 @@ struct mlx5_glue { struct ibv_flow *(*create_flow)(struct ibv_qp *qp, struct ibv_flow_attr *flow); int (*destroy_flow)(struct ibv_flow *flow_id); + int (*destroy_flow_action)(struct ibv_flow_action *action); struct ibv_qp *(*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr); struct ibv_qp *(*create_qp_ex) @@ -137,6 +144,12 @@ struct mlx5_glue { struct mlx5dv_flow_match_parameters *match_value, size_t num_actions, struct mlx5dv_flow_action_attr *actions_attr); + struct ibv_flow_action *(*dv_create_flow_action_packet_reformat) + (struct ibv_context *ctx, + size_t data_sz, + void *data, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type); }; const struct mlx5_glue *mlx5_glue; From patchwork Wed Oct 10 08:35:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 46465 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E24DE1B1C3; Wed, 10 Oct 2018 10:35:42 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id A6C491B1DA for ; Wed, 10 Oct 2018 10:35:41 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Oct 2018 10:40:30 +0200 Received: from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx [10.128.130.87]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w9A8ZbOw011577; Wed, 10 Oct 2018 11:35:40 +0300 From: Dekel Peled To: yskoh@mellanox.com, shahafs@mellanox.com Cc: dev@dpdk.org, orika@mellanox.com Date: Wed, 10 Oct 2018 11:35:29 +0300 Message-Id: <1539160531-27953-3-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> References: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH v4 2/4] net/mlx5: add Direct Verbs encap and decap defs 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" This patch adds the required definitions for DV encap/decap actions. It also adds usage of the new actions definition in validation function of existing drop operation. Signed-off-by: Dekel Peled Acked-by: Yongseok Koh --- drivers/net/mlx5/mlx5_flow.c | 8 ++++++++ drivers/net/mlx5/mlx5_flow.h | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 1087f67..b452e11 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -766,6 +766,14 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have 2 fate actions in" " same flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_DECAP | + MLX5_FLOW_ACTION_TUNNEL_DECAP_L3 | + MLX5_FLOW_ACTION_TUNNEL_ENCAP | + MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't encap or decap and drop in" + " same flow"); if (attr->egress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 690c597..01c73a2 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -82,6 +82,10 @@ #define MLX5_FLOW_ACTION_OF_SET_VLAN_VID (1u << 9) #define MLX5_FLOW_ACTION_OF_SET_VLAN_PCP (1u << 10) #define MLX5_FLOW_ACTION_JUMP (1u << 11) +#define MLX5_FLOW_ACTION_TUNNEL_ENCAP (1u << 12) +#define MLX5_FLOW_ACTION_TUNNEL_DECAP (1u << 13) +#define MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3 (1u << 14) +#define MLX5_FLOW_ACTION_TUNNEL_DECAP_L3 (1u << 15) #define MLX5_FLOW_FATE_ACTIONS \ (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS) @@ -172,6 +176,8 @@ struct mlx5_flow_dv { #ifdef HAVE_IBV_FLOW_DV_SUPPORT struct mlx5dv_flow_action_attr actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS]; /**< Action list. */ + struct ibv_flow_action *encap_verb; /**< Verbs object of encap. */ + struct ibv_flow_action *decap_verb; /**< Verbs object of decap. */ #endif int actions_n; /**< number of actions. */ }; From patchwork Wed Oct 10 08:35:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 46468 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3F7471B471; Wed, 10 Oct 2018 10:35:50 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 9D7BE1B446 for ; Wed, 10 Oct 2018 10:35:46 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Oct 2018 10:40:31 +0200 Received: from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx [10.128.130.87]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w9A8ZbOx011577; Wed, 10 Oct 2018 11:35:41 +0300 From: Dekel Peled To: yskoh@mellanox.com, shahafs@mellanox.com Cc: dev@dpdk.org, orika@mellanox.com Date: Wed, 10 Oct 2018 11:35:30 +0300 Message-Id: <1539160531-27953-4-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> References: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH v4 3/4] net/mlx5: add L2 and L3 encap to Direct Verbs 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" This patch adds support for Direct Verbs encap operations, L2 and L3. Signed-off-by: Dekel Peled Acked-by: Yongseok Koh --- drivers/net/mlx5/mlx5_flow_dv.c | 227 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 5 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 80e7b24..73a22ba 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -84,6 +84,168 @@ } /** + * Validate the tunnel encap action. + * + * @param[in] action_flags + * holds the actions detected until now. + * @param[in] action + * Pointer to the encap action. + * @param[in] attr + * Pointer to flow attributes + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +flow_dv_validate_action_tunnel_encap(uint64_t action_flags, + const struct rte_flow_action *action, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + const struct rte_flow_action_tunnel_encap *tunnel_encap = action->conf; + + if (!tunnel_encap || !(tunnel_encap->buf)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "configuration cannot be null"); + if (action_flags & MLX5_FLOW_ACTION_DROP) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't drop and encap in same flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_ENCAP | + MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't have 2 encap actions in same" + " flow"); + if (attr->ingress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "encap action not supported for " + "ingress"); + return 0; +} + +/** + * Validate the tunnel encap L3 action + * + * @param[in] action_flags + * holds the actions detected until now. + * @param[in] action + * Pointer to the encap action. + * @param[in] attr + * Pointer to flow attributes + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +flow_dv_validate_action_tunnel_encap_l3(uint64_t action_flags, + const struct rte_flow_action *action, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + const struct rte_flow_action_tunnel_encap_l3 *tunnel_encap_l3 = + action->conf; + + if (!tunnel_encap_l3 || !(tunnel_encap_l3->buf)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "configuration cannot be null"); + if (action_flags & MLX5_FLOW_ACTION_DROP) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't drop and encap in same flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_ENCAP | + MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't have 2 encap actions in same" + " flow"); + if (attr->ingress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "encap action not supported for " + "ingress"); + return 0; +} + +/** + * Convert encap action to DV specification. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] action + * Pointer to action structure. + * @param[out] error + * Pointer to the error structure. + * + * @return + * Pointer to action on success, NULL otherwise and rte_errno is set. + */ +static struct ibv_flow_action * +flow_dv_create_encap(struct rte_eth_dev *dev, + const struct rte_flow_action *action, + struct rte_flow_error *error) +{ + struct ibv_flow_action *encap_verb = NULL; + const struct rte_flow_action_tunnel_encap *encap_data; + struct priv *priv = dev->data->dev_private; + + encap_data = (const struct rte_flow_action_tunnel_encap *)action->conf; + encap_verb = mlx5_glue->dv_create_flow_action_packet_reformat + (priv->ctx, encap_data->size, + encap_data->size ? encap_data->buf : NULL, + MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL, + MLX5DV_FLOW_TABLE_TYPE_NIC_TX); + if (!encap_verb) + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "cannot create encap action"); + return encap_verb; +} + +/** + * Convert encap L3 action to DV specification. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] action + * Pointer to action structure. + * @param[out] error + * Pointer to the error structure. + * + * @return + * Pointer to action on success, NULL otherwise and rte_errno is set. + */ +static struct ibv_flow_action * +flow_dv_create_encap_l3(struct rte_eth_dev *dev, + const struct rte_flow_action *action, + struct rte_flow_error *error) +{ + struct ibv_flow_action *encap_l3_verb = NULL; + const struct rte_flow_action_tunnel_encap_l3 *encap_l3_data; + struct priv *priv = dev->data->dev_private; + + encap_l3_data = + (const struct rte_flow_action_tunnel_encap_l3 *)action->conf; + encap_l3_verb = mlx5_glue->dv_create_flow_action_packet_reformat + (priv->ctx, encap_l3_data->size, + encap_l3_data->size ? encap_l3_data->buf : NULL, + MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL, + MLX5DV_FLOW_TABLE_TYPE_NIC_TX); + if (!encap_l3_verb) + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "cannot create encap L3 action"); + return encap_l3_verb; +} + +/** * Verify the @p attributes will be correctly understood by the NIC and store * them in the @p flow if everything is correct. * @@ -330,6 +492,20 @@ action_flags |= MLX5_FLOW_ACTION_COUNT; ++actions_n; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP: + ret = flow_dv_validate_action_tunnel_encap + (action_flags, actions, attr, error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_TUNNEL_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP_L3: + ret = flow_dv_validate_action_tunnel_encap_l3 + (action_flags, actions, attr, error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -1038,14 +1214,23 @@ /** * Store the requested actions in an array. * + * @param[in] dev + * Pointer to rte_eth_dev structure. * @param[in] action * Flow action to translate. * @param[in, out] dev_flow * Pointer to the mlx5_flow. + * @param[out] error + * Pointer to the error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. */ -static void -flow_dv_create_action(const struct rte_flow_action *action, - struct mlx5_flow *dev_flow) +static int +flow_dv_create_action(struct rte_eth_dev *dev, + const struct rte_flow_action *action, + struct mlx5_flow *dev_flow, + struct rte_flow_error *error) { const struct rte_flow_action_queue *queue; const struct rte_flow_action_rss *rss; @@ -1092,10 +1277,35 @@ /* Added to array only in apply since we need the QP */ flow->actions |= MLX5_FLOW_ACTION_RSS; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + flow_dv_create_encap(dev, action, error); + if (!(dev_flow->dv.actions[actions_n].action)) + return -rte_errno; + dev_flow->dv.encap_verb = + dev_flow->dv.actions[actions_n].action; + flow->actions |= MLX5_FLOW_ACTION_TUNNEL_ENCAP; + actions_n++; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP_L3: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + flow_dv_create_encap_l3(dev, action, error); + if (!(dev_flow->dv.actions[actions_n].action)) + return -rte_errno; + dev_flow->dv.encap_verb = + dev_flow->dv.actions[actions_n].action; + flow->actions |= MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3; + actions_n++; + break; default: break; } dev_flow->dv.actions_n = actions_n; + return 0; } static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 }; @@ -1259,8 +1469,10 @@ matcher.egress = attr->egress; if (flow_dv_matcher_register(dev, &matcher, dev_flow, error)) return -rte_errno; - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) - flow_dv_create_action(actions, dev_flow); + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + if (flow_dv_create_action(dev, actions, dev_flow, error)) + return -rte_errno; + } return 0; } @@ -1444,6 +1656,11 @@ LIST_REMOVE(dev_flow, next); if (dev_flow->dv.matcher) flow_dv_matcher_release(dev, dev_flow->dv.matcher); + if (dev_flow->dv.encap_verb) { + claim_zero(mlx5_glue->destroy_flow_action + (dev_flow->dv.encap_verb)); + dev_flow->dv.encap_verb = NULL; + } rte_free(dev_flow); } } From patchwork Wed Oct 10 08:35:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 46469 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0A5471B47B; Wed, 10 Oct 2018 10:35:52 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 7F1DD1B445 for ; Wed, 10 Oct 2018 10:35:46 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Oct 2018 10:40:32 +0200 Received: from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx [10.128.130.87]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w9A8ZbP0011577; Wed, 10 Oct 2018 11:35:42 +0300 From: Dekel Peled To: yskoh@mellanox.com, shahafs@mellanox.com Cc: dev@dpdk.org, orika@mellanox.com Date: Wed, 10 Oct 2018 11:35:31 +0300 Message-Id: <1539160531-27953-5-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> References: <1539113137-4914-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH v4 4/4] net/mlx5: add L2 and L3 decap to Direct Verbs 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" This patch adds support for Direct Verbs decap operations, L2 and L3. Signed-off-by: Dekel Peled Acked-by: Yongseok Koh --- drivers/net/mlx5/mlx5_flow_dv.c | 215 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 73a22ba..d4ff812 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -120,6 +120,12 @@ RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have 2 encap actions in same" " flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_DECAP | + MLX5_FLOW_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't encap and decap in same" + " flow"); if (attr->ingress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, @@ -167,6 +173,12 @@ RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have 2 encap actions in same" " flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_DECAP | + MLX5_FLOW_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't encap and decap in same" + " flow"); if (attr->ingress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, @@ -177,6 +189,100 @@ } /** + * Validate the tunnel decap action + * + * @param[in] action_flags + * holds the actions detected until now. + * @param[in] attr + * Pointer to flow attributes + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +flow_dv_validate_action_tunnel_decap(uint64_t action_flags, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + if (action_flags & MLX5_FLOW_ACTION_DROP) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't drop and decap in same flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_DECAP | + MLX5_FLOW_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't have 2 decap actions in same" + " flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_ENCAP | + MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't encap and decap in same" + " flow"); + if (attr->egress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, + "decap action not supported for " + "egress"); + return 0; +} + +/** + * Validate the tunnel decap L3 action + * + * @param[in] action_flags + * holds the actions detected until now. + * @param[in] action + * Pointer to the decap action. + * @param[in] attr + * Pointer to flow attributes + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +flow_dv_validate_action_tunnel_decap_l3(uint64_t action_flags, + const struct rte_flow_action *action, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + const struct rte_flow_action_tunnel_decap_l3 *tunnel_decap_l3 = + action->conf; + + if (!tunnel_decap_l3 || !(tunnel_decap_l3->buf)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "configuration cannot be null"); + if (action_flags & MLX5_FLOW_ACTION_DROP) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't drop and decap in same flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_DECAP | + MLX5_FLOW_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't have 2 decap actions in same" + " flow"); + if (action_flags & (MLX5_FLOW_ACTION_TUNNEL_ENCAP | + MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "can't encap and decap in same" + " flow"); + if (attr->egress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, + "decap action not supported for " + "egress"); + return 0; +} + +/** * Convert encap action to DV specification. * * @param[in] dev @@ -246,6 +352,72 @@ } /** + * Convert decap action to DV specification. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] action + * Pointer to action structure. + * @param[out] error + * Pointer to the error structure. + * + * @return + * Pointer to action on success, NULL otherwise and rte_errno is set. + */ +static struct ibv_flow_action * +flow_dv_create_decap(struct rte_eth_dev *dev, + const struct rte_flow_action *action __rte_unused, + struct rte_flow_error *error) +{ + struct ibv_flow_action *decap_verb = NULL; + struct priv *priv = dev->data->dev_private; + + decap_verb = mlx5_glue->dv_create_flow_action_packet_reformat + (priv->ctx, 0, NULL, + MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2, + MLX5DV_FLOW_TABLE_TYPE_NIC_RX); + if (!decap_verb) + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "cannot create decap action"); + return decap_verb; +} + +/** + * Convert decap L3 action to DV specification. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] action + * Pointer to action structure. + * @param[out] error + * Pointer to the error structure. + * + * @return + * Pointer to action on success, NULL otherwise and rte_errno is set. + */ +static struct ibv_flow_action * +flow_dv_create_decap_l3(struct rte_eth_dev *dev, + const struct rte_flow_action *action, + struct rte_flow_error *error) +{ + struct ibv_flow_action *decap_l3_verb = NULL; + const struct rte_flow_action_tunnel_decap_l3 *decap_l3_data; + struct priv *priv = dev->data->dev_private; + + decap_l3_data = + (const struct rte_flow_action_tunnel_decap_l3 *)action->conf; + decap_l3_verb = mlx5_glue->dv_create_flow_action_packet_reformat + (priv->ctx, decap_l3_data->size, + decap_l3_data->size ? decap_l3_data->buf : NULL, + MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2, + MLX5DV_FLOW_TABLE_TYPE_NIC_RX); + if (!decap_l3_verb) + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "cannot create decap L3 action"); + return decap_l3_verb; +} + +/** * Verify the @p attributes will be correctly understood by the NIC and store * them in the @p flow if everything is correct. * @@ -506,6 +678,20 @@ return ret; action_flags |= MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP: + ret = flow_dv_validate_action_tunnel_decap + (action_flags, attr, error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_TUNNEL_DECAP; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP_L3: + ret = flow_dv_validate_action_tunnel_decap_l3 + (action_flags, actions, attr, error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_TUNNEL_DECAP_L3; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -1301,6 +1487,30 @@ flow->actions |= MLX5_FLOW_ACTION_TUNNEL_ENCAP_L3; actions_n++; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + flow_dv_create_decap(dev, action, error); + if (!(dev_flow->dv.actions[actions_n].action)) + return -rte_errno; + dev_flow->dv.decap_verb = + dev_flow->dv.actions[actions_n].action; + flow->actions |= MLX5_FLOW_ACTION_TUNNEL_DECAP; + actions_n++; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP_L3: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + flow_dv_create_decap_l3(dev, action, error); + if (!(dev_flow->dv.actions[actions_n].action)) + return -rte_errno; + dev_flow->dv.decap_verb = + dev_flow->dv.actions[actions_n].action; + flow->actions |= MLX5_FLOW_ACTION_TUNNEL_DECAP_L3; + actions_n++; + break; default: break; } @@ -1661,6 +1871,11 @@ (dev_flow->dv.encap_verb)); dev_flow->dv.encap_verb = NULL; } + if (dev_flow->dv.decap_verb) { + claim_zero(mlx5_glue->destroy_flow_action + (dev_flow->dv.decap_verb)); + dev_flow->dv.decap_verb = NULL; + } rte_free(dev_flow); } }