From patchwork Thu Sep 27 14:50:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 45537 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 9367C1B4FF; Thu, 27 Sep 2018 16:52:28 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 8A06C1B4DC for ; Thu, 27 Sep 2018 16:52:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 27 Sep 2018 16:56:45 +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 w8REq7gJ013802; Thu, 27 Sep 2018 17:52:09 +0300 From: Dekel Peled To: dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com Cc: orika@mellanox.com Date: Thu, 27 Sep 2018 17:50:42 +0300 Message-Id: <1538059845-35896-2-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> References: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH 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. Signed-off-by: Dekel Peled --- drivers/net/mlx5/mlx5_glue.c | 33 +++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_glue.h | 7 +++++++ 2 files changed, 40 insertions(+) diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c index 48590df..caa4c34 100644 --- a/drivers/net/mlx5/mlx5_glue.c +++ b/drivers/net/mlx5/mlx5_glue.c @@ -174,6 +174,12 @@ return ibv_destroy_flow(flow_id); } +static int +mlx5_glue_destroy_flow_action(struct ibv_flow_action *action) +{ + return ibv_destroy_flow_action(action); +} + static struct ibv_qp * mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) { @@ -388,6 +394,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_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 +444,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 +468,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..7431f58 100644 --- a/drivers/net/mlx5/mlx5_glue.h +++ b/drivers/net/mlx5/mlx5_glue.h @@ -85,6 +85,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 +138,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 Thu Sep 27 14:50:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 45536 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 9DA1D1B4F5; Thu, 27 Sep 2018 16:52:23 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 811431B4D3 for ; Thu, 27 Sep 2018 16:52:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 27 Sep 2018 16:56:43 +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 w8REq7gK013802; Thu, 27 Sep 2018 17:52:10 +0300 From: Dekel Peled To: dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com Cc: orika@mellanox.com Date: Thu, 27 Sep 2018 17:50:43 +0300 Message-Id: <1538059845-35896-3-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> References: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH 2/4] net/mlx5: add definitions for DV encap and decap 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 add 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 --- drivers/net/mlx5/mlx5_flow.c | 10 ++++++++++ drivers/net/mlx5/mlx5_flow.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 79a06df..fed0d29 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -768,6 +768,16 @@ 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_ACTION_TUNNEL_DECAP | + MLX5_ACTION_TUNNEL_DECAP_L3 | + MLX5_ACTION_TUNNEL_ENCAP | + MLX5_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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, diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index a353d07..4a4f923 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -90,6 +90,10 @@ #define MLX5_ACTION_OF_PUSH_VLAN (1u << 8) #define MLX5_ACTION_OF_SET_VLAN_VID (1u << 9) #define MLX5_ACTION_OF_SET_VLAN_PCP (1u << 10) +#define MLX5_ACTION_TUNNEL_ENCAP (1u << 11) +#define MLX5_ACTION_TUNNEL_DECAP (1u << 12) +#define MLX5_ACTION_TUNNEL_ENCAP_L3 (1u << 13) +#define MLX5_ACTION_TUNNEL_DECAP_L3 (1u << 14) /* possible L3 layers protocols filtering. */ #define MLX5_IP_PROTOCOL_TCP 6 @@ -175,6 +179,9 @@ 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 Thu Sep 27 14:50:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 45534 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 9C2F01B4D1; Thu, 27 Sep 2018 16:52:17 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 6EC501B4D1 for ; Thu, 27 Sep 2018 16:52:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 27 Sep 2018 16:56:44 +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 w8REq7gL013802; Thu, 27 Sep 2018 17:52:10 +0300 From: Dekel Peled To: dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com Cc: orika@mellanox.com Date: Thu, 27 Sep 2018 17:50:44 +0300 Message-Id: <1538059845-35896-4-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> References: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH 3/4] net/mlx5: add DV encap L2 and L3 operations 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 --- drivers/net/mlx5/mlx5_flow_dv.c | 249 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 5 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 1f3fcb8..50925ac 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -85,6 +85,178 @@ } /** + * 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 +mlx5_flow_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_ACTION_DROP) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't drop and encap in same flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_ENCAP | + MLX5_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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 +mlx5_flow_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_ACTION_DROP) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't drop and encap in same flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_ENCAP | + MLX5_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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] action + * Pointer to action structure. + * @param[in] ctx + * Verbs context. + * @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 * +mlx5_flow_dv_create_encap(const struct rte_flow_action *action, + struct ibv_context *ctx, + struct rte_flow_error *error) +{ + struct ibv_flow_action *encap_verb = NULL; + const struct rte_flow_action_tunnel_encap *encap_data; + + encap_data = (const struct rte_flow_action_tunnel_encap *)action->conf; + encap_verb = mlx5_glue->dv_create_flow_action_packet_reformat(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] action + * Pointer to action structure. + * @param[in] ctx + * Verbs context. + * @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 * +mlx5_flow_dv_create_encap_l3(const struct rte_flow_action *action, + struct ibv_context *ctx, + struct rte_flow_error *error) +{ + struct ibv_flow_action *encap_l3_verb = NULL; + const struct rte_flow_action_tunnel_encap_l3 *encap_l3_data; + + encap_l3_data = + (const struct rte_flow_action_tunnel_encap_l3 *)action->conf; + encap_l3_verb = mlx5_glue->dv_create_flow_action_packet_reformat(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. * @@ -337,6 +509,26 @@ action_flags |= MLX5_ACTION_COUNT; ++actions_n; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP: + ret = mlx5_flow_validate_action_tunnel_encap + (action_flags, + actions, + attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_TUNNEL_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_ENCAP_L3: + ret = mlx5_flow_validate_action_tunnel_encap_l3 + (action_flags, + actions, + attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_TUNNEL_ENCAP_L3; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -1047,10 +1239,19 @@ * Flow action to translate. * @param[in, out] dev_flow * Pointer to the mlx5_flow. + * @param[in] ctx + * Verbs context. + * @param[out] error + * Pointer to the error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. */ -static void +static int flow_dv_create_action(const struct rte_flow_action *action, - struct mlx5_flow *dev_flow) + struct mlx5_flow *dev_flow, + struct ibv_context *ctx, + struct rte_flow_error *error) { const struct rte_flow_action_queue *queue; const struct rte_flow_action_rss *rss; @@ -1095,10 +1296,35 @@ /* Added to array only in apply since we need the QP */ flow->actions |= MLX5_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 = + mlx5_flow_dv_create_encap(action, ctx, 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_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 = + mlx5_flow_dv_create_encap_l3(action, ctx, 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_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 }; @@ -1247,6 +1473,7 @@ }; void *match_value = dev_flow->dv.value.buf; uint8_t inner = 0; + int retval = 0; if (priority == MLX5_FLOW_PRIO_RSVD) priority = priv->config.flow_prio - 1; @@ -1262,9 +1489,14 @@ 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); - return 0; + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + retval = + flow_dv_create_action(actions, dev_flow, priv->ctx, error); + if (retval) + break; + } + + return retval; } /** @@ -1447,6 +1679,13 @@ 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 Thu Sep 27 14:50:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 45535 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 22E3B1B4E3; Thu, 27 Sep 2018 16:52:20 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 84D061B4D9 for ; Thu, 27 Sep 2018 16:52:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 27 Sep 2018 16:56:45 +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 w8REq7gM013802; Thu, 27 Sep 2018 17:52:11 +0300 From: Dekel Peled To: dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com Cc: orika@mellanox.com Date: Thu, 27 Sep 2018 17:50:45 +0300 Message-Id: <1538059845-35896-5-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> References: <1538059845-35896-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH 4/4] net/mlx5: add DV decap L2 and L3 operations 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 --- drivers/net/mlx5/mlx5_flow_dv.c | 258 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 248 insertions(+), 10 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 50925ac..ca44f13 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -126,12 +126,20 @@ NULL, "can't have 2 encap actions in same" " flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_DECAP | + MLX5_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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, - NULL, - "encap action not supported for " - "ingress"); + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "encap action not supported for " + "ingress"); return 0; } @@ -178,12 +186,130 @@ NULL, "can't have 2 encap actions in same" " flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_DECAP | + MLX5_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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, - NULL, - "encap action not supported for " - "ingress"); + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "encap action not supported for " + "ingress"); + return 0; +} + +/** + * 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 +mlx5_flow_validate_action_tunnel_decap(uint64_t action_flags, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + if (action_flags & MLX5_ACTION_DROP) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't drop and decap in same flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_DECAP | + MLX5_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't have 2 decap actions in same" + " flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_ENCAP | + MLX5_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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 +mlx5_flow_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_ACTION_DROP) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't drop and decap in same flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_DECAP | + MLX5_ACTION_TUNNEL_DECAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "can't have 2 decap actions in same" + " flow"); + if (action_flags & (MLX5_ACTION_TUNNEL_ENCAP | + MLX5_ACTION_TUNNEL_ENCAP_L3)) + return rte_flow_error_set(error, + ENOTSUP, + 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; } @@ -257,6 +383,72 @@ } /** + * Convert decap action to DV specification. + * + * @param[in] action + * Pointer to action structure. + * @param[in] ctx + * Verbs context. + * @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 * +mlx5_flow_dv_create_decap(const struct rte_flow_action *action __rte_unused, + struct ibv_context *ctx, + struct rte_flow_error *error) +{ + struct ibv_flow_action *decap_verb = NULL; + + decap_verb = mlx5_glue->dv_create_flow_action_packet_reformat(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] action + * Pointer to action structure. + * @param[in] ctx + * Verbs context. + * @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 * +mlx5_flow_dv_create_decap_l3(const struct rte_flow_action *action, + struct ibv_context *ctx, + struct rte_flow_error *error) +{ + struct ibv_flow_action *decap_l3_verb = NULL; + const struct rte_flow_action_tunnel_decap_l3 *decap_l3_data; + + decap_l3_data = + (const struct rte_flow_action_tunnel_decap_l3 *)action->conf; + decap_l3_verb = mlx5_glue->dv_create_flow_action_packet_reformat(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. * @@ -529,6 +721,25 @@ return ret; action_flags |= MLX5_ACTION_TUNNEL_ENCAP_L3; break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP: + ret = mlx5_flow_validate_action_tunnel_decap + (action_flags, + attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_TUNNEL_DECAP; + break; + case RTE_FLOW_ACTION_TYPE_TUNNEL_DECAP_L3: + ret = mlx5_flow_validate_action_tunnel_decap_l3 + (action_flags, + actions, + attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_TUNNEL_DECAP_L3; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -1320,6 +1531,30 @@ flow->actions |= MLX5_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 = + mlx5_flow_dv_create_decap(action, ctx, 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_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 = + mlx5_flow_dv_create_decap_l3(action, ctx, 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_ACTION_TUNNEL_DECAP_L3; + actions_n++; + break; default: break; } @@ -1679,13 +1914,16 @@ 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; } - + 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); } }