From patchwork Fri Apr 20 12:23:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xueming Li X-Patchwork-Id: 38634 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 81A571AFF4; Fri, 20 Apr 2018 14:27:31 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 77CD6D0B2 for ; Fri, 20 Apr 2018 14:27:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Apr 2018 15:25:24 +0300 Received: from dev-r630-06.mtbc.labs.mlnx (dev-r630-06.mtbc.labs.mlnx [10.12.205.180]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w3KCO2GQ021596; Fri, 20 Apr 2018 15:24:03 +0300 Received: from dev-r630-06.mtbc.labs.mlnx (localhost [127.0.0.1]) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7) with ESMTP id w3KCO2MD113422; Fri, 20 Apr 2018 20:24:02 +0800 Received: (from xuemingl@localhost) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7/Submit) id w3KCO2sM113421; Fri, 20 Apr 2018 20:24:02 +0800 From: Xueming Li To: Iremonger Bernard , Nelio Laranjeiro , Shahaf Shuler Cc: Xueming Li , dev@dpdk.org Date: Fri, 20 Apr 2018 20:23:38 +0800 Message-Id: <20180420122340.113348-10-xuemingl@mellanox.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20180420122340.113348-1-xuemingl@mellanox.com> References: <20180420122340.113348-1-xuemingl@mellanox.com> In-Reply-To: <20180417151436.161374-1-xuemingl@mellanox.com> References: <20180417151436.161374-1-xuemingl@mellanox.com> Subject: [dpdk-dev] [PATCH v5 09/11] net/mlx5: introduce VXLAN-GPE tunnel type 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" Signed-off-by: Xueming Li Acked-by: Nelio Laranjeiro --- doc/guides/nics/mlx5.rst | 8 ++-- drivers/net/mlx5/mlx5_flow.c | 107 ++++++++++++++++++++++++++++++++++++++++++- drivers/net/mlx5/mlx5_rxtx.c | 3 +- 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 421274729..6b83759c8 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -329,16 +329,16 @@ Run-time configuration - ``l3_vxlan_en`` parameter [int] - A nonzero value allows L3 VXLAN flow creation. To enable L3 VXLAN, users - has to configure firemware and enable this prameter. This is a prerequisite - to receive this kind of traffic. + A nonzero value allows L3 VXLAN and VXLAN-GPE flow creation. To enable + L3 VXLAN or VXLAN-GPE, users has to configure firemware and enable this + prameter. This is a prerequisite to receive this kind of traffic. Disabled by default. Firmware configuration ~~~~~~~~~~~~~~~~~~~~~~ -- L3 VXLAN destination UDP port +- L3 VXLAN and VXLAN-GPE destination UDP port .. code-block:: console diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 593c960f8..a55644cd0 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -92,6 +92,11 @@ mlx5_flow_create_vxlan(const struct rte_flow_item *item, struct mlx5_flow_data *data); static int +mlx5_flow_create_vxlan_gpe(const struct rte_flow_item *item, + const void *default_mask, + struct mlx5_flow_data *data); + +static int mlx5_flow_create_gre(const struct rte_flow_item *item, const void *default_mask, struct mlx5_flow_data *data); @@ -242,10 +247,12 @@ struct rte_flow { #define IS_TUNNEL(type) ( \ (type) == RTE_FLOW_ITEM_TYPE_VXLAN || \ + (type) == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || \ (type) == RTE_FLOW_ITEM_TYPE_GRE) const uint32_t flow_ptype[] = { [RTE_FLOW_ITEM_TYPE_VXLAN] = RTE_PTYPE_TUNNEL_VXLAN, + [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = RTE_PTYPE_TUNNEL_VXLAN_GPE, [RTE_FLOW_ITEM_TYPE_GRE] = RTE_PTYPE_TUNNEL_GRE, }; @@ -254,6 +261,8 @@ const uint32_t flow_ptype[] = { const uint32_t ptype_ext[] = { [PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN)] = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP, + [PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN_GPE)] = RTE_PTYPE_TUNNEL_VXLAN_GPE | + RTE_PTYPE_L4_UDP, [PTYPE_IDX(RTE_PTYPE_TUNNEL_GRE)] = RTE_PTYPE_TUNNEL_GRE, }; @@ -311,6 +320,7 @@ static const struct mlx5_flow_items mlx5_flow_items[] = { [RTE_FLOW_ITEM_TYPE_END] = { .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_VXLAN_GPE, RTE_FLOW_ITEM_TYPE_GRE), }, [RTE_FLOW_ITEM_TYPE_ETH] = { @@ -389,7 +399,8 @@ static const struct mlx5_flow_items mlx5_flow_items[] = { .dst_sz = sizeof(struct ibv_flow_spec_ipv6), }, [RTE_FLOW_ITEM_TYPE_UDP] = { - .items = ITEMS(RTE_FLOW_ITEM_TYPE_VXLAN), + .items = ITEMS(RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_VXLAN_GPE), .actions = valid_actions, .mask = &(const struct rte_flow_item_udp){ .hdr = { @@ -441,6 +452,19 @@ static const struct mlx5_flow_items mlx5_flow_items[] = { .convert = mlx5_flow_create_vxlan, .dst_sz = sizeof(struct ibv_flow_spec_tunnel), }, + [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = { + .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_IPV6), + .actions = valid_actions, + .mask = &(const struct rte_flow_item_vxlan_gpe){ + .vni = "\xff\xff\xff", + }, + .default_mask = &rte_flow_item_vxlan_gpe_mask, + .mask_sz = sizeof(struct rte_flow_item_vxlan_gpe), + .convert = mlx5_flow_create_vxlan_gpe, + .dst_sz = sizeof(struct ibv_flow_spec_tunnel), + }, }; /** Structure to pass to the conversion function. */ @@ -1775,6 +1799,87 @@ mlx5_flow_create_vxlan(const struct rte_flow_item *item, } /** + * Convert VXLAN-GPE item to Verbs specification. + * + * @param item[in] + * Item specification. + * @param default_mask[in] + * Default bit-masks to use when item->mask is not provided. + * @param data[in, out] + * User structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_create_vxlan_gpe(const struct rte_flow_item *item, + const void *default_mask, + struct mlx5_flow_data *data) +{ + struct priv *priv = data->dev->data->dev_private; + const struct rte_flow_item_vxlan_gpe *spec = item->spec; + const struct rte_flow_item_vxlan_gpe *mask = item->mask; + struct mlx5_flow_parse *parser = data->parser; + unsigned int size = sizeof(struct ibv_flow_spec_tunnel); + struct ibv_flow_spec_tunnel vxlan = { + .type = parser->inner | IBV_FLOW_SPEC_VXLAN_TUNNEL, + .size = size, + }; + union vni { + uint32_t vlan_id; + uint8_t vni[4]; + } id; + + if (!priv->config.l3_vxlan_en) + return rte_flow_error_set(data->error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "L3 VXLAN not enabled by device" + " parameter and/or not configured" + " in firmware"); + id.vni[0] = 0; + parser->inner = IBV_FLOW_SPEC_INNER; + parser->tunnel = ptype_ext[PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN_GPE)]; + parser->out_layer = parser->layer; + parser->layer = HASH_RXQ_TUNNEL; + /* Default VXLAN-GPE to outer RSS. */ + if (!parser->rss_conf.level) + parser->rss_conf.level = 1; + if (spec) { + if (!mask) + mask = default_mask; + memcpy(&id.vni[1], spec->vni, 3); + vxlan.val.tunnel_id = id.vlan_id; + memcpy(&id.vni[1], mask->vni, 3); + vxlan.mask.tunnel_id = id.vlan_id; + if (spec->protocol) + return rte_flow_error_set(data->error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "VxLAN-GPE protocol not" + " supported"); + /* Remove unwanted bits from values. */ + vxlan.val.tunnel_id &= vxlan.mask.tunnel_id; + } + /* + * Tunnel id 0 is equivalent as not adding a VXLAN layer, if only this + * layer is defined in the Verbs specification it is interpreted as + * wildcard and all packets will match this rule, if it follows a full + * stack layer (ex: eth / ipv4 / udp), all packets matching the layers + * before will also match this rule. + * To avoid such situation, VNI 0 is currently refused. + */ + /* Only allow tunnel w/o tunnel id pattern after proper outer spec. */ + if (parser->out_layer == HASH_RXQ_ETH && !vxlan.val.tunnel_id) + return rte_flow_error_set(data->error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "VxLAN-GPE vni cannot be 0"); + mlx5_flow_create_copy(parser, &vxlan, size); + return 0; +} + +/** * Convert GRE item to Verbs specification. * * @param item[in] diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index 060ff0e85..f10ea13c1 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -466,8 +466,7 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n) uint8_t vlan_sz = (buf->ol_flags & PKT_TX_VLAN_PKT) ? 4 : 0; const uint64_t is_tunneled = - buf->ol_flags & (PKT_TX_TUNNEL_GRE | - PKT_TX_TUNNEL_VXLAN); + buf->ol_flags & (PKT_TX_TUNNEL_MASK); tso_header_sz = buf->l2_len + vlan_sz + buf->l3_len + buf->l4_len;