From patchwork Wed Sep 19 06:48:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongseok Koh X-Patchwork-Id: 44889 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 790DC5689; Wed, 19 Sep 2018 08:48:42 +0200 (CEST) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50069.outbound.protection.outlook.com [40.107.5.69]) by dpdk.org (Postfix) with ESMTP id 1556A4F98 for ; Wed, 19 Sep 2018 08:48:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hSrivmbfbv0AY0tCyNfOxcORuOqdbCeN+RsZMu7dw4Q=; b=WE/bnvB9+eU72NEspDMgPA9Wkgf3JuLE4JHMhpqjjMZn6IDJnOC7PlMX9yzhS5kxfiTI4lW7C+po6ZWUei5zEwQGUPxSEHjnY/zyAtJwHURZJhjJ+wCCgdHpEw/bQOMf8qfiJ35zrvKmB6sLRQsx1aZBH/wkYZ6g8iLjsumgU+g= Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by DB3PR0502MB4010.eurprd05.prod.outlook.com (52.134.72.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1143.18; Wed, 19 Sep 2018 06:48:39 +0000 Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::452:cfe7:8363:61c1]) by DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::452:cfe7:8363:61c1%2]) with mapi id 15.20.1143.017; Wed, 19 Sep 2018 06:48:38 +0000 From: Yongseok Koh To: Shahaf Shuler CC: "dev@dpdk.org" , Ori Kam Thread-Topic: [PATCH 05/11] net/mlx5: add Direct Verbs validation function Thread-Index: AQHUT+TL0K0C5RzQj0epbN1kyw2fMQ== Date: Wed, 19 Sep 2018 06:48:38 +0000 Message-ID: <20180919064814.21645-6-yskoh@mellanox.com> References: <20180919064814.21645-1-yskoh@mellanox.com> In-Reply-To: <20180919064814.21645-1-yskoh@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: CY4PR19CA0042.namprd19.prod.outlook.com (2603:10b6:903:103::28) To DB3PR0502MB3980.eurprd05.prod.outlook.com (2603:10a6:8:10::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [209.116.155.178] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR0502MB4010; 6:bzAGP1It3fc2B6Mo+dcjtT4ZBDWTNIQWPe41ckHdtHm710mf/s6P8+BbKOdb/QKJxaNJxoglYlnL13Q2jSH+/Z+KKrRuh+3wM7OAEyy+nG7NuYhhMe6fHPWd30GMAET5ebitoUPhuCyePiPuNOTOdl2/eq2I5qIYcPG9Es03IVEPTmk+pDt20j02HhOCuBrhtVfp4UUxEin/iOe0J3Uq848vPfAriv0w5w3fSwinK+Mk+r8OUr9gHJtd/ecNlwtsSls4jhXr+dvo0swmEMksu8qQtWGNdkaRRKlkjTy3hh4AzCmIepewDBrBv5CmYEJmbcfpudpwszJx6H2iy3ZEUcoox5W8/vvTTtWzy+THtx4Ve9a3PtoSUkGXsSjZ1RHcOLJi3s/aGMqV0QHgShoWKeCQVRjfIQjpHvI87T4aoNEQjubqRMUByUzIHw9mkdN/LdgRwhd6AoAeBcbmlTwipw==; 5:fZb/UB1eyaHKRCaUtiSCEMs+StVMNt4qgNnNaK6LzsW6YC75XN8kNAcOOBPL+Dt3oub8Qub/1lrJK5YHgSenxcJyn/NANO6pjG7MvqIhIND4iQsfn7MNW561umhdzJSo3C/tgfBpCV7FQOqsSvuj+cWIg0kQ058AeL1f2Eaoxtk=; 7:VAMAXSx7gFman0Y9HJQ57U7hMOXillyK0PfFD7sV3KDH5pPjryelZs9JiIc3Jwl7v1qfOb2uc96EVlFbhxEjCi6B8qDrPMVyuQZxOjSz0Re4idz+6rXaZALk7BV24pv4tqXcK0AO2a7u3iWsw0ZG/O1Ce1mhIxufPFzt7l8Wpk8N6ZI0fBkDwr1w0Ov+vBLxx3E8nhnC//2dYk5jczmnMfuIj75ZW6kzjw2eWsVjJiW3yfr975/CnnhYCNnDJOot x-ms-office365-filtering-correlation-id: 6a5c8164-666a-4b21-4ec7-08d61dfbedd2 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB3PR0502MB4010; x-ms-traffictypediagnostic: DB3PR0502MB4010: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(93001095)(3231355)(944501410)(52105095)(6055026)(149027)(150027)(6041310)(20161123564045)(20161123558120)(20161123562045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699050); SRVR:DB3PR0502MB4010; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB4010; x-forefront-prvs: 0800C0C167 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(396003)(376002)(39860400002)(346002)(366004)(136003)(189003)(199004)(51234002)(5250100002)(6512007)(107886003)(6862004)(54906003)(97736004)(6636002)(478600001)(8936002)(8676002)(76176011)(14454004)(36756003)(4326008)(26005)(37006003)(25786009)(53936002)(5660300001)(68736007)(52116002)(99286004)(6506007)(45954006)(86362001)(386003)(6116002)(7736002)(81156014)(305945005)(81166006)(106356001)(316002)(446003)(2900100001)(105586002)(102836004)(19627235002)(66066001)(2616005)(6436002)(11346002)(6486002)(476003)(256004)(1076002)(14444005)(575784001)(2906002)(486006)(3846002); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB4010; H:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: yKQqiQZBsQQRMyspBCeQN7vNJ0I5vtk+vsMUletkFr1JczXJX+nhyh6GaXwBvP/c36FcT1bdpr9hrFIFBVQnKjFyjliFJsPTmZbaFZpe/8OPOTese5eT608JhtpJ2t6Tk8Jo03pcVTtRUv+Cd2HK4vC6Y5r8sx01u4LamiBHRolqa/I1bCLfGom+H4Jn4tWytoztsbpbCnBtRfrC1Dv5zooTq4+rIQXvjrB5Jy1i45qlykf8H3npdkWOi+pp5TNJIUg+crdWrFs+Eu3ZbF6rha7dJXJyfzE6sfrT7Sw0EOQa/bjDgR3NGWZtIFvDTdG2pcDXmib3B5WU5Uj24u6DUjdt3zP/Gk886a1yPTZX87s= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6a5c8164-666a-4b21-4ec7-08d61dfbedd2 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Sep 2018 06:48:38.8627 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR0502MB4010 Subject: [dpdk-dev] [PATCH 05/11] net/mlx5: add Direct Verbs validation function 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" From: Ori Kam This is commit introduce the Direct Verbs driver API. The Direct Verbs is an API adds new features like encapsulation, match on metatdata. In this commit the validation function was added, most of the validation is done with functions that are also in use for the Verbs API. Signed-off-by: Ori Kam Acked-by: Yongseok Koh --- drivers/net/mlx5/Makefile | 6 + drivers/net/mlx5/mlx5_flow.h | 6 + drivers/net/mlx5/mlx5_flow_dv.c | 312 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+) create mode 100644 drivers/net/mlx5/mlx5_flow_dv.c diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 9bd6bfb82..d510a4275 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -31,6 +31,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_stats.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rss.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mr.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_dv.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_verbs.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl.c @@ -136,6 +137,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_IBV_FLOW_DV_SUPPORT \ + infiniband/mlx5dv.h \ + enum MLX5DV_FLOW_ACTION_TAG \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_ETHTOOL_LINK_MODE_25G \ /usr/include/linux/ethtool.h \ enum ETHTOOL_LINK_MODE_25000baseCR_Full_BIT \ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 4df60db92..9b0cd28ae 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -103,6 +103,9 @@ #define MLX5_PRIORITY_MAP_L4 0 #define MLX5_PRIORITY_MAP_MAX 3 +/* Max number of actions per DV flow. */ +#define MLX5_DV_MAX_NUMBER_OF_ACTIONS 8 + /* Verbs specification header. */ struct ibv_spec_header { enum ibv_flow_spec_type type; @@ -250,6 +253,9 @@ int mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, struct rte_flow_error *error); void mlx5_flow_init_driver_ops(struct rte_eth_dev *dev); +/* mlx5_flow_dv.c */ +void mlx5_flow_dv_get_driver_ops(struct mlx5_flow_driver_ops *flow_ops); + /* mlx5_flow_verbs.c */ void mlx5_flow_verbs_get_driver_ops(struct mlx5_flow_driver_ops *flow_ops); diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c new file mode 100644 index 000000000..86a8b3cd0 --- /dev/null +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include + +/* Verbs header. */ +/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mlx5.h" +#include "mlx5_defs.h" +#include "mlx5_prm.h" +#include "mlx5_glue.h" +#include "mlx5_flow.h" + +#ifdef HAVE_IBV_FLOW_DV_SUPPORT + +/** + * Verify the @p attributes will be correctly understood by the NIC and store + * them in the @p flow if everything is correct. + * + * @param[in] dev + * Pointer to dev struct. + * @param[in] attributes + * 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_attributes(struct rte_eth_dev *dev, + const struct rte_flow_attr *attributes, + struct rte_flow_error *error) +{ + struct priv *priv = dev->data->dev_private; + uint32_t priority_max = priv->config.flow_prio - 1; + + if (attributes->group) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, + NULL, + "groups is not supported"); + if (attributes->priority != MLX5_FLOW_PRIO_RSVD && + attributes->priority >= priority_max) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + NULL, + "priority out of range"); + if (attributes->egress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, + NULL, + "egress is not supported"); + if (attributes->transfer) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, + NULL, + "transfer is not supported"); + if (!attributes->ingress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "ingress attribute is mandatory"); + return 0; +} + +/** + * Internal validation function. For validating both actions and items. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] attr + * Pointer to the flow attributes. + * @param[in] items + * Pointer to the list of items. + * @param[in] actions + * Pointer to the list of actions. + * @param[out] error + * Pointer to the error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_ernno is set. + */ +static int +flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + int ret; + uint32_t action_flags = 0; + uint32_t item_flags = 0; + int tunnel = 0; + uint8_t next_protocol = 0xff; + int actions_n = 0; + + if (items == NULL) + return -1; + ret = flow_dv_validate_attributes(dev, attr, error); + if (ret < 0) + return ret; + for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { + switch (items->type) { + case RTE_FLOW_ITEM_TYPE_VOID: + break; + case RTE_FLOW_ITEM_TYPE_ETH: + ret = mlx5_flow_validate_item_eth(items, item_flags, + error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 : + MLX5_FLOW_LAYER_OUTER_L2; + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + ret = mlx5_flow_validate_item_vlan(items, item_flags, + error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : + MLX5_FLOW_LAYER_OUTER_VLAN; + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + ret = mlx5_flow_validate_item_ipv4(items, item_flags, + error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : + MLX5_FLOW_LAYER_OUTER_L3_IPV4; + if (items->mask != NULL && + ((const struct rte_flow_item_ipv4 *) + items->mask)->hdr.next_proto_id) + next_protocol = + ((const struct rte_flow_item_ipv4 *) + (items->spec))->hdr.next_proto_id; + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + ret = mlx5_flow_validate_item_ipv6(items, item_flags, + error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + if (items->mask != NULL && + ((const struct rte_flow_item_ipv6 *) + items->mask)->hdr.proto) + next_protocol = + ((const struct rte_flow_item_ipv6 *) + items->spec)->hdr.proto; + break; + case RTE_FLOW_ITEM_TYPE_UDP: + ret = mlx5_flow_validate_item_udp(items, item_flags, + next_protocol, + error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP : + MLX5_FLOW_LAYER_OUTER_L4_UDP; + break; + case RTE_FLOW_ITEM_TYPE_TCP: + ret = mlx5_flow_validate_item_tcp(items, item_flags, + next_protocol, error); + if (ret < 0) + return ret; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP : + MLX5_FLOW_LAYER_OUTER_L4_TCP; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + ret = mlx5_flow_validate_item_vxlan(items, item_flags, + error); + if (ret < 0) + return ret; + item_flags |= MLX5_FLOW_LAYER_VXLAN; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + ret = mlx5_flow_validate_item_vxlan_gpe(items, + item_flags, dev, + error); + if (ret < 0) + return ret; + item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; + break; + case RTE_FLOW_ITEM_TYPE_GRE: + ret = mlx5_flow_validate_item_gre(items, item_flags, + next_protocol, error); + if (ret < 0) + return ret; + item_flags |= MLX5_FLOW_LAYER_GRE; + break; + case RTE_FLOW_ITEM_TYPE_MPLS: + ret = mlx5_flow_validate_item_mpls(items, item_flags, + next_protocol, + error); + if (ret < 0) + return ret; + item_flags |= MLX5_FLOW_LAYER_MPLS; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + NULL, "item not supported"); + } + } + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + if (actions_n == MLX5_DV_MAX_NUMBER_OF_ACTIONS) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + actions, "too many actions"); + tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_VOID: + break; + case RTE_FLOW_ACTION_TYPE_FLAG: + ret = mlx5_flow_validate_action_flag(action_flags, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_FLAG; + ++actions_n; + break; + case RTE_FLOW_ACTION_TYPE_MARK: + ret = mlx5_flow_validate_action_mark(actions, + action_flags, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_MARK; + ++actions_n; + break; + case RTE_FLOW_ACTION_TYPE_DROP: + ret = mlx5_flow_validate_action_drop(action_flags, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_DROP; + ++actions_n; + break; + case RTE_FLOW_ACTION_TYPE_QUEUE: + ret = mlx5_flow_validate_action_queue(actions, + action_flags, dev, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_QUEUE; + ++actions_n; + break; + case RTE_FLOW_ACTION_TYPE_RSS: + ret = mlx5_flow_validate_action_rss(actions, + action_flags, dev, + error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_RSS; + ++actions_n; + break; + case RTE_FLOW_ACTION_TYPE_COUNT: + ret = mlx5_flow_validate_action_count(dev, error); + if (ret < 0) + return ret; + action_flags |= MLX5_ACTION_COUNT; + ++actions_n; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + actions, + "action not supported"); + } + } + return 0; +} + +/** + * Fills the flow_ops with the function pointers. + * + * @param[out] flow_ops + * Pointer to driver_ops structure. + */ +void +mlx5_flow_dv_get_driver_ops(struct mlx5_flow_driver_ops *flow_ops) +{ + *flow_ops = (struct mlx5_flow_driver_ops) { + .validate = flow_dv_validate, + .prepare = NULL, + .translate = NULL, + .apply = NULL, + .remove = NULL, + .destroy = NULL, + }; +} + +#endif /* HAVE_IBV_FLOW_DV_SUPPORT */