From patchwork Wed Oct 24 11:08:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dekel Peled X-Patchwork-Id: 47319 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 9D1A01B1E8; Wed, 24 Oct 2018 13:09:13 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id EB4761B192 for ; Wed, 24 Oct 2018 13:09:09 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from dekelp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 24 Oct 2018 13:14:15 +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 w9OB8xX4024546; Wed, 24 Oct 2018 14:09:07 +0300 From: Dekel Peled To: yskoh@mellanox.com, shahafs@mellanox.com Cc: dev@dpdk.org, orika@mellanox.com Date: Wed, 24 Oct 2018 14:08:19 +0300 Message-Id: <1540379299-23764-3-git-send-email-dekelp@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1540379299-23764-1-git-send-email-dekelp@mellanox.com> References: <1540379299-23764-1-git-send-email-dekelp@mellanox.com> Subject: [dpdk-dev] [PATCH 2/2] net/mlx5: add NVGRE encap decap to Direct Verbs 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 NVGRE encap and decap operations, in Direct Verbs flow. Signed-off-by: Dekel Peled --- drivers/net/mlx5/mlx5_flow.h | 2 + drivers/net/mlx5/mlx5_flow_dv.c | 144 ++++++++++++++++++++++++---------------- 2 files changed, 89 insertions(+), 57 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 9c28e50..dd7c3db 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -94,6 +94,8 @@ #define MLX5_FLOW_ACTION_SET_MAC_DST (1u << 21) #define MLX5_FLOW_ACTION_VXLAN_ENCAP (1u << 22) #define MLX5_FLOW_ACTION_VXLAN_DECAP (1u << 23) +#define MLX5_FLOW_ACTION_NVGRE_ENCAP (1u << 24) +#define MLX5_FLOW_ACTION_NVGRE_DECAP (1u << 25) #define MLX5_FLOW_FATE_ACTIONS \ (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 06ecabf..ca87ae8 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -43,7 +43,7 @@ * Encap buf length, max: * Eth:14/VLAN:8/IPv6:40/TCP:36/TUNNEL:20/Eth:14 */ -#define MLX5_ENCAP_LEN 132 +#define MLX5_ENCAP_MAX_LEN 132 /** * Validate META item. @@ -107,7 +107,8 @@ } /** - * Validate the vxlan encap action. + * Validate the L2 encap action. + * Used for VXLAN and NVGRE encap actions. * * @param[in] action_flags * Holds the actions detected until now. @@ -122,14 +123,12 @@ * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_validate_action_vxlan_encap(uint64_t action_flags, - const struct rte_flow_action *action, - const struct rte_flow_attr *attr, - struct rte_flow_error *error) +flow_dv_validate_action_l2_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_vxlan_encap *vxlan_encap = action->conf; - - if (!vxlan_encap) + if (!(action->conf)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, "configuration cannot be null"); @@ -137,11 +136,14 @@ 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_VXLAN_ENCAP) + if (action_flags & (MLX5_FLOW_ACTION_VXLAN_ENCAP | + MLX5_FLOW_ACTION_VXLAN_DECAP | + MLX5_FLOW_ACTION_NVGRE_ENCAP | + MLX5_FLOW_ACTION_NVGRE_DECAP)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "can't have 2 encap actions in same" - " flow"); + "can have a single encap or decap" + " action in a flow"); if (attr->ingress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, @@ -152,7 +154,8 @@ } /** - * Validate the vxlan decap action. + * Validate the L2 decap action. + * Used for VXLAN and NVGRE decap actions. * * @param[in] action_flags * Holds the actions detected until now. @@ -167,7 +170,7 @@ * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_validate_action_vxlan_decap(uint64_t action_flags, +flow_dv_validate_action_l2_decap(uint64_t action_flags, const struct rte_flow_action *action __rte_unused, const struct rte_flow_attr *attr, struct rte_flow_error *error) @@ -176,10 +179,14 @@ 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_VXLAN_ENCAP) + if (action_flags & (MLX5_FLOW_ACTION_VXLAN_ENCAP | + MLX5_FLOW_ACTION_VXLAN_DECAP | + MLX5_FLOW_ACTION_NVGRE_ENCAP | + MLX5_FLOW_ACTION_NVGRE_DECAP)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "can't encap and decap in same flow"); + "can have a single encap or decap" + " action in a flow"); if (attr->egress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, @@ -190,18 +197,18 @@ } static size_t item_len[] = { - [RTE_FLOW_ITEM_TYPE_VOID] = 0, - [RTE_FLOW_ITEM_TYPE_ETH] = sizeof(struct rte_flow_item_eth), - [RTE_FLOW_ITEM_TYPE_VLAN] = sizeof(struct rte_flow_item_vlan), - [RTE_FLOW_ITEM_TYPE_IPV4] = sizeof(struct rte_flow_item_ipv4), - [RTE_FLOW_ITEM_TYPE_IPV6] = sizeof(struct rte_flow_item_ipv6), - [RTE_FLOW_ITEM_TYPE_UDP] = sizeof(struct rte_flow_item_udp), - [RTE_FLOW_ITEM_TYPE_TCP] = sizeof(struct rte_flow_item_tcp), - [RTE_FLOW_ITEM_TYPE_VXLAN] = sizeof(struct rte_flow_item_vxlan), - [RTE_FLOW_ITEM_TYPE_GRE] = sizeof(struct rte_flow_item_gre), - [RTE_FLOW_ITEM_TYPE_NVGRE] = sizeof(struct rte_flow_item_gre), + [RTE_FLOW_ITEM_TYPE_VOID] = 0, + [RTE_FLOW_ITEM_TYPE_ETH] = sizeof(struct rte_flow_item_eth), + [RTE_FLOW_ITEM_TYPE_VLAN] = sizeof(struct rte_flow_item_vlan), + [RTE_FLOW_ITEM_TYPE_IPV4] = sizeof(struct rte_flow_item_ipv4), + [RTE_FLOW_ITEM_TYPE_IPV6] = sizeof(struct rte_flow_item_ipv6), + [RTE_FLOW_ITEM_TYPE_UDP] = sizeof(struct rte_flow_item_udp), + [RTE_FLOW_ITEM_TYPE_TCP] = sizeof(struct rte_flow_item_tcp), + [RTE_FLOW_ITEM_TYPE_VXLAN] = sizeof(struct rte_flow_item_vxlan), + [RTE_FLOW_ITEM_TYPE_GRE] = sizeof(struct rte_flow_item_gre), + [RTE_FLOW_ITEM_TYPE_NVGRE] = sizeof(struct rte_flow_item_nvgre), [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = sizeof(struct rte_flow_item_vxlan_gpe), - [RTE_FLOW_ITEM_TYPE_MPLS] = sizeof(struct rte_flow_item_mpls), + [RTE_FLOW_ITEM_TYPE_MPLS] = sizeof(struct rte_flow_item_mpls), }; /** @@ -222,8 +229,9 @@ * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_convert_encap(struct rte_flow_item *item, uint8_t *buf, size_t *size, - struct rte_flow_error *error, uint16_t l3_type) +flow_dv_convert_encap(const struct rte_flow_item *item, uint8_t *buf, + size_t *size, struct rte_flow_error *error, + uint16_t l3_type) { struct ether_hdr *eth = NULL; struct vlan_hdr *vlan = NULL; @@ -237,9 +245,8 @@ assert(item); *size = 0; for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { - /* TODO: variable length handling: raw, vxlan and nvgre. */ len = item_len[item->type]; - if (len + *size > MLX5_ENCAP_LEN) + if (len + *size > MLX5_ENCAP_MAX_LEN) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, (void *)item->type, @@ -361,7 +368,8 @@ } /** - * Convert VXLAN encap action to DV specification. + * Convert L2 encap action to DV specification. + * Used for VXLAN and NVGRE encap actions. * * @param[in] dev * Pointer to rte_eth_dev structure. @@ -374,20 +382,25 @@ * Pointer to action on success, NULL otherwise and rte_errno is set. */ static struct ibv_flow_action * -flow_dv_create_vxlan_encap(struct rte_eth_dev *dev, - const struct rte_flow_action *action, - struct rte_flow_error *error) +flow_dv_create_l2_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_vxlan_encap *encap_data; + const struct rte_flow_item *encap_data; struct priv *priv = dev->data->dev_private; - uint8_t buf[MLX5_ENCAP_LEN]; + uint8_t buf[MLX5_ENCAP_MAX_LEN]; size_t size = 0; int convert_result; - encap_data = (const struct rte_flow_action_vxlan_encap *)action->conf; - convert_result = flow_dv_convert_encap(encap_data->definition, - buf, &size, error, 0); + if (action->type == RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) + encap_data = ((const struct rte_flow_action_vxlan_encap *) + action->conf)->definition; + else + encap_data = ((const struct rte_flow_action_nvgre_encap *) + action->conf)->definition; + convert_result = flow_dv_convert_encap(encap_data, buf, &size, + error, 0); if (convert_result) return NULL; encap_verb = mlx5_glue->dv_create_flow_action_packet_reformat @@ -396,12 +409,13 @@ MLX5DV_FLOW_TABLE_TYPE_NIC_TX); if (!encap_verb) rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, - NULL, "cannot create vxlan encap action"); + NULL, "cannot create L2 encap action"); return encap_verb; } /** - * Convert VXLAN decap action to DV specification. + * Convert L2 decap action to DV specification. + * Used for VXLAN and NVGRE decap actions. * * @param[in] dev * Pointer to rte_eth_dev structure. @@ -414,9 +428,9 @@ * Pointer to action on success, NULL otherwise and rte_errno is set. */ static struct ibv_flow_action * -flow_dv_create_vxlan_decap(struct rte_eth_dev *dev, - const struct rte_flow_action *action __rte_unused, - struct rte_flow_error *error) +flow_dv_create_l2_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; @@ -683,21 +697,29 @@ ++actions_n; break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: - ret = flow_dv_validate_action_vxlan_encap(action_flags, - actions, attr, - error); + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + ret = flow_dv_validate_action_l2_encap(action_flags, + actions, attr, + error); if (ret < 0) return ret; - action_flags |= MLX5_FLOW_ACTION_VXLAN_ENCAP; + action_flags |= (actions->type == + RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) ? + MLX5_FLOW_ACTION_VXLAN_ENCAP : + MLX5_FLOW_ACTION_NVGRE_ENCAP; ++actions_n; break; case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: - ret = flow_dv_validate_action_vxlan_decap(action_flags, - actions, attr, - error); + case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: + ret = flow_dv_validate_action_l2_decap(action_flags, + actions, attr, + error); if (ret < 0) return ret; - action_flags |= MLX5_FLOW_ACTION_VXLAN_DECAP; + action_flags |= (actions->type == + RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) ? + MLX5_FLOW_ACTION_VXLAN_DECAP : + MLX5_FLOW_ACTION_NVGRE_DECAP; ++actions_n; break; default: @@ -1473,27 +1495,35 @@ flow->actions |= MLX5_FLOW_ACTION_RSS; break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; dev_flow->dv.actions[actions_n].action = - flow_dv_create_vxlan_encap(dev, action, error); + flow_dv_create_l2_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_VXLAN_ENCAP; + flow->actions |= + (action->type == RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ? + MLX5_FLOW_ACTION_VXLAN_ENCAP : + MLX5_FLOW_ACTION_NVGRE_ENCAP); actions_n++; break; case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; dev_flow->dv.actions[actions_n].action = - flow_dv_create_vxlan_decap(dev, action, error); + flow_dv_create_l2_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_VXLAN_DECAP; + flow->actions |= + (action->type == RTE_FLOW_ACTION_TYPE_VXLAN_DECAP ? + MLX5_FLOW_ACTION_VXLAN_DECAP : + MLX5_FLOW_ACTION_NVGRE_DECAP); actions_n++; break; default: