From patchwork Mon Sep 9 15:56:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59039 X-Patchwork-Delegate: rasland@nvidia.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 482DE1ED90; Mon, 9 Sep 2019 17:57:01 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 9DB331ED64 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:43 +0300 Message-Id: <722c53ed070c19d562e75eb76c6d1ab873597ea8.1567951422.git.motih@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 1/7] net/mlx5: support for an action search in a list 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 commit adds a helper routine that supports searching for a specific action in a list of actions. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow.c | 23 +++++++++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 78cc06f..eb36052 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -697,6 +697,29 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, } /* + * return a pointer to the desired action in the list of actions. + * + * @param[in] actions + * The list of actions to search the action in. + * @param[in] action + * The action to find. + * + * @return + * Pointer to the action in the list, if found. NULL otherwise. + */ +const struct rte_flow_action * +mlx5_flow_find_action(const struct rte_flow_action *actions, + enum rte_flow_action_type action) +{ + if (actions == NULL) + return NULL; + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) + if (actions->type == action) + return actions; + return NULL; +} + +/* * Validate the flag action. * * @param[in] action_flags diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 822ff36..8d193b6 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -442,6 +442,9 @@ uint64_t mlx5_flow_hashfields_adjust(struct mlx5_flow *dev_flow, int tunnel, uint64_t hash_fields); uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, uint32_t subpriority); +const struct rte_flow_action *mlx5_flow_find_action + (const struct rte_flow_action *actions, + enum rte_flow_action_type action); int mlx5_flow_validate_action_count(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, struct rte_flow_error *error); From patchwork Mon Sep 9 15:56:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59038 X-Patchwork-Delegate: rasland@nvidia.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 ECFDD1ED7C; Mon, 9 Sep 2019 17:56:58 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 872821ECE9 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:44 +0300 Message-Id: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 2/7] net/mlx5: add VLAN push/pop DR commands 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 commit adds the mlx5dv VLAN push and pop commands to mlx5_glue interface. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/Makefile | 5 +++++ drivers/net/mlx5/meson.build | 2 ++ drivers/net/mlx5/mlx5_glue.c | 29 +++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_glue.h | 6 ++++++ 4 files changed, 42 insertions(+) diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 9f6a7b4..d89a7b5 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -164,6 +164,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum MLX5DV_DR_DOMAIN_TYPE_FDB \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR_VLAN \ + infiniband/mlx5dv.h \ + func mlx5dv_dr_action_create_push_vlan \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_IBV_DEVX_OBJ \ infiniband/mlx5dv.h \ func mlx5dv_devx_obj_create \ diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index 3072c44..fb764fa 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -132,6 +132,8 @@ if build 'MLX5DV_DR_DOMAIN_TYPE_NIC_RX' ], [ 'HAVE_MLX5DV_DR_ESWITCH', 'infiniband/mlx5dv.h', 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], + [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_push_vlan' ], [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', 'SUPPORTED_40000baseKR4_Full' ], [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c index 50c369a..9ee37f4 100644 --- a/drivers/net/mlx5/mlx5_glue.c +++ b/drivers/net/mlx5/mlx5_glue.c @@ -415,6 +415,31 @@ } static void * +mlx5_glue_dr_create_flow_action_push_vlan(struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_push_vlan(domain, vlan_tag); +#else + (void)domain; + (void)vlan_tag; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_pop_vlan(void) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_pop_vlan(); +#else + errno = ENOTSUP; + return NULL; +#endif +} + +static void * mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level) { #ifdef HAVE_MLX5DV_DR @@ -1016,6 +1041,10 @@ mlx5_glue_dr_create_flow_action_dest_vport, .dr_create_flow_action_drop = mlx5_glue_dr_create_flow_action_drop, + .dr_create_flow_action_push_vlan = + mlx5_glue_dr_create_flow_action_push_vlan, + .dr_create_flow_action_pop_vlan = + mlx5_glue_dr_create_flow_action_pop_vlan, .dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl, .dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl, .dr_create_domain = mlx5_glue_dr_create_domain, diff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h index 6b5dadf..82d6b10 100644 --- a/drivers/net/mlx5/mlx5_glue.h +++ b/drivers/net/mlx5/mlx5_glue.h @@ -9,6 +9,8 @@ #include #include +#include "rte_byteorder.h" + /* Verbs headers do not support -pedantic. */ #ifdef PEDANTIC #pragma GCC diagnostic ignored "-Wpedantic" @@ -156,6 +158,10 @@ struct mlx5_glue { void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); void *(*dr_create_flow_action_dest_vport)(void *domain, uint32_t vport); void *(*dr_create_flow_action_drop)(); + void *(*dr_create_flow_action_push_vlan) + (struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag); + void *(*dr_create_flow_action_pop_vlan)(); void *(*dr_create_flow_tbl)(void *domain, uint32_t level); int (*dr_destroy_flow_tbl)(void *tbl); void *(*dr_create_domain)(struct ibv_context *ctx, From patchwork Mon Sep 9 15:56:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59037 X-Patchwork-Delegate: rasland@nvidia.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 A15831ED69; Mon, 9 Sep 2019 17:56:56 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 944111ED02 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:45 +0300 Message-Id: <734d78cf0f69ef27150d086dc7853f0cbf53be9b.1567951423.git.motih@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 3/7] net/mlx5: support pop flow action on VLAN header 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 commit adds support for RTE_FLOW_ACTION_TYPE_OF_POP_VLAN via direct verbs flow rules. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko --- doc/guides/nics/mlx5.rst | 10 +++++ doc/guides/rel_notes/release_19_11.rst | 6 +++ drivers/net/mlx5/mlx5.c | 9 ++++ drivers/net/mlx5/mlx5.h | 2 + drivers/net/mlx5/mlx5_flow.h | 5 ++- drivers/net/mlx5/mlx5_flow_dv.c | 78 ++++++++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 4115520..2ae2e8f 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -124,6 +124,12 @@ Limitations Will match any ipv4 packet (VLAN included). +- VLAN pop offload command: + + - Flow rules having a VLAN pop offload command as one of their actions and + are lacking a match on VLAN as one of their items are not supported. + - The command is not supported on egress traffic. + - A multi segment packet must have not more segments than reported by dev_infos_get() in tx_desc_lim.nb_seg_max field. This value depends on maximal supported Tx descriptor size and ``txq_inline_min`` settings and may be from 2 (worst case forced by maximal @@ -1032,6 +1038,10 @@ Supported hardware offloads | | | rdma-core 24 | | N/A | | | | ConnectX-5 | | N/A | +-----------------------+-----------------+-----------------+ + | | VLAN | | DPDK 19.11 | | DPDK 19.11 | + | | (of_pop_vlan) | | OFED 4.6-4 | | OFED 4.6-4 | + | | | ConnectX-5 | | ConnectX-5 | + +-----------------------+-----------------+-----------------+ Notes for testpmd ----------------- diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 27cfbd9..5c2ac15 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -223,3 +223,9 @@ Tested Platforms Also, make sure to start the actual text at the margin. ========================================================= +* **Updated Mellanox mlx5 driver.** + + Updated Mellanox mlx5 driver with new features and improvements, including: + + * Added support for VLAN pop flow offload command. + diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index dc7b10b..8e10932 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -549,6 +549,7 @@ struct mlx5_dev_spawn_data { sh->esw_drop_action = mlx5_glue->dr_create_flow_action_drop(); } #endif + sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan(); sh->dv_refcnt++; priv->dr_shared = 1; return 0; @@ -571,6 +572,10 @@ struct mlx5_dev_spawn_data { mlx5_glue->destroy_flow_action(sh->esw_drop_action); sh->esw_drop_action = NULL; } + if (sh->pop_vlan_action) { + mlx5_glue->destroy_flow_action(sh->pop_vlan_action); + sh->pop_vlan_action = NULL; + } return err; #else (void)priv; @@ -616,6 +621,10 @@ struct mlx5_dev_spawn_data { sh->esw_drop_action = NULL; } #endif + if (sh->pop_vlan_action) { + mlx5_glue->destroy_flow_action(sh->pop_vlan_action); + sh->pop_vlan_action = NULL; + } pthread_mutex_destroy(&sh->dv_mutex); #else (void)priv; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 09ca4b1..a18f588 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -570,6 +570,8 @@ struct mlx5_ibv_shared { struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES]; /* TX Direct Rules tables. */ void *esw_drop_action; /* Pointer to DR E-Switch drop action. */ + void *pop_vlan_action; /* Pointer to DR pop VLAN action. */ + /* TX Direct Rules tables/ */ LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers; LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps; LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 8d193b6..06b0470 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -154,7 +154,8 @@ #define MLX5_FLOW_DECAP_ACTIONS (MLX5_FLOW_ACTION_VXLAN_DECAP | \ MLX5_FLOW_ACTION_NVGRE_DECAP | \ - MLX5_FLOW_ACTION_RAW_DECAP) + MLX5_FLOW_ACTION_RAW_DECAP | \ + MLX5_FLOW_ACTION_OF_POP_VLAN) #define MLX5_FLOW_MODIFY_HDR_ACTIONS (MLX5_FLOW_ACTION_SET_IPV4_SRC | \ MLX5_FLOW_ACTION_SET_IPV4_DST | \ @@ -171,6 +172,8 @@ MLX5_FLOW_ACTION_INC_TCP_ACK | \ MLX5_FLOW_ACTION_DEC_TCP_ACK) +#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN) + #ifndef IPPROTO_MPLS #define IPPROTO_MPLS 137 #endif diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 7b2ba07..fd2e810 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -815,6 +815,61 @@ struct field_modify_info modify_tcp[] = { } /** + * Validate the pop VLAN action. + * + * @param[in] action_flags + * Holds the actions detected until now. + * @param[in] action + * Pointer to the pop vlan action. + * @param[in] item_flags + * The items found in this flow rule. + * @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_errno is set. + */ +static int +flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, + uint64_t action_flags, + const struct rte_flow_action *action, + uint64_t item_flags, + const struct rte_flow_attr *attr, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + + (void)action; + (void)attr; + if (!priv->sh->pop_vlan_action) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "pop vlan action is not supported"); + /* + * Check for inconsistencies: + * fail strip_vlan in a flow that matches packets without VLAN tags. + * fail strip_vlan in a flow that matches packets without explicitly a + * matching on VLAN tag ? + */ + if (action_flags & MLX5_FLOW_ACTION_OF_POP_VLAN) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "no support for multiple vlan pop " + "actions"); + if (!(item_flags & MLX5_FLOW_LAYER_OUTER_VLAN)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "cannot pop vlan without a " + "match on (outer) vlan in the flow"); + return 0; +} + +/** * Validate count action. * * @param[in] dev @@ -3109,6 +3164,16 @@ struct field_modify_info modify_tcp[] = { action_flags |= MLX5_FLOW_ACTION_COUNT; ++actions_n; break; + case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: + if (flow_dv_validate_action_pop_vlan(dev, + action_flags, + actions, + item_flags, attr, + error)) + return -rte_errno; + action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; + ++actions_n; + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: ret = flow_dv_validate_action_l2_encap(action_flags, @@ -3283,6 +3348,13 @@ struct field_modify_info modify_tcp[] = { "action not supported"); } } + if ((action_flags & MLX5_FLOW_LAYER_TUNNEL) && + (action_flags & MLX5_FLOW_VLAN_ACTIONS)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + actions, + "can't have vxlan and vlan" + " actions in the same rule"); /* Eswitch has few restrictions on using items and actions */ if (attr->transfer) { if (action_flags & MLX5_FLOW_ACTION_FLAG) @@ -4801,6 +4873,12 @@ struct field_modify_info modify_tcp[] = { action, "cannot create counter" " object."); + break; + case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: + dev_flow->dv.actions[actions_n++] = + priv->sh->pop_vlan_action; + action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: if (flow_dv_create_action_l2_encap(dev, actions, From patchwork Mon Sep 9 15:56:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59040 X-Patchwork-Delegate: rasland@nvidia.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 0AA601ED9C; Mon, 9 Sep 2019 17:57:05 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 9B1DE1ED61 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:46 +0300 Message-Id: <8a16a03ca4e01cbd915588ca1a0c3c2c32cfac7d.1567951423.git.motih@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 4/7] net/mlx5: support push flow action on VLAN header 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 commit adds support for RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN using direct verbs flow rules. If present in the flow, The VLAN default values are taken from the VLAN item configuration. In this commit only the VLAN TPID value can be set since VLAN modification actions are not supported yet. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko --- v5: - Fixed bug in retrieving VLAN VID and PCP from the existing VLAN flow item. --- doc/guides/nics/mlx5.rst | 6 +- doc/guides/rel_notes/release_19_11.rst | 1 + drivers/net/mlx5/mlx5.h | 2 + drivers/net/mlx5/mlx5_flow.h | 18 ++- drivers/net/mlx5/mlx5_flow_dv.c | 272 +++++++++++++++++++++++++++++++++ 5 files changed, 295 insertions(+), 4 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 2ae2e8f..875a87f 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -130,6 +130,8 @@ Limitations are lacking a match on VLAN as one of their items are not supported. - The command is not supported on egress traffic. +- VLAN push offload is not supported on ingress traffic. + - A multi segment packet must have not more segments than reported by dev_infos_get() in tx_desc_lim.nb_seg_max field. This value depends on maximal supported Tx descriptor size and ``txq_inline_min`` settings and may be from 2 (worst case forced by maximal @@ -1039,8 +1041,8 @@ Supported hardware offloads | | | ConnectX-5 | | N/A | +-----------------------+-----------------+-----------------+ | | VLAN | | DPDK 19.11 | | DPDK 19.11 | - | | (of_pop_vlan) | | OFED 4.6-4 | | OFED 4.6-4 | - | | | ConnectX-5 | | ConnectX-5 | + | | (of_pop_vlan / | | OFED 4.6-4 | | OFED 4.6-4 | + | | of_push_vlan) | | ConnectX-5 | | ConnectX-5 | +-----------------------+-----------------+-----------------+ Notes for testpmd diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 5c2ac15..afe92ab 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -228,4 +228,5 @@ Tested Platforms Updated Mellanox mlx5 driver with new features and improvements, including: * Added support for VLAN pop flow offload command. + * Added support for VLAN push flow offload command. diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index a18f588..dbdc3ce 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -579,6 +579,8 @@ struct mlx5_ibv_shared { LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl; LIST_HEAD(port_id_action_list, mlx5_flow_dv_port_id_action_resource) port_id_action_list; /* List of port ID actions. */ + LIST_HEAD(push_vlan_action_list, mlx5_flow_dv_push_vlan_action_resource) + push_vlan_action_list; /* List of push VLAN actions. */ struct mlx5_flow_counter_mng cmng; /* Counters management structure. */ /* Shared interrupt handler section. */ pthread_mutex_t intr_mutex; /* Interrupt config mutex. */ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 06b0470..15c9c04 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -150,7 +150,8 @@ #define MLX5_FLOW_ENCAP_ACTIONS (MLX5_FLOW_ACTION_VXLAN_ENCAP | \ MLX5_FLOW_ACTION_NVGRE_ENCAP | \ - MLX5_FLOW_ACTION_RAW_ENCAP) + MLX5_FLOW_ACTION_RAW_ENCAP | \ + MLX5_FLOW_ACTION_OF_PUSH_VLAN) #define MLX5_FLOW_DECAP_ACTIONS (MLX5_FLOW_ACTION_VXLAN_DECAP | \ MLX5_FLOW_ACTION_NVGRE_DECAP | \ @@ -172,7 +173,8 @@ MLX5_FLOW_ACTION_INC_TCP_ACK | \ MLX5_FLOW_ACTION_DEC_TCP_ACK) -#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN) +#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN | \ + MLX5_FLOW_ACTION_OF_PUSH_VLAN) #ifndef IPPROTO_MPLS #define IPPROTO_MPLS 137 @@ -309,6 +311,16 @@ struct mlx5_flow_dv_port_id_action_resource { uint32_t port_id; /**< Port ID value. */ }; +/* Push VLAN action resource structure */ +struct mlx5_flow_dv_push_vlan_action_resource { + LIST_ENTRY(mlx5_flow_dv_push_vlan_action_resource) next; + /* Pointer to next element. */ + rte_atomic32_t refcnt; /**< Reference counter. */ + void *action; /**< Direct verbs action object. */ + uint8_t ft_type; /**< Flow table type, Rx, Tx or FDB. */ + rte_be32_t vlan_tag; /**< VLAN tag value. */ +}; + /* * Max number of actions per DV flow. * See CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED @@ -335,6 +347,8 @@ struct mlx5_flow_dv { /**< Pointer to port ID action resource. */ struct mlx5_vf_vlan vf_vlan; /**< Structure for VF VLAN workaround. */ + struct mlx5_flow_dv_push_vlan_action_resource *push_vlan_res; + /**< Pointer to push VLAN action resource in cache. */ #ifdef HAVE_IBV_FLOW_DV_SUPPORT void *actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS]; /**< Action list. */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index fd2e810..2780735 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -50,6 +50,13 @@ #define MLX5DV_DR_ACTION_FLAGS_ROOT_LEVEL 1 #endif +/* VLAN header definitions */ +#define MLX5DV_FLOW_VLAN_PCP_SHIFT 13 +#define MLX5DV_FLOW_VLAN_PCP_MASK (0x7 << MLX5DV_FLOW_VLAN_PCP_SHIFT) +#define MLX5DV_FLOW_VLAN_VID_MASK 0x0fff +#define MLX5DV_FLOW_VLAN_PCP_MASK_BE RTE_BE16(MLX5DV_FLOW_VLAN_PCP_MASK) +#define MLX5DV_FLOW_VLAN_VID_MASK_BE RTE_BE16(MLX5DV_FLOW_VLAN_VID_MASK) + union flow_dv_attr { struct { uint32_t valid:1; @@ -817,6 +824,8 @@ struct field_modify_info modify_tcp[] = { /** * Validate the pop VLAN action. * + * @param[in] dev + * Pointer to the rte_eth_dev structure. * @param[in] action_flags * Holds the actions detected until now. * @param[in] action @@ -870,6 +879,101 @@ struct field_modify_info modify_tcp[] = { } /** + * Get VLAN default info from vlan match info. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] item + * the list of item specifications. + * @param[out] vlan + * pointer VLAN info to fill to. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static void +flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, + struct rte_vlan_hdr *vlan) +{ + const struct rte_flow_item_vlan nic_mask = { + .tci = RTE_BE16(MLX5DV_FLOW_VLAN_PCP_MASK | + MLX5DV_FLOW_VLAN_VID_MASK), + .inner_type = RTE_BE16(0xffff), + }; + + if (items == NULL) + return; + for (; items->type != RTE_FLOW_ITEM_TYPE_END && + items->type != RTE_FLOW_ITEM_TYPE_VLAN; items++) + ; + if (items->type == RTE_FLOW_ITEM_TYPE_VLAN) { + const struct rte_flow_item_vlan *vlan_m = items->mask; + const struct rte_flow_item_vlan *vlan_v = items->spec; + + if (!vlan_m) + vlan_m = &nic_mask; + /* Only full match values are accepted */ + if ((vlan_m->tci & MLX5DV_FLOW_VLAN_PCP_MASK_BE) == + MLX5DV_FLOW_VLAN_PCP_MASK_BE) { + vlan->vlan_tci &= MLX5DV_FLOW_VLAN_PCP_MASK; + vlan->vlan_tci |= + rte_be_to_cpu_16(vlan_v->tci & + MLX5DV_FLOW_VLAN_PCP_MASK_BE); + } + if ((vlan_m->tci & MLX5DV_FLOW_VLAN_VID_MASK_BE) == + MLX5DV_FLOW_VLAN_VID_MASK_BE) { + vlan->vlan_tci &= ~MLX5DV_FLOW_VLAN_VID_MASK; + vlan->vlan_tci |= + rte_be_to_cpu_16(vlan_v->tci & + MLX5DV_FLOW_VLAN_VID_MASK_BE); + } + if (vlan_m->inner_type == nic_mask.inner_type) + vlan->eth_proto = rte_be_to_cpu_16(vlan_v->inner_type & + vlan_m->inner_type); + } +} + +/** + * Validate the push VLAN 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_errno is set. + */ +static int +flow_dv_validate_action_push_vlan(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_of_push_vlan *push_vlan = action->conf; + + if (push_vlan->ethertype != RTE_BE16(RTE_ETHER_TYPE_VLAN) && + push_vlan->ethertype != RTE_BE16(RTE_ETHER_TYPE_QINQ)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "invalid vlan ethertype"); + if (action_flags & + (MLX5_FLOW_ACTION_OF_POP_VLAN | MLX5_FLOW_ACTION_OF_PUSH_VLAN)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "no support for multiple VLAN " + "actions"); + (void)attr; + return 0; +} + +/** * Validate count action. * * @param[in] dev @@ -1300,6 +1404,77 @@ struct field_modify_info modify_tcp[] = { } /** + * Find existing push vlan resource or create and register a new one. + * + * @param dev[in, out] + * Pointer to rte_eth_dev structure. + * @param[in, out] resource + * Pointer to port ID action resource. + * @parm[in, out] dev_flow + * Pointer to the dev_flow. + * @param[out] error + * pointer to error structure. + * + * @return + * 0 on success otherwise -errno and errno is set. + */ +static int +flow_dv_push_vlan_action_resource_register + (struct rte_eth_dev *dev, + struct mlx5_flow_dv_push_vlan_action_resource *resource, + struct mlx5_flow *dev_flow, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_ibv_shared *sh = priv->sh; + struct mlx5_flow_dv_push_vlan_action_resource *cache_resource; + struct mlx5dv_dr_domain *domain; + + /* Lookup a matching resource from cache. */ + LIST_FOREACH(cache_resource, &sh->push_vlan_action_list, next) { + if (resource->vlan_tag == cache_resource->vlan_tag && + resource->ft_type == cache_resource->ft_type) { + DRV_LOG(DEBUG, "push-VLAN action resource resource %p: " + "refcnt %d++", + (void *)cache_resource, + rte_atomic32_read(&cache_resource->refcnt)); + rte_atomic32_inc(&cache_resource->refcnt); + dev_flow->dv.push_vlan_res = cache_resource; + return 0; + } + } + /* Register new push_vlan action resource. */ + cache_resource = rte_calloc(__func__, 1, sizeof(*cache_resource), 0); + if (!cache_resource) + return rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "cannot allocate resource memory"); + *cache_resource = *resource; + if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB) + domain = sh->fdb_domain; + else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_RX) + domain = sh->rx_domain; + else + domain = sh->tx_domain; + cache_resource->action = + mlx5_glue->dr_create_flow_action_push_vlan(domain, + resource->vlan_tag); + if (!cache_resource->action) { + rte_free(cache_resource); + return rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "cannot create action"); + } + rte_atomic32_init(&cache_resource->refcnt); + rte_atomic32_inc(&cache_resource->refcnt); + LIST_INSERT_HEAD(&sh->push_vlan_action_list, cache_resource, next); + dev_flow->dv.push_vlan_res = cache_resource; + DRV_LOG(DEBUG, "new push vlan action resource %p: refcnt %d++", + (void *)cache_resource, + rte_atomic32_read(&cache_resource->refcnt)); + return 0; +} +/** * Get the size of specific rte_flow_item_type * * @param[in] item_type @@ -1719,6 +1894,44 @@ struct field_modify_info modify_tcp[] = { } /** + * Create action push VLAN. + * + * @param[in] dev + * Pointer to rte_eth_dev structure. + * @param[in] vlan_tag + * the vlan tag to push to the Ethernet header. + * @param[in, out] dev_flow + * Pointer to the mlx5_flow. + * @param[in] attr + * Pointer to the flow attributes. + * @param[out] error + * Pointer to the error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_dv_create_action_push_vlan(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_vlan_hdr *vlan, + struct mlx5_flow *dev_flow, + struct rte_flow_error *error) +{ + struct mlx5_flow_dv_push_vlan_action_resource res; + + res.vlan_tag = + rte_cpu_to_be_32(((uint32_t)vlan->eth_proto) << 16 | + vlan->vlan_tci); + if (attr->transfer) + res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB; + else + res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX : + MLX5DV_FLOW_TABLE_TYPE_NIC_RX; + return flow_dv_push_vlan_action_resource_register + (dev, &res, dev_flow, error); +} + +/** * Validate the modify-header actions. * * @param[in] action_flags @@ -3174,6 +3387,15 @@ struct field_modify_info modify_tcp[] = { action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; ++actions_n; break; + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: + ret = flow_dv_validate_action_push_vlan(action_flags, + actions, attr, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN; + ++actions_n; + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: ret = flow_dv_validate_action_l2_encap(action_flags, @@ -4765,6 +4987,8 @@ struct field_modify_info modify_tcp[] = { void *match_mask = matcher.mask.buf; void *match_value = dev_flow->dv.value.buf; uint8_t next_protocol = 0xff; + struct rte_vlan_hdr vlan = { 0 }; + bool vlan_inherited = false; flow->group = attr->group; if (attr->transfer) @@ -4879,6 +5103,21 @@ struct field_modify_info modify_tcp[] = { priv->sh->pop_vlan_action; action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; break; + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: + if (!vlan_inherited) { + flow_dev_get_vlan_info_from_items(items, &vlan); + vlan_inherited = true; + } + vlan.eth_proto = rte_be_to_cpu_16 + ((((const struct rte_flow_action_of_push_vlan *) + actions->conf)->ethertype)); + if (flow_dv_create_action_push_vlan + (dev, attr, &vlan, dev_flow, error)) + return -rte_errno; + dev_flow->dv.actions[actions_n++] = + dev_flow->dv.push_vlan_res->action; + action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN; + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: if (flow_dv_create_action_l2_encap(dev, actions, @@ -5526,6 +5765,37 @@ struct field_modify_info modify_tcp[] = { } /** + * Release push vlan action resource. + * + * @param flow + * Pointer to mlx5_flow. + * + * @return + * 1 while a reference on it exists, 0 when freed. + */ +static int +flow_dv_push_vlan_action_resource_release(struct mlx5_flow *flow) +{ + struct mlx5_flow_dv_push_vlan_action_resource *cache_resource = + flow->dv.push_vlan_res; + + assert(cache_resource->action); + DRV_LOG(DEBUG, "push VLAN action resource %p: refcnt %d--", + (void *)cache_resource, + rte_atomic32_read(&cache_resource->refcnt)); + if (rte_atomic32_dec_and_test(&cache_resource->refcnt)) { + claim_zero(mlx5_glue->destroy_flow_action + (cache_resource->action)); + LIST_REMOVE(cache_resource, next); + rte_free(cache_resource); + DRV_LOG(DEBUG, "push vlan action resource %p: removed", + (void *)cache_resource); + return 0; + } + return 1; +} + +/** * Remove the flow from the NIC but keeps it in memory. * * @param[in] dev @@ -5597,6 +5867,8 @@ struct field_modify_info modify_tcp[] = { flow_dv_jump_tbl_resource_release(dev_flow); if (dev_flow->dv.port_id_action) flow_dv_port_id_action_resource_release(dev_flow); + if (dev_flow->dv.push_vlan_res) + flow_dv_push_vlan_action_resource_release(dev_flow); rte_free(dev_flow); } } From patchwork Mon Sep 9 15:56:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59042 X-Patchwork-Delegate: rasland@nvidia.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 4151B1EDB6; Mon, 9 Sep 2019 17:57:11 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id F33A21ED66 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:47 +0300 Message-Id: <672cb17b8fd1c7171bb2714840124de51c004fd0.1567951423.git.motih@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 5/7] net/mlx5: support modify VLAN priority on VLAN hdr 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 commit adds support for modifying the VLAN priority (PCP) field in about-to-be-pushed VLAN header. This feature can only modify the PCP field of a new VLAN header yet to be pushed. It does not support modifying an existing or already pushed VLAN headers. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko Acked-by: Viacheslav Ovsiienko --- v4: - Fixed typo in an error message. --- doc/guides/nics/mlx5.rst | 5 ++- doc/guides/rel_notes/release_19_11.rst | 1 + drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 875a87f..01215f4 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -132,6 +132,8 @@ Limitations - VLAN push offload is not supported on ingress traffic. +- VLAN set PCP offload is not supported on existing headers. + - A multi segment packet must have not more segments than reported by dev_infos_get() in tx_desc_lim.nb_seg_max field. This value depends on maximal supported Tx descriptor size and ``txq_inline_min`` settings and may be from 2 (worst case forced by maximal @@ -1042,7 +1044,8 @@ Supported hardware offloads +-----------------------+-----------------+-----------------+ | | VLAN | | DPDK 19.11 | | DPDK 19.11 | | | (of_pop_vlan / | | OFED 4.6-4 | | OFED 4.6-4 | - | | of_push_vlan) | | ConnectX-5 | | ConnectX-5 | + | | of_push_vlan / | | ConnectX-5 | | ConnectX-5 | + | | of_set_vlan_pcp) | | | +-----------------------+-----------------+-----------------+ Notes for testpmd diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index afe92ab..5067a1c 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -229,4 +229,5 @@ Tested Platforms * Added support for VLAN pop flow offload command. * Added support for VLAN push flow offload command. + * Added support for VLAN set PCP offload command. diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 2780735..73459a0 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -974,6 +974,47 @@ struct field_modify_info modify_tcp[] = { } /** + * Validate the set VLAN PCP. + * + * @param[in] action_flags + * Holds the actions detected until now. + * @param[in] actions + * Pointer to the list of actions remaining in the flow rule. + * @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_errno is set. + */ +static int +flow_dv_validate_action_set_vlan_pcp(uint64_t action_flags, + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + const struct rte_flow_action *action = actions; + const struct rte_flow_action_of_set_vlan_pcp *conf = action->conf; + + if (conf->vlan_pcp > 7) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "VLAN PCP value is too big"); + if (mlx5_flow_find_action(actions, + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN) == NULL) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "set VLAN PCP can only be used " + "with push VLAN action"); + if (action_flags & MLX5_FLOW_ACTION_OF_PUSH_VLAN) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "set VLAN PCP action must precede " + "the push VLAN action"); + return 0; +} + +/** * Validate count action. * * @param[in] dev @@ -3396,6 +3437,13 @@ struct field_modify_info modify_tcp[] = { action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN; ++actions_n; break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: + ret = flow_dv_validate_action_set_vlan_pcp + (action_flags, actions, error); + if (ret < 0) + return ret; + /* Count PCP with push_vlan command. */ + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: ret = flow_dv_validate_action_l2_encap(action_flags, @@ -4989,6 +5037,7 @@ struct field_modify_info modify_tcp[] = { uint8_t next_protocol = 0xff; struct rte_vlan_hdr vlan = { 0 }; bool vlan_inherited = false; + uint16_t vlan_tci; flow->group = attr->group; if (attr->transfer) @@ -5118,6 +5167,19 @@ struct field_modify_info modify_tcp[] = { dev_flow->dv.push_vlan_res->action; action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN; break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: + if (!vlan_inherited) { + flow_dev_get_vlan_info_from_items(items, &vlan); + vlan_inherited = true; + } + vlan_tci = + ((const struct rte_flow_action_of_set_vlan_pcp *) + actions->conf)->vlan_pcp; + vlan_tci = vlan_tci << MLX5DV_FLOW_VLAN_PCP_SHIFT; + vlan.vlan_tci &= ~MLX5DV_FLOW_VLAN_PCP_MASK; + vlan.vlan_tci |= vlan_tci; + /* Push VLAN command will use this value */ + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: if (flow_dv_create_action_l2_encap(dev, actions, From patchwork Mon Sep 9 15:56:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59043 X-Patchwork-Delegate: rasland@nvidia.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 096591EDC3; Mon, 9 Sep 2019 17:57:14 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 005F71ED68 for ; Mon, 9 Sep 2019 17:56:53 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:48 +0300 Message-Id: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 6/7] net/mlx5: supp modify VLAN ID on new VLAN header 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 commit adds support for modifying the VLAN ID (VID) field in an about-to-be-pushed VLAN header. This feature can only modify the VID field of a new VLAN header yet to be pushed. It does not support modifying an existing or already pushed VLAN headers. Signed-off-by: Moti Haimovsky --- v4: - Fixed typo in an error message. - Fixed bug in verifying VLAN VID value, used 0xFFFE instead of 0xFFE. --- doc/guides/nics/mlx5.rst | 5 ++- doc/guides/rel_notes/release_19_11.rst | 1 + drivers/net/mlx5/mlx5_flow_dv.c | 59 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 01215f4..3a2a366 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -134,6 +134,8 @@ Limitations - VLAN set PCP offload is not supported on existing headers. +- VLAN set VID offload is not supported on existing headers. + - A multi segment packet must have not more segments than reported by dev_infos_get() in tx_desc_lim.nb_seg_max field. This value depends on maximal supported Tx descriptor size and ``txq_inline_min`` settings and may be from 2 (worst case forced by maximal @@ -1045,7 +1047,8 @@ Supported hardware offloads | | VLAN | | DPDK 19.11 | | DPDK 19.11 | | | (of_pop_vlan / | | OFED 4.6-4 | | OFED 4.6-4 | | | of_push_vlan / | | ConnectX-5 | | ConnectX-5 | - | | of_set_vlan_pcp) | | | + | | of_set_vlan_pcp / | | | + | | of_set_vlan_vid) | | | +-----------------------+-----------------+-----------------+ Notes for testpmd diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 5067a1c..66297d8 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -230,4 +230,5 @@ Tested Platforms * Added support for VLAN pop flow offload command. * Added support for VLAN push flow offload command. * Added support for VLAN set PCP offload command. + * Added support for VLAN set VID offload command. diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 73459a0..4b68aa6 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1015,6 +1015,47 @@ struct field_modify_info modify_tcp[] = { } /** + * Validate the set VLAN VID. + * + * @param[in] action_flags + * Holds the actions detected until now. + * @param[in] actions + * Pointer to the list of actions remaining in the flow rule. + * @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_errno is set. + */ +static int +flow_dv_validate_action_set_vlan_vid(uint64_t action_flags, + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + const struct rte_flow_action *action = actions; + const struct rte_flow_action_of_set_vlan_vid *conf = action->conf; + + if (conf->vlan_vid > RTE_BE16(0xFFE)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "VLAN VID value is too big"); + if (mlx5_flow_find_action(actions, + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN) == NULL) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "set VLAN VID can only be used " + "with push VLAN action"); + if (action_flags & MLX5_FLOW_ACTION_OF_PUSH_VLAN) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "set VLAN VID action must precede " + "the push VLAN action"); + return 0; +} + +/** * Validate count action. * * @param[in] dev @@ -3444,6 +3485,13 @@ struct field_modify_info modify_tcp[] = { return ret; /* Count PCP with push_vlan command. */ break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: + ret = flow_dv_validate_action_set_vlan_vid + (action_flags, actions, error); + if (ret < 0) + return ret; + /* Count VID with push_vlan command. */ + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: ret = flow_dv_validate_action_l2_encap(action_flags, @@ -5180,6 +5228,17 @@ struct field_modify_info modify_tcp[] = { vlan.vlan_tci |= vlan_tci; /* Push VLAN command will use this value */ break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: + if (!vlan_inherited) { + flow_dev_get_vlan_info_from_items(items, &vlan); + vlan_inherited = true; + } + vlan.vlan_tci &= ~MLX5DV_FLOW_VLAN_VID_MASK; + vlan.vlan_tci |= rte_be_to_cpu_16 + (((const struct rte_flow_action_of_set_vlan_vid *) + actions->conf)->vlan_vid); + /* Push VLAN command will use this value */ + break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: if (flow_dv_create_action_l2_encap(dev, actions, From patchwork Mon Sep 9 15:56:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 59041 X-Patchwork-Delegate: rasland@nvidia.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 B2C891EDA9; Mon, 9 Sep 2019 17:57:08 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id F3C071ED67 for ; Mon, 9 Sep 2019 17:56:52 +0200 (CEST) From: Moti Haimovsky To: viacheslavo@mellanox.com, rasland@mellanox.com Cc: dev@dpdk.org Date: Mon, 9 Sep 2019 18:56:49 +0300 Message-Id: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 7/7] net/mlx5: supp modify VLAN ID on existing VLAN hdr 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 commit adds support for modifying the VID of the outermost VLAN header already present in the packet. Signed-off-by: Moti Haimovsky Acked-by: Viacheslav Ovsiienko --- doc/guides/nics/mlx5.rst | 20 ++++----- drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 89 ++++++++++++++++++++++++++++++++++++----- drivers/net/mlx5/mlx5_prm.h | 1 + 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 3a2a366..c2e9003 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -134,8 +134,6 @@ Limitations - VLAN set PCP offload is not supported on existing headers. -- VLAN set VID offload is not supported on existing headers. - - A multi segment packet must have not more segments than reported by dev_infos_get() in tx_desc_lim.nb_seg_max field. This value depends on maximal supported Tx descriptor size and ``txq_inline_min`` settings and may be from 2 (worst case forced by maximal @@ -1021,13 +1019,17 @@ Supported hardware offloads | | (set_ipv4_src / | | OFED 4.6-2 | | OFED 4.6-2 | | | set_ipv4_dst / | | rdma-core 24 | | rdma-core 23 | | | set_ipv6_src / | | ConnectX-5 | | ConnectX-5 | - | | set_ipv6_dst / | | | - | | set_tp_src / | | | - | | set_tp_dst / | | | - | | dec_ttl / | | | - | | set_ttl / | | | - | | set_mac_src / | | | - | | set_mac_dst) | | | + | | set_ipv6_dst / | | | | | + | | set_tp_src / | | | | | + | | set_tp_dst / | | | | | + | | dec_ttl / | | | | | + | | set_ttl / | | | | | + | | set_mac_src / | | | | | + | | set_mac_dst) | | | | | + | | | | | | | + | | (of_set_vlan_vid) | | DPDK 19.11 | | DPDK 19.11 | + | | | OFED 4.6-4 | | OFED 4.6-4 | + | | | ConnectX-5 | | ConnectX-5 | +-----------------------+-----------------+-----------------+ | Jump | | DPDK 19.05 | | DPDK 19.02 | | | | OFED 4.6-4 | | OFED 4.6-4 | diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 15c9c04..95abbb8 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -171,7 +171,8 @@ MLX5_FLOW_ACTION_INC_TCP_SEQ | \ MLX5_FLOW_ACTION_DEC_TCP_SEQ | \ MLX5_FLOW_ACTION_INC_TCP_ACK | \ - MLX5_FLOW_ACTION_DEC_TCP_ACK) + MLX5_FLOW_ACTION_DEC_TCP_ACK | \ + MLX5_FLOW_ACTION_OF_SET_VLAN_VID) #define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN | \ MLX5_FLOW_ACTION_OF_PUSH_VLAN) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 4b68aa6..330a868 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -115,6 +115,12 @@ struct field_modify_info modify_eth[] = { {0, 0, 0}, }; +struct field_modify_info modify_vlan_out_first_vid[] = { + /* Size in bits !!! */ + {12, 0, MLX5_MODI_OUT_FIRST_VID}, + {0, 0, 0}, +}; + struct field_modify_info modify_ipv4[] = { {1, 8, MLX5_MODI_OUT_IPV4_TTL}, {4, 12, MLX5_MODI_OUT_SIPV4}, @@ -397,6 +403,46 @@ struct field_modify_info modify_tcp[] = { } /** + * Convert modify-header set VLAN VID action to DV specification. + * + * @param[in,out] resource + * Pointer to the modify-header resource. + * @param[in] action + * Pointer to action specification. + * @param[out] error + * Pointer to the error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_dv_convert_action_modify_vlan_vid + (struct mlx5_flow_dv_modify_hdr_resource *resource, + const struct rte_flow_action *action, + struct rte_flow_error *error) +{ + const struct rte_flow_action_of_set_vlan_vid *conf = + (const struct rte_flow_action_of_set_vlan_vid *)(action->conf); + int i = resource->actions_num; + struct mlx5_modification_cmd *actions = &resource->actions[i]; + struct field_modify_info *field = modify_vlan_out_first_vid; + + if (i >= MLX5_MODIFY_NUM) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "too many items to modify"); + actions[i].action_type = MLX5_MODIFICATION_TYPE_SET; + actions[i].field = field->id; + actions[i].length = field->size; + actions[i].offset = field->offset; + actions[i].data0 = rte_cpu_to_be_32(actions[i].data0); + actions[i].data1 = conf->vlan_vid; + actions[i].data1 = actions[i].data1 << 16; + resource->actions_num = ++i; + return 0; +} + +/** * Convert modify-header set TP action to DV specification. * * @param[in,out] resource @@ -1017,8 +1063,8 @@ struct field_modify_info modify_tcp[] = { /** * Validate the set VLAN VID. * - * @param[in] action_flags - * Holds the actions detected until now. + * @param[in] item_flags + * Holds the items detected in this rule. * @param[in] actions * Pointer to the list of actions remaining in the flow rule. * @param[in] attr @@ -1030,7 +1076,7 @@ struct field_modify_info modify_tcp[] = { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_validate_action_set_vlan_vid(uint64_t action_flags, +flow_dv_validate_action_set_vlan_vid(uint64_t item_flags, const struct rte_flow_action actions[], struct rte_flow_error *error) { @@ -1041,17 +1087,27 @@ struct field_modify_info modify_tcp[] = { return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, "VLAN VID value is too big"); + /* If a push VLAN action follows then it will handle this action */ if (mlx5_flow_find_action(actions, - RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN) == NULL) + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN)) + return 0; + + /* + * Action is on an existing VLAN header: + * Need to verify this is a single modify CID action. + * Rule mast include a match on outer VLAN. + */ + if (mlx5_flow_find_action(++action, + RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID)) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, action, - "set VLAN VID can only be used " - "with push VLAN action"); - if (action_flags & MLX5_FLOW_ACTION_OF_PUSH_VLAN) - return rte_flow_error_set(error, ENOTSUP, + "Multiple VLAN VID modifications are " + "not supported"); + if (!(item_flags & MLX5_FLOW_LAYER_OUTER_VLAN)) + return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, - "set VLAN VID action must precede " - "the push VLAN action"); + "match on VLAN is required in order " + "to set VLAN VID"); return 0; } @@ -3487,7 +3543,7 @@ struct field_modify_info modify_tcp[] = { break; case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: ret = flow_dv_validate_action_set_vlan_vid - (action_flags, actions, error); + (item_flags, actions, error); if (ret < 0) return ret; /* Count VID with push_vlan command. */ @@ -5214,6 +5270,8 @@ struct field_modify_info modify_tcp[] = { dev_flow->dv.actions[actions_n++] = dev_flow->dv.push_vlan_res->action; action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN; + /* Push VLAN command is also handling this VLAN_VID */ + action_flags &= ~MLX5_FLOW_ACTION_OF_SET_VLAN_VID; break; case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: if (!vlan_inherited) { @@ -5238,6 +5296,15 @@ struct field_modify_info modify_tcp[] = { (((const struct rte_flow_action_of_set_vlan_vid *) actions->conf)->vlan_vid); /* Push VLAN command will use this value */ + if (mlx5_flow_find_action + (actions, + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN)) + break; + /* If no VLAN push - this is a modify header action */ + if (flow_dv_convert_action_modify_vlan_vid + (&res, actions, error)) + return -rte_errno; + action_flags |= MLX5_FLOW_ACTION_OF_SET_VLAN_VID; break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h index d62837e..e5afc1c 100644 --- a/drivers/net/mlx5/mlx5_prm.h +++ b/drivers/net/mlx5/mlx5_prm.h @@ -413,6 +413,7 @@ enum mlx5_modification_field { MLX5_MODI_OUT_DIPV6_31_0, MLX5_MODI_OUT_SIPV4, MLX5_MODI_OUT_DIPV4, + MLX5_MODI_OUT_FIRST_VID, MLX5_MODI_IN_SMAC_47_16 = 0x31, MLX5_MODI_IN_SMAC_15_0, MLX5_MODI_IN_ETHERTYPE,