From patchwork Fri Apr 21 10:48:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dima Chumak X-Patchwork-Id: 13219799 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03AD1C77B75 for ; Fri, 21 Apr 2023 10:49:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231522AbjDUKtx (ORCPT ); Fri, 21 Apr 2023 06:49:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231591AbjDUKtt (ORCPT ); Fri, 21 Apr 2023 06:49:49 -0400 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2081.outbound.protection.outlook.com [40.107.244.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 243486E92 for ; Fri, 21 Apr 2023 03:49:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EtTPNKefQ2+OaTL/e8jqXuzfH11/hSC1Lh4VBTGgP/wJrUakdVS87X/hfRVam3XYjQAYklFCfR6VFAe/uOVW1cDRm5x2bHocnSpgH1u88cBYb1HhPMQJra0hUmxQIRzPcJrSL3aCn9ysyZEKtdAkoSmVVk5QGZGzP9vmcC0Pf7fgWjQGQ22oS7h7cT+RFeJ6JKREGt8vIkXI6qkHNoMTk+e32n8Y7Vu9k1WDIkPZx/Ws2CfgPjoTWd6qQ768+jUAJRZIrwxZE2Yl5qa0u1UsJbsl/uh1+mC+jSqO2KcfgDiLL33RKEqlI4Blwt5U/JCBa30cYXaGNsR/5AjrqMw7FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=G2znixs7Z60tItwVLQpqrCQd4r+HNF9pI3VUrDVtjtA=; b=B8g1CnPjmu24nci5NUx4Yy1RhoZ+pD235lpsz+XIjJJiS3UYjJGEPQLj4nR0ogPgZHrXPUHriiBf9NMH6MUuEhfS8ir7P+MlwpMbrsBvYHzAVUDvA7cy6WOXxZljgrTdQV2o2l5ycyLHzEUQMga9fatsVQyjJYSWndOb5MCHfVj1U56CRal7qWr9cY9CEed/FmCQJdiJq4qZ9cYLyMhvjqn9K2mForBk4nLzWhpX/M42smtJH7lXP+fnUuHmlXorm+gtBKhQzvelnkvxXor8n8b1hRRRkvrkcffZKiYBtMxn1TaEJrXAnzqnSrYtKYb3WOx1iKf3eN9GYkpHohPZ+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.233) smtp.rcpttodomain=davemloft.net smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=G2znixs7Z60tItwVLQpqrCQd4r+HNF9pI3VUrDVtjtA=; b=c1wdtL44ADKOsTWcvCfg27o7V7yDyY/85RgrWV1bM/Ttaae68BtBIOws3dgqpz2lnYYt42LQ1k1DtH/ljhL9DEyr7OBT0TFqQhjZq18FsMbRn8d6nu3ZzYQdPHgQSa2Jts6Iu4DpqEyhN5YEZhFMl4hJV41VjOAPwJYY+iFOkrGbC9S3aTX8NYaoOJWVFRHK6hFWesnW7l0G3ARxR84n3YXSQxqqLhKifw5ROf6oHZSk+lcgNGpIcI1Vo6NFZyXdtvuEDZEdAaKhgK8ciUqg3wvnMjJhIw5GZ8juNanrmL+aiA0tjcLeiE+NUF2Gxa5Z9bXtMMnGDSO3oGcNJqcBVQ== Received: from BN1PR13CA0028.namprd13.prod.outlook.com (2603:10b6:408:e2::33) by BL1PR12MB5144.namprd12.prod.outlook.com (2603:10b6:208:316::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.22; Fri, 21 Apr 2023 10:49:44 +0000 Received: from BN8NAM11FT085.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e2:cafe::3d) by BN1PR13CA0028.outlook.office365.com (2603:10b6:408:e2::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.11 via Frontend Transport; Fri, 21 Apr 2023 10:49:44 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.233) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.233 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.233; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.233) by BN8NAM11FT085.mail.protection.outlook.com (10.13.176.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.27 via Frontend Transport; Fri, 21 Apr 2023 10:49:43 +0000 Received: from drhqmail202.nvidia.com (10.126.190.181) by mail.nvidia.com (10.127.129.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Fri, 21 Apr 2023 03:49:35 -0700 Received: from drhqmail202.nvidia.com (10.126.190.181) by drhqmail202.nvidia.com (10.126.190.181) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Fri, 21 Apr 2023 03:49:34 -0700 Received: from vdi.nvidia.com (10.127.8.13) by mail.nvidia.com (10.126.190.181) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Fri, 21 Apr 2023 03:49:32 -0700 From: Dima Chumak To: "David S. Miller" , Jakub Kicinski , Eric Dumazet , Paolo Abeni CC: , Jiri Pirko , Leon Romanovsky , Saeed Mahameed , Dima Chumak , Jiri Pirko Subject: [PATCH net-next V2 1/4] devlink: Expose port function commands to control IPsec crypto offloads Date: Fri, 21 Apr 2023 13:48:58 +0300 Message-ID: <20230421104901.897946-2-dchumak@nvidia.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230421104901.897946-1-dchumak@nvidia.com> References: <20230421104901.897946-1-dchumak@nvidia.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT085:EE_|BL1PR12MB5144:EE_ X-MS-Office365-Filtering-Correlation-Id: 6e5231ac-e968-4026-9c1b-08db42561dbd X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: xDzjPGDlXvru8V1V40/t6z7n8erO9ZqT6aKGDtsMjztUQlwCz2rweEUSn3Jnjlgw09YYdMpM4KfIpcM9hutkcSgq1BHbKitzQZHpw1rTaMBC4GwNBqGdDiSShneoIXiblxf1eXEcr0FFNGdlhdGCWJkE3F1cGIZ6SUztkLnRMwtO130BGnQIAXZae6fty7Wz7WjAWK26P18c1aS/wWzRftDkqkppVQokAGEvz3TttU4j3ylprRZYTVP4lkYzI9p6dsB+DSRV5GP4AShr/JdEYCJNSUhZjx2k2IZJDkA2MlD3tQhEo5BUqTwlSHT10JKpcatmDC9gLEj/R0K8u+sEh/NwR9/NU3eR8Lbq1l8tK84hbcxqXjZgfuGx1pwxAs2ZvMiKOTyYYfzG15ifc9aKG1QFXes6HbeI/ZlIEITJvJXb6yXKpZpskRpXoU0wrc9wt7Z/IhzsJQn1pnM/rliIiZhmGyq+CQ+fzcMimOeTxZLCAQMplZKvm5czOqKrQmOUjZqCo68FpcvqqQQQZY58ZJq3UjuYhehYZyaF9pgxvnRDd3GPXHm2PJkqc245hrhloCM1phDYyDKoVLXQPVPCeoRdwH5IUzZ48HY+LcTjoaDOyU28ismnAlJhSlgTd9VK9/TjVgiwMic6oLIr24aLz6yol8Dmg+5Rn7NFEZXo77xZMxP2cuU4ou/5P85DxYFNl4EFnSuXAnq9OjzLNkD7b63sokM0/f0FIOQ1Vvr5U6uaELtTRJlynOYoD4scSyq34Zzi7DwqUdJWbbWViVLjClg3hfGIfZq6NZSopltYTy4= X-Forefront-Antispam-Report: CIP:216.228.118.233;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge2.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(346002)(136003)(396003)(376002)(39860400002)(451199021)(36840700001)(40470700004)(46966006)(41300700001)(70206006)(70586007)(316002)(110136005)(34020700004)(107886003)(26005)(54906003)(4326008)(478600001)(186003)(8936002)(426003)(8676002)(83380400001)(336012)(5660300002)(1076003)(36860700001)(47076005)(7696005)(36756003)(6666004)(40460700003)(82740400003)(356005)(2906002)(2616005)(7636003)(82310400005)(40480700001)(86362001);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Apr 2023 10:49:43.4768 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6e5231ac-e968-4026-9c1b-08db42561dbd X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.233];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT085.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR12MB5144 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Expose port function commands to enable / disable IPsec crypto offloads, this is used to control the port IPsec capabilities. When IPsec crypto is disabled for a function of the port (default), function cannot offload any IPsec crypto operations (Encrypt/Decrypt and XFRM state offloading). When enabled, IPsec crypto operations can be offloaded by the function of the port. Example of a PCI VF port which supports IPsec crypto offloads: $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable ipsec_crypto disable $ devlink port function set pci/0000:06:00.0/1 ipsec_crypto enable $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable ipsec_crypto enable Signed-off-by: Dima Chumak Reviewed-by: Jiri Pirko --- .../networking/devlink/devlink-port.rst | 27 +++++++++ include/net/devlink.h | 21 +++++++ include/uapi/linux/devlink.h | 2 + net/devlink/leftover.c | 55 +++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/Documentation/networking/devlink/devlink-port.rst b/Documentation/networking/devlink/devlink-port.rst index 3da590953ce8..6983b11559cb 100644 --- a/Documentation/networking/devlink/devlink-port.rst +++ b/Documentation/networking/devlink/devlink-port.rst @@ -128,6 +128,9 @@ Users may also set the RoCE capability of the function using Users may also set the function as migratable using 'devlink port function set migratable' command. +Users may also set the IPsec crypto capability of the function using +`devlink port function set ipsec_crypto` command. + Function attributes =================== @@ -240,6 +243,30 @@ Attach VF to the VM. Start the VM. Perform live migration. +IPsec crypto capability setup +----------------------------- +When user enables IPsec crypto capability for a VF, user application can offload +XFRM state crypto operation (Encrypt/Decrypt) to this VF. + +When IPsec crypto capability is disabled (default) for a VF, the XFRM state is +processed in software by the kernel. + +- Get IPsec crypto capability of the VF device:: + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:00:00:00:00:00 ipsec_crypto disabled + +- Set IPsec crypto capability of the VF device:: + + $ devlink port function set pci/0000:06:00.0/2 ipsec_crypto enable + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:00:00:00:00:00 ipsec_crypto enabled + Subfunction ============ diff --git a/include/net/devlink.h b/include/net/devlink.h index 6a942e70e451..4e5f4aeca29d 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1495,6 +1495,27 @@ struct devlink_ops { int (*port_fn_migratable_set)(struct devlink_port *devlink_port, bool enable, struct netlink_ext_ack *extack); + /** + * @port_fn_ipsec_crypto_get: Port function's ipsec_crypto get function. + * + * Query ipsec_crypto state of a function managed by the devlink port. + * Return -EOPNOTSUPP if port function IPsec crypto offload is not + * supported. + */ + int (*port_fn_ipsec_crypto_get)(struct devlink_port *devlink_port, + bool *is_enable, + struct netlink_ext_ack *extack); + /** + * @port_fn_ipsec_crypto_set: Port function's ipsec_crypto set function. + * + * Enable/Disable ipsec_crypto state of a function managed by the devlink + * port. + * Return -EOPNOTSUPP if port function IPsec crypto offload is not + * supported. + */ + int (*port_fn_ipsec_crypto_set)(struct devlink_port *devlink_port, + bool enable, + struct netlink_ext_ack *extack); /** * port_new() - Add a new port function of a specified flavor * @devlink: Devlink instance diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 3782d4219ac9..f9ae9a058ad2 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -661,6 +661,7 @@ enum devlink_resource_unit { enum devlink_port_fn_attr_cap { DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT, DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT, + DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT, /* Add new caps above */ __DEVLINK_PORT_FN_ATTR_CAPS_MAX, @@ -669,6 +670,7 @@ enum devlink_port_fn_attr_cap { #define DEVLINK_PORT_FN_CAP_ROCE _BITUL(DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT) #define DEVLINK_PORT_FN_CAP_MIGRATABLE \ _BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT) +#define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT) enum devlink_port_function_attr { DEVLINK_PORT_FUNCTION_ATTR_UNSPEC, diff --git a/net/devlink/leftover.c b/net/devlink/leftover.c index dffca2f9bfa7..07761df2471d 100644 --- a/net/devlink/leftover.c +++ b/net/devlink/leftover.c @@ -492,6 +492,29 @@ static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops, return 0; } +static int devlink_port_fn_ipsec_crypto_fill(const struct devlink_ops *ops, + struct devlink_port *devlink_port, + struct nla_bitfield32 *caps, + struct netlink_ext_ack *extack) +{ + bool is_enable; + int err; + + if (!ops->port_fn_ipsec_crypto_get || + devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) + return 0; + + err = ops->port_fn_ipsec_crypto_get(devlink_port, &is_enable, extack); + if (err) { + if (err == -EOPNOTSUPP) + return 0; + return err; + } + + devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO, is_enable); + return 0; +} + static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, struct devlink_port *devlink_port, struct sk_buff *msg, @@ -509,6 +532,10 @@ static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, if (err) return err; + err = devlink_port_fn_ipsec_crypto_fill(ops, devlink_port, &caps, extack); + if (err) + return err; + if (!caps.selector) return 0; err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value, @@ -843,6 +870,15 @@ devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable, return ops->port_fn_roce_set(devlink_port, enable, extack); } +static int +devlink_port_fn_ipsec_crypto_set(struct devlink_port *devlink_port, bool enable, + struct netlink_ext_ack *extack) +{ + const struct devlink_ops *ops = devlink_port->devlink->ops; + + return ops->port_fn_ipsec_crypto_set(devlink_port, enable, extack); +} + static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, const struct nlattr *attr, struct netlink_ext_ack *extack) @@ -867,6 +903,13 @@ static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, if (err) return err; } + if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO) { + err = devlink_port_fn_ipsec_crypto_set(devlink_port, caps_value & + DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO, + extack); + if (err) + return err; + } return 0; } @@ -1235,6 +1278,18 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port, return -EOPNOTSUPP; } } + if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO) { + if (!ops->port_fn_ipsec_crypto_set) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "Port doesn't support ipsec_crypto function attribute"); + return -EOPNOTSUPP; + } + if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "ipsec_crypto function attribute supported for VFs only"); + return -EOPNOTSUPP; + } + } } return 0; } From patchwork Fri Apr 21 10:48:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dima Chumak X-Patchwork-Id: 13219802 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4926CC77B75 for ; Fri, 21 Apr 2023 10:50:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231590AbjDUKuL (ORCPT ); Fri, 21 Apr 2023 06:50:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231562AbjDUKuC (ORCPT ); Fri, 21 Apr 2023 06:50:02 -0400 Received: from NAM04-MW2-obe.outbound.protection.outlook.com (mail-mw2nam04on2046.outbound.protection.outlook.com [40.107.101.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FA759038 for ; Fri, 21 Apr 2023 03:49:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lgyGkihVn4ymMRP/EM5QlMgj7DFyT6dSB5nsGJtRX1DOBE0hlwWDTajpFZYnKA89htZN4tBwMQ1FFnP+zYwj+hQc2vq6Huu2kuPtxQT1VuqbOJK0y54UNStIT3LSeiCuXg7+73OOrhFQdqtw0OAilFgCQ4z2MiKAh4+Rj2rpRxn/NSQy1JAklwDG8BbejWYx3jlfRlChre7VRd5e7h2JEXTJkW0uoeH9ZBNjRoNIfBzSQAKAF8zCXOxcfH/S3H+Q15Jw55RlCt+zbQ7aXVegqFoCCuPf796tGHWtwZoJ8t+urAq69dCneLw4iul33lAv63HJb2WQ9bVkBIYIaSVgrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=wNzh+/gLNKT7sPaM9ChnFfJ4kiwD1XB3qpDxer0hc5o=; b=IrIhCh6cXDDlfNwwUWFC6o9OKVXm5r08jHKyuXLNKR6FBqvQI4tKXYqSEsVRXZM9A7zuLnRnOF4YoT9t1nAPAc+IpCMrLNBFWAt78gghUZsC5DT2EC3RLPtMK6z/WvqriTzxFROhzLPzSfCkPfrs3eKfoP3b067unTtPFKumbsQtG55Vt7zT7ZyNeQi+5zZjofYM7DPqR5agTu+S8xEc0Q7HpV/IIZxqyxxNauVPmmCTDrI9PZ8w//HftbNoEz1fRg9Oo635CnvwNn06NCIyVLT3GaUuZ0KTuOFfQD7ILO+PFQI7CV035wE4nCsbVePI9wiRhcOgOLXI8aXH6J89vA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=davemloft.net smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=wNzh+/gLNKT7sPaM9ChnFfJ4kiwD1XB3qpDxer0hc5o=; b=MHDDW1btIyT1PZmD0sd0yo9fHl5GC/BPdoe2KS0YprdDlue9ZADaB6O91IWlQRK/RCMfnA8zG+x8WqoPllLMS6JsYvKdGJkti5VtP8o+f8lSaYevfWDKEFpNbb5kloR4nmh3ul4iZyyjApQ3xYVi3cP0nJTdi2irrHgx5RSGzKW4+x+m8BMNLGlakwmou0rZM8BeiWwztubLATjHmLvpmTiu2WK39JSJDR/h3/vW+QvKHrhyNbSaYSQLIt9DOwRdnldUBmc2iDDIxjlC3oVgpux0cO2VTkTK3nSAwsH17NJwbpBHT3K2Mra1WgXp56EPDMliq0mcE9p0RhVCYg3qDw== Received: from BN9PR03CA0229.namprd03.prod.outlook.com (2603:10b6:408:f8::24) by CO6PR12MB5410.namprd12.prod.outlook.com (2603:10b6:5:35b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.21; Fri, 21 Apr 2023 10:49:47 +0000 Received: from BL02EPF000145BB.namprd05.prod.outlook.com (2603:10b6:408:f8:cafe::24) by BN9PR03CA0229.outlook.office365.com (2603:10b6:408:f8::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.25 via Frontend Transport; Fri, 21 Apr 2023 10:49:47 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.232) by BL02EPF000145BB.mail.protection.outlook.com (10.167.241.211) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.15 via Frontend Transport; Fri, 21 Apr 2023 10:49:47 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Fri, 21 Apr 2023 03:49:38 -0700 Received: from drhqmail202.nvidia.com (10.126.190.181) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Fri, 21 Apr 2023 03:49:37 -0700 Received: from vdi.nvidia.com (10.127.8.13) by mail.nvidia.com (10.126.190.181) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Fri, 21 Apr 2023 03:49:35 -0700 From: Dima Chumak To: "David S. Miller" , Jakub Kicinski , Eric Dumazet , Paolo Abeni CC: , Jiri Pirko , Leon Romanovsky , Saeed Mahameed , Dima Chumak Subject: [PATCH net-next V2 2/4] net/mlx5: Implement devlink port function cmds to control ipsec_crypto Date: Fri, 21 Apr 2023 13:48:59 +0300 Message-ID: <20230421104901.897946-3-dchumak@nvidia.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230421104901.897946-1-dchumak@nvidia.com> References: <20230421104901.897946-1-dchumak@nvidia.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF000145BB:EE_|CO6PR12MB5410:EE_ X-MS-Office365-Filtering-Correlation-Id: 540c0d23-0541-4e30-9d69-08db42561fd9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: xXf0FTH2crFa2a/Jll0LQ6eA1ND4Fh8xxJ8QBRXvAcGJVFSDcwa0ZurahEsPA1X1f27BoJNFqDBfjMwKcEPrjLh3Jmf+LWVnWyg4We+NM23iP/3VcmZqG6RIqJLbJRsbVCO4f5EQL/dRltQnnAyQq3VDKvhfAykaT1JS3fdCDurDfyhpK9/UoWvrQxy0jCY7x9HQ+B85frMRY2fsAnGA795vYegRRUB51RDVpxoRpjQygiS+Tr6KP0HH7ZIfRc8zf0JCoxy1MYHoBb+yMHZowmGNWlV7QqLhldvy+l5yKFWJsYleF/uJi8f0IZFbYXQOKh7YpVQnZfwLb9YVYgjly4KAe8LjHvbLWyM2E6HE8KR5Omxt1oQhfueg7ro4oFlbqZwh8/iEhXzWdirVCsVolg+obKjtlE7XovlhRVTOX/GmS/5JnzFP+M3kxrxepnd19S0Nj6ZiMvzgul8nt6tY74/bIgWzxLVgnHbmCd+0iM+Kgx4FAlHleXfLcdNLfETTaAzkaYT7r9wlWYM/6d4lXZzg0GQOxFw/cUsf8OK7BRfbryi5uWISujb+vjLIyqmuXvE9Tt3td/iAELUonhvDIWNJB5/loyDQNZScL7jzoFVi5i7VHRjyNf70E3pmbGIDzx4O+1yjZUJcmXHCiIwAys0eRjk3OunVgvcsA7axHcQ1UcAXAu7BRB5PI67yJio/rEl6iL3JqjoOmaGA1HKHEuUVJWNkRdz+k/Wqrt5j30Yyo507Px6ZGDqyV8TefyXucLm/x+pYV0UB8gT9ETc7EQ== X-Forefront-Antispam-Report: CIP:216.228.118.232;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge1.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(376002)(396003)(346002)(39860400002)(136003)(451199021)(46966006)(36840700001)(40470700004)(1076003)(26005)(186003)(426003)(336012)(107886003)(41300700001)(6666004)(7696005)(36860700001)(83380400001)(47076005)(2616005)(54906003)(478600001)(110136005)(40460700003)(4326008)(82310400005)(70586007)(70206006)(40480700001)(356005)(316002)(7636003)(5660300002)(8936002)(82740400003)(36756003)(2906002)(30864003)(86362001)(8676002)(309714004);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Apr 2023 10:49:47.0158 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 540c0d23-0541-4e30-9d69-08db42561fd9 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.232];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BL02EPF000145BB.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR12MB5410 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Implement devlink port function commands to enable / disable IPsec crypto offloads. This is used to control the IPsec capability of the device. When ipsec_crypto is enabled for a VF, it prevents adding IPsec crypto offloads on the PF, because the two cannot be active simultaneously due to HW constraints. Conversely, if there are any active IPsec crypto offloads on the PF, it's not allowed to enable ipsec_crypto on a VF, until PF IPsec offloads are cleared. Signed-off-by: Dima Chumak --- v1 -> v2: - Fix build when CONFIG_XFRM is not set. - Fix switchdev mode init for HW that doesn't have ipsec_offload capability - Perform additional capability checks to test if ipsec_crypto offload is supported by the HW --- .../ethernet/mellanox/mlx5/switchdev.rst | 8 + .../net/ethernet/mellanox/mlx5/core/Makefile | 2 +- .../net/ethernet/mellanox/mlx5/core/devlink.c | 6 +- .../mellanox/mlx5/core/en_accel/ipsec.c | 18 + .../ethernet/mellanox/mlx5/core/esw/ipsec.c | 329 ++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/eswitch.c | 29 ++ .../net/ethernet/mellanox/mlx5/core/eswitch.h | 23 ++ .../mellanox/mlx5/core/eswitch_offloads.c | 105 ++++++ .../ethernet/mellanox/mlx5/core/lib/ipsec.h | 41 +++ include/linux/mlx5/driver.h | 1 + include/linux/mlx5/mlx5_ifc.h | 3 + 11 files changed, 563 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec.h diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst index 01deedb71597..9a41da6b33ff 100644 --- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst +++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst @@ -168,6 +168,14 @@ explicitly enable the VF migratable capability. mlx5 driver support devlink port function attr mechanism to setup migratable capability. (refer to Documentation/networking/devlink/devlink-port.rst) +IPsec crypto capability setup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User who wants mlx5 PCI VFs to be able to perform IPsec crypto offloading need +to explicitly enable the VF ipsec_crypto capability. + +mlx5 driver support devlink port function attr mechanism to setup ipsec_crypto +capability. (refer to Documentation/networking/devlink/devlink-port.rst) + SF state setup -------------- diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile index ca3c66cd47ec..3f84950d0217 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile @@ -69,7 +69,7 @@ mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o # mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offloads_termtbl.o \ ecpf.o rdma.o esw/legacy.o \ - esw/debugfs.o esw/devlink_port.o esw/vporttbl.o esw/qos.o + esw/debugfs.o esw/devlink_port.o esw/vporttbl.o esw/qos.o esw/ipsec.o mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \ esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index 25d1a04ef443..e1c7cd11444f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -324,7 +324,11 @@ static const struct devlink_ops mlx5_devlink_ops = { .port_fn_roce_set = mlx5_devlink_port_fn_roce_set, .port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get, .port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set, -#endif +#ifdef CONFIG_XFRM + .port_fn_ipsec_crypto_get = mlx5_devlink_port_fn_ipsec_crypto_get, + .port_fn_ipsec_crypto_set = mlx5_devlink_port_fn_ipsec_crypto_set, +#endif /* CONFIG_XFRM */ +#endif /* CONFIG_MLX5_ESWITCH */ #ifdef CONFIG_MLX5_SF_MANAGER .port_new = mlx5_devlink_sf_port_new, .port_del = mlx5_devlink_sf_port_del, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 5fd609d1120e..aa67f129dc94 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -38,6 +38,8 @@ #include #include "en.h" +#include "eswitch.h" +#include "lib/ipsec.h" #include "ipsec.h" #include "ipsec_rxtx.h" @@ -622,6 +624,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, struct mlx5e_ipsec_sa_entry *sa_entry = NULL; struct net_device *netdev = x->xso.real_dev; struct mlx5e_ipsec *ipsec; + struct mlx5_eswitch *esw; struct mlx5e_priv *priv; gfp_t gfp; int err; @@ -646,6 +649,11 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, if (err) goto err_xfrm; + esw = priv->mdev->priv.eswitch; + if (esw && mlx5_esw_vport_ipsec_offload_enabled(esw)) + return -EBUSY; + mlx5_eswitch_ipsec_offloads_count_inc(priv->mdev); + /* check esn */ if (x->props.flags & XFRM_STATE_ESN) mlx5e_ipsec_update_esn_state(sa_entry); @@ -711,6 +719,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, kfree(sa_entry->work->data); kfree(sa_entry->work); err_xfrm: + mlx5_eswitch_ipsec_offloads_count_dec(priv->mdev); kfree(sa_entry); NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy"); return err; @@ -734,6 +743,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x) /* Make sure that no ARP requests are running in parallel */ flush_workqueue(ipsec->wq); + mlx5_eswitch_ipsec_offloads_count_dec(ipsec->mdev); } static void mlx5e_xfrm_free_state(struct xfrm_state *x) @@ -1007,6 +1017,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x, { struct net_device *netdev = x->xdo.real_dev; struct mlx5e_ipsec_pol_entry *pol_entry; + struct mlx5_eswitch *esw; struct mlx5e_priv *priv; int err; @@ -1027,6 +1038,11 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x, pol_entry->x = x; pol_entry->ipsec = priv->ipsec; + esw = priv->mdev->priv.eswitch; + if (esw && mlx5_esw_vport_ipsec_offload_enabled(esw)) + return -EBUSY; + mlx5_eswitch_ipsec_offloads_count_inc(priv->mdev); + mlx5e_ipsec_build_accel_pol_attrs(pol_entry, &pol_entry->attrs); err = mlx5e_accel_ipsec_fs_add_pol(pol_entry); if (err) @@ -1036,6 +1052,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x, return 0; err_fs: + mlx5_eswitch_ipsec_offloads_count_dec(priv->mdev); kfree(pol_entry); NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy"); return err; @@ -1045,6 +1062,7 @@ static void mlx5e_xfrm_free_policy(struct xfrm_policy *x) { struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x); + mlx5_eswitch_ipsec_offloads_count_dec(pol_entry->ipsec->mdev); mlx5e_accel_ipsec_fs_del_pol(pol_entry); kfree(pol_entry); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c new file mode 100644 index 000000000000..5da5fc17cafb --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + +#include +#include +#include "mlx5_core.h" +#include "eswitch.h" +#include "lib/ipsec.h" + +static int esw_ipsec_vf_query_generic(struct mlx5_core_dev *dev, u16 vport_num, bool *result) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *hca_cap = NULL, *query_cap = NULL; + int err; + + if (!MLX5_CAP_GEN(dev, vhca_resource_manager)) + return -EOPNOTSUPP; + + if (!mlx5_esw_ipsec_vf_offload_supported(dev)) { + *result = false; + return 0; + } + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + if (!query_cap) + return -ENOMEM; + + err = mlx5_vport_get_other_func_general_cap(dev, vport_num, query_cap); + if (err) + goto out; + + hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + *result = MLX5_GET(cmd_hca_cap, hca_cap, ipsec_offload); +out: + kvfree(query_cap); + return err; +} + +enum esw_vport_ipsec_offload { + MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD, +}; + +static int esw_ipsec_vf_query(struct mlx5_core_dev *dev, struct mlx5_vport *vport, bool *crypto) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *hca_cap = NULL, *query_cap = NULL; + bool ipsec_enabled; + int err; + + /* Querying IPsec caps only makes sense when generic ipsec_offload + * HCA cap is enabled + */ + err = esw_ipsec_vf_query_generic(dev, vport->index, &ipsec_enabled); + if (err) + return err; + if (!ipsec_enabled) { + *crypto = false; + return 0; + } + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + if (!query_cap) + return -ENOMEM; + + err = mlx5_vport_get_other_func_cap(dev, vport->index, query_cap, MLX5_CAP_IPSEC); + if (err) + goto out; + + hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + *crypto = MLX5_GET(ipsec_cap, hca_cap, ipsec_crypto_offload); +out: + kvfree(query_cap); + return err; +} + +static int esw_ipsec_vf_set_generic(struct mlx5_core_dev *dev, u16 vport_num, bool ipsec_ofld) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); + void *hca_cap = NULL, *query_cap = NULL, *cap; + int ret; + + if (!MLX5_CAP_GEN(dev, vhca_resource_manager)) + return -EOPNOTSUPP; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + hca_cap = kvzalloc(set_sz, GFP_KERNEL); + if (!hca_cap || !query_cap) { + ret = -ENOMEM; + goto out; + } + + ret = mlx5_vport_get_other_func_general_cap(dev, vport_num, query_cap); + if (ret) + goto out; + + cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); + memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), + MLX5_UN_SZ_BYTES(hca_cap_union)); + MLX5_SET(cmd_hca_cap, cap, ipsec_offload, ipsec_ofld); + + MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); + MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); + MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport_num); + + MLX5_SET(set_hca_cap_in, hca_cap, op_mod, + MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1); + ret = mlx5_cmd_exec_in(dev, set_hca_cap, hca_cap); +out: + kvfree(hca_cap); + kvfree(query_cap); + return ret; +} + +static int esw_ipsec_vf_set_bytype(struct mlx5_core_dev *dev, struct mlx5_vport *vport, + bool enable, enum esw_vport_ipsec_offload type) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); + void *hca_cap = NULL, *query_cap = NULL, *cap; + int ret; + + if (!MLX5_CAP_GEN(dev, vhca_resource_manager)) + return -EOPNOTSUPP; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + hca_cap = kvzalloc(set_sz, GFP_KERNEL); + if (!hca_cap || !query_cap) { + ret = -ENOMEM; + goto out; + } + + ret = mlx5_vport_get_other_func_cap(dev, vport->index, query_cap, MLX5_CAP_IPSEC); + if (ret) + goto out; + + cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); + memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), + MLX5_UN_SZ_BYTES(hca_cap_union)); + + switch (type) { + case MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD: + MLX5_SET(ipsec_cap, cap, ipsec_crypto_offload, enable); + break; + default: + ret = -EOPNOTSUPP; + goto out; + } + + MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); + MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); + MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport->index); + + MLX5_SET(set_hca_cap_in, hca_cap, op_mod, + MLX5_SET_HCA_CAP_OP_MOD_IPSEC << 1); + ret = mlx5_cmd_exec_in(dev, set_hca_cap, hca_cap); +out: + kvfree(hca_cap); + kvfree(query_cap); + return ret; +} + +static int esw_ipsec_vf_crypto_aux_caps_set(struct mlx5_core_dev *dev, u16 vport_num, bool enable) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); + void *hca_cap = NULL, *query_cap = NULL, *cap; + struct mlx5_eswitch *esw = dev->priv.eswitch; + int ret; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + hca_cap = kvzalloc(set_sz, GFP_KERNEL); + if (!hca_cap || !query_cap) { + ret = -ENOMEM; + goto out; + } + + ret = mlx5_vport_get_other_func_cap(dev, vport_num, query_cap, MLX5_CAP_ETHERNET_OFFLOADS); + if (ret) + goto out; + + cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); + memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), + MLX5_UN_SZ_BYTES(hca_cap_union)); + MLX5_SET(per_protocol_networking_offload_caps, cap, insert_trailer, enable); + MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); + MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); + MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport_num); + MLX5_SET(set_hca_cap_in, hca_cap, op_mod, + MLX5_SET_HCA_CAP_OP_MOD_ETHERNET_OFFLOADS << 1); + ret = mlx5_cmd_exec_in(esw->dev, set_hca_cap, hca_cap); +out: + kvfree(hca_cap); + kvfree(query_cap); + return ret; +} + +static int esw_ipsec_vf_offload_set_bytype(struct mlx5_eswitch *esw, struct mlx5_vport *vport, + bool enable, enum esw_vport_ipsec_offload type) +{ + struct mlx5_core_dev *dev = esw->dev; + int err = 0; + + if (vport->index == MLX5_VPORT_PF) + return -EOPNOTSUPP; + + if (!mlx5_esw_vport_ipsec_offload_enabled(esw) && mlx5_eswitch_ipsec_offloads_enabled(dev)) + return -EBUSY; + + if (type == MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD) { + err = esw_ipsec_vf_crypto_aux_caps_set(dev, vport->index, enable); + if (err) { + mlx5_core_dbg(dev, + "Failed to set auxiliary caps for ipsec_crypto_offload: %d\n", + err); + return err; + } + } + + if (enable) { + err = esw_ipsec_vf_set_generic(dev, vport->index, enable); + if (err) { + mlx5_core_dbg(dev, "Failed to enable generic ipsec_offload: %d\n", err); + return err; + } + err = esw_ipsec_vf_set_bytype(dev, vport, enable, type); + if (err) { + mlx5_core_dbg(dev, "Failed to enable ipsec_offload type %d: %d\n", type, + err); + return err; + } + } else { + err = esw_ipsec_vf_set_bytype(dev, vport, enable, type); + if (err) { + mlx5_core_dbg(dev, "Failed to disable ipsec_offload type %d: %d\n", type, + err); + return err; + } + err = esw_ipsec_vf_set_generic(dev, vport->index, enable); + if (err) { + mlx5_core_dbg(dev, "Failed to disable generic ipsec_offload: %d\n", + err); + return err; + } + } + + if (type == MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD) + vport->info.ipsec_crypto_enabled = enable; + + return err; +} + +static bool esw_ipsec_offload_supported(struct mlx5_core_dev *dev, u16 vport_num) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *hca_cap = NULL, *query_cap = NULL; + int err; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + if (!query_cap) + return false; + + err = mlx5_vport_get_other_func_cap(dev, vport_num, query_cap, MLX5_CAP_GENERAL); + if (err) + goto notsupported; + hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + if (!MLX5_GET(cmd_hca_cap, hca_cap, log_max_dek)) + goto notsupported; + + kvfree(query_cap); + return true; + +notsupported: + kvfree(query_cap); + return false; +} + +bool mlx5_esw_ipsec_vf_offload_supported(struct mlx5_core_dev *dev) +{ + /* Old firmware doesn't support ipsec_offload capability for VFs. This + * can be detected by checking reformat_add_esp_trasport capability - + * when this cap isn't supported it means firmware cannot be trusted + * about what it reports for ipsec_offload cap. + */ + return MLX5_CAP_FLOWTABLE_NIC_TX(dev, reformat_add_esp_trasport); +} + +bool mlx5_esw_ipsec_vf_crypto_offload_supported(struct mlx5_core_dev *dev, u16 vport_num) +{ + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *hca_cap = NULL, *query_cap = NULL; + int err; + + if (!mlx5_esw_ipsec_vf_offload_supported(dev)) + return false; + + if (!esw_ipsec_offload_supported(dev, vport_num)) + return false; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + if (!query_cap) + return false; + + err = mlx5_vport_get_other_func_cap(dev, vport_num, query_cap, MLX5_CAP_ETHERNET_OFFLOADS); + if (err) + goto notsupported; + hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + if (!MLX5_GET(per_protocol_networking_offload_caps, hca_cap, swp)) + goto notsupported; + + kvfree(query_cap); + return true; + +notsupported: + kvfree(query_cap); + return false; +} + +int mlx5_esw_ipsec_vf_offload_get(struct mlx5_core_dev *dev, struct mlx5_vport *vport, bool *crypto) +{ + return esw_ipsec_vf_query(dev, vport, crypto); +} + +int mlx5_esw_ipsec_vf_crypto_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, + bool enable) +{ + return esw_ipsec_vf_offload_set_bytype(esw, vport, enable, + MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD); +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 8bdf28762f41..e3b492a84f1b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -47,6 +47,7 @@ #include "devlink.h" #include "ecpf.h" #include "en/mod_hdr.h" +#include "en_accel/ipsec.h" enum { MLX5_ACTION_NONE = 0, @@ -782,6 +783,7 @@ static void esw_vport_cleanup_acl(struct mlx5_eswitch *esw, static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport *vport) { int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + bool ipsec_crypto_enabled; void *query_ctx; void *hca_caps; int err; @@ -809,6 +811,11 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport * hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); vport->info.mig_enabled = MLX5_GET(cmd_hca_cap_2, hca_caps, migratable); + + err = mlx5_esw_ipsec_vf_offload_get(esw->dev, vport, &ipsec_crypto_enabled); + if (err) + goto out_free; + vport->info.ipsec_crypto_enabled = ipsec_crypto_enabled; out_free: kfree(query_ctx); return err; @@ -873,6 +880,23 @@ static void esw_vport_cleanup(struct mlx5_eswitch *esw, struct mlx5_vport *vport esw_vport_cleanup_acl(esw, vport); } +void mlx5_esw_vport_ipsec_offload_enable(struct mlx5_eswitch *esw) +{ + esw->enabled_ipsec_vf_count++; + WARN_ON(!esw->enabled_ipsec_vf_count); +} + +void mlx5_esw_vport_ipsec_offload_disable(struct mlx5_eswitch *esw) +{ + esw->enabled_ipsec_vf_count--; + WARN_ON(esw->enabled_ipsec_vf_count == U16_MAX); +} + +bool mlx5_esw_vport_ipsec_offload_enabled(struct mlx5_eswitch *esw) +{ + return !!esw->enabled_ipsec_vf_count; +} + int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, enum mlx5_eswitch_vport_event enabled_events) { @@ -895,6 +919,8 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, /* Sync with current vport context */ vport->enabled_events = enabled_events; vport->enabled = true; + if (vport->vport != MLX5_VPORT_PF && vport->info.ipsec_crypto_enabled) + mlx5_esw_vport_ipsec_offload_enable(esw); /* Esw manager is trusted by default. Host PF (vport 0) is trusted as well * in smartNIC as it's a vport group manager. @@ -953,6 +979,9 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num) MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) mlx5_esw_vport_vhca_id_clear(esw, vport_num); + if (vport->vport != MLX5_VPORT_PF && vport->info.ipsec_crypto_enabled) + mlx5_esw_vport_ipsec_offload_disable(esw); + /* We don't assume VFs will cleanup after themselves. * Calling vport change handler while vport is disabled will cleanup * the vport resources. diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index e9d68fdf68f5..d1f469ec284b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -157,6 +157,7 @@ struct mlx5_vport_info { u8 trusted: 1; u8 roce_enabled: 1; u8 mig_enabled: 1; + u8 ipsec_crypto_enabled: 1; }; /* Vport context events */ @@ -344,6 +345,7 @@ struct mlx5_eswitch { } params; struct blocking_notifier_head n_head; struct dentry *dbgfs; + u16 enabled_ipsec_vf_count; }; void esw_offloads_disable(struct mlx5_eswitch *esw); @@ -520,6 +522,12 @@ int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enab struct netlink_ext_ack *extack); int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable, struct netlink_ext_ack *extack); +#ifdef CONFIG_XFRM +int mlx5_devlink_port_fn_ipsec_crypto_get(struct devlink_port *port, bool *is_enabled, + struct netlink_ext_ack *extack); +int mlx5_devlink_port_fn_ipsec_crypto_set(struct devlink_port *port, bool enable, + struct netlink_ext_ack *extack); +#endif /* CONFIG_XFRM */ void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, @@ -654,6 +662,16 @@ mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, enum mlx5_eswitch_vport_event enabled_events); void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw); +bool mlx5_esw_ipsec_vf_offload_supported(struct mlx5_core_dev *dev); +bool mlx5_esw_ipsec_vf_crypto_offload_supported(struct mlx5_core_dev *dev, u16 vport_num); +int mlx5_esw_ipsec_vf_offload_get(struct mlx5_core_dev *dev, struct mlx5_vport *vport, + bool *crypto); +int mlx5_esw_ipsec_vf_crypto_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, + bool enable); +void mlx5_esw_vport_ipsec_offload_enable(struct mlx5_eswitch *esw); +void mlx5_esw_vport_ipsec_offload_disable(struct mlx5_eswitch *esw); +bool mlx5_esw_vport_ipsec_offload_enabled(struct mlx5_eswitch *esw); + int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, enum mlx5_eswitch_vport_event enabled_events); void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num); @@ -819,6 +837,11 @@ static inline bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev) static inline void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev) { } + +static inline bool mlx5_esw_vport_ipsec_offload_enabled(struct mlx5_eswitch *esw) +{ + return false; +} #endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESWITCH_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index b6e2709c1371..d0cb80714f00 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -4204,3 +4204,108 @@ int mlx5_devlink_port_fn_roce_set(struct devlink_port *port, bool enable, mutex_unlock(&esw->state_lock); return err; } + +#ifdef CONFIG_XFRM +int mlx5_devlink_port_fn_ipsec_crypto_get(struct devlink_port *port, bool *is_enabled, + struct netlink_ext_ack *extack) +{ + struct mlx5_eswitch *esw; + struct mlx5_vport *vport; + int err = -EOPNOTSUPP; + + esw = mlx5_devlink_eswitch_get(port->devlink); + if (IS_ERR(esw)) + return PTR_ERR(esw); + + vport = mlx5_devlink_port_fn_get_vport(port, esw); + if (IS_ERR(vport)) { + NL_SET_ERR_MSG_MOD(extack, "Invalid port"); + return PTR_ERR(vport); + } + + if (!mlx5_esw_ipsec_vf_offload_supported(esw->dev)) { + NL_SET_ERR_MSG_MOD(extack, "Device doesn't support ipsec_crypto"); + return err; + } + + mutex_lock(&esw->state_lock); + if (vport->enabled) { + *is_enabled = vport->info.ipsec_crypto_enabled; + err = 0; + } + mutex_unlock(&esw->state_lock); + return err; +} + +int mlx5_devlink_port_fn_ipsec_crypto_set(struct devlink_port *port, bool enable, + struct netlink_ext_ack *extack) +{ + struct mlx5_eswitch *esw; + struct mlx5_vport *vport; + int err = -EOPNOTSUPP; + struct net *net; + u16 vport_num; + + esw = mlx5_devlink_eswitch_get(port->devlink); + if (IS_ERR(esw)) + return PTR_ERR(esw); + + vport = mlx5_devlink_port_fn_get_vport(port, esw); + if (IS_ERR(vport)) { + NL_SET_ERR_MSG_MOD(extack, "Invalid port"); + return PTR_ERR(vport); + } + + vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index); + if (!mlx5_esw_ipsec_vf_crypto_offload_supported(esw->dev, vport_num)) { + NL_SET_ERR_MSG_MOD(extack, + "Device doesn't support ipsec_crypto or capability is blocked"); + return err; + } + + /* xfrm_cfg lock is needed to avoid races with XFRM state being added to + * the PF net device. Netlink stack takes this lock for `ip xfrm` user + * commands, so here we need to take it before esw->state_lock to + * preserve the order. + */ + net = dev_net(esw->dev->mlx5e_res.uplink_netdev); + mutex_lock(&net->xfrm.xfrm_cfg_mutex); + + mutex_lock(&esw->state_lock); + if (!vport->enabled) { + NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled"); + goto out; + } + if (vport->info.ipsec_crypto_enabled == enable) { + err = 0; + goto out; + } + + err = mlx5_esw_ipsec_vf_crypto_offload_set(esw, vport, enable); + switch (err) { + case 0: + break; + case -EBUSY: + NL_SET_ERR_MSG_MOD(extack, + "Failed setting ipsec_crypto. Make sure ip xfrm state/policy is cleared on the PF."); + goto out; + case -EINVAL: + NL_SET_ERR_MSG_MOD(extack, + "Failed setting ipsec_crypto. Make sure to unbind the VF first"); + goto out; + default: + NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA ipsec_crypto_offload cap."); + goto out; + } + + vport->info.ipsec_crypto_enabled = enable; + if (enable) + mlx5_esw_vport_ipsec_offload_enable(esw); + else + mlx5_esw_vport_ipsec_offload_disable(esw); +out: + mutex_unlock(&esw->state_lock); + mutex_unlock(&net->xfrm.xfrm_cfg_mutex); + return err; +} +#endif /* CONFIG_XFRM */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec.h new file mode 100644 index 000000000000..cf0bca6d5f3e --- /dev/null +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef __MLX5_LIB_IPSEC_H__ +#define __MLX5_LIB_IPSEC_H__ + +#include + +#ifdef CONFIG_MLX5_EN_IPSEC + +/* The caller must hold mlx5_eswitch->state_lock */ +static inline void mlx5_eswitch_ipsec_offloads_count_inc(struct mlx5_core_dev *mdev) +{ + WARN_ON(mdev->ipsec_offloads_count == U64_MAX); + mdev->ipsec_offloads_count++; +} + +/* The caller must hold mlx5_eswitch->state_lock */ +static inline void mlx5_eswitch_ipsec_offloads_count_dec(struct mlx5_core_dev *mdev) +{ + WARN_ON(mdev->ipsec_offloads_count == 0); + mdev->ipsec_offloads_count--; +} + +/* The caller must hold mlx5_eswitch->state_lock */ +static inline bool mlx5_eswitch_ipsec_offloads_enabled(struct mlx5_core_dev *mdev) +{ + return !!mdev->ipsec_offloads_count; +} +#else +static inline void mlx5_eswitch_ipsec_offloads_count_inc(struct mlx5_core_dev *mdev) { } + +static inline void mlx5_eswitch_ipsec_offloads_count_dec(struct mlx5_core_dev *mdev) { } + +static inline bool mlx5_eswitch_ipsec_offloads_enabled(struct mlx5_core_dev *mdev) +{ + return false; +} +#endif /* CONFIG_MLX5_EN_IPSEC */ + +#endif /* __MLX5_LIB_IPSEC_H__ */ diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 135a3c8d8237..5c2ad022879f 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -812,6 +812,7 @@ struct mlx5_core_dev { u32 vsc_addr; struct mlx5_hv_vhca *hv_vhca; struct mlx5_thermal *thermal; + u64 ipsec_offloads_count; }; struct mlx5_db { diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 20d00e09b168..e1ee4cf4799f 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -65,9 +65,11 @@ enum { enum { MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0, + MLX5_SET_HCA_CAP_OP_MOD_ETHERNET_OFFLOADS = 0x1, MLX5_SET_HCA_CAP_OP_MOD_ODP = 0x2, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC = 0x3, MLX5_SET_HCA_CAP_OP_MOD_ROCE = 0x4, + MLX5_SET_HCA_CAP_OP_MOD_IPSEC = 0x15, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2 = 0x20, MLX5_SET_HCA_CAP_OP_MODE_PORT_SELECTION = 0x25, }; @@ -3477,6 +3479,7 @@ union mlx5_ifc_hca_cap_union_bits { struct mlx5_ifc_shampo_cap_bits shampo_cap; struct mlx5_ifc_macsec_cap_bits macsec_cap; struct mlx5_ifc_crypto_cap_bits crypto_cap; + struct mlx5_ifc_ipsec_cap_bits ipsec_cap; u8 reserved_at_0[0x8000]; }; From patchwork Fri Apr 21 10:49:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dima Chumak X-Patchwork-Id: 13219800 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18BD7C77B75 for ; Fri, 21 Apr 2023 10:50:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231542AbjDUKuA (ORCPT ); Fri, 21 Apr 2023 06:50:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40004 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229825AbjDUKtv (ORCPT ); Fri, 21 Apr 2023 06:49:51 -0400 Received: from NAM04-DM6-obe.outbound.protection.outlook.com (mail-dm6nam04on2077.outbound.protection.outlook.com [40.107.102.77]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5572B6E92 for ; Fri, 21 Apr 2023 03:49:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QQQJnBnaRsNWkZiLsyOMJ/SGKTwd32o26DcLeCWsFQ6CVkMSOIVuE54fLNQPh9mXj+CVcm6VpO9IaRW+jt4N0eH/JjEPXpQsYc6bf6gvIrIdq8RcberZkAnfwpEImBAxZfVHoKa7ydQWgIJx7S2BHSypMcclkzwWMOY8rUgZA8HO2ag2I0sakGQRjOscoL7yi15xWyx/pSqyjsNH07wSFtXz5bepwWDs4hruKiVJ+tbK8KFbyjemYoLp1WQfqg1w+yQD9uePyK/hi43fVpp30oDniGJNXB+NJwNoCzNoh0MaI1dyYVSmFLEg0SoZAsEBs81qq48mj8/JxjlRdM9NXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=h/8fzqFBSSJ1v1rH0wsmzXvevh0TGzu+UtY3Pmgutt0=; b=WpCNs/C75eUJcmn8RjbUzNCTxIYloD9+UlxwjX3SggjPXB7fJLNw+zFN9yrhtLEDMs0CSKYDhHyNImUSuqIStTqe2kCAM96MwWxAh1JR/sHu/vFTVhsM4Sa4Bxff6qgetRFDQy456ma9sSunzNfanEr6okSl/F74lnE984QOe4j+CgDT5blqV+rwjrA/i6gDC5qw650QNfQW2LrLhYTRDjwLdFi+wP2bvX3e2jA7pNPHSarFBW2oCKeELvCv1mg8u9bGMluYgNN+uxni+qT9g57H1fnVqPqqNEjQ48/NsAvgDt3QuixS5qmQ7F0ebeHyIZSeN/pjEwN0hVjPrw6s5w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.233) smtp.rcpttodomain=davemloft.net smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=h/8fzqFBSSJ1v1rH0wsmzXvevh0TGzu+UtY3Pmgutt0=; b=CHOfZZmAu5S8MNgmmDAJu4H92VDKJnK3vw/JeT+PvoaUb6VYOIcCDbC51v2tHHhYgIAg9bhxh58JNGxvmEwzowxVLJqdWxZHZrhjtjhtUuGpYAm+pGbAhm1Wd99JNa3/c/6WuyN7a1y7xbKwYiNOeiaZV5cXdo6vypbA3WnhJli50JWWMmcQWGKIpQVEo9vm21M++U0fgB2+oGwfbstPEyKkshxHZrN2AlobyDvj0g8OoOoMnUN0O+fg3u8D4mH5wJrmfVCrFB+47J+WDWQH2ZKz0pLTuyzAB2MCSkMJxR39g84D8UnfY59NG/MpV6kijVnadcC932Kch7q0dCfk8A== Received: from BN1PR13CA0030.namprd13.prod.outlook.com (2603:10b6:408:e2::35) by MN0PR12MB5905.namprd12.prod.outlook.com (2603:10b6:208:379::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.30; Fri, 21 Apr 2023 10:49:48 +0000 Received: from BN8NAM11FT085.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e2:cafe::43) by BN1PR13CA0030.outlook.office365.com (2603:10b6:408:e2::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.11 via Frontend Transport; Fri, 21 Apr 2023 10:49:48 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.233) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.233 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.233; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.233) by BN8NAM11FT085.mail.protection.outlook.com (10.13.176.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.27 via Frontend Transport; Fri, 21 Apr 2023 10:49:47 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Fri, 21 Apr 2023 03:49:41 -0700 Received: from drhqmail202.nvidia.com (10.126.190.181) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Fri, 21 Apr 2023 03:49:40 -0700 Received: from vdi.nvidia.com (10.127.8.13) by mail.nvidia.com (10.126.190.181) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Fri, 21 Apr 2023 03:49:38 -0700 From: Dima Chumak To: "David S. Miller" , Jakub Kicinski , Eric Dumazet , Paolo Abeni CC: , Jiri Pirko , Leon Romanovsky , Saeed Mahameed , Dima Chumak , Jiri Pirko Subject: [PATCH net-next V2 3/4] devlink: Expose port function commands to control IPsec packet offloads Date: Fri, 21 Apr 2023 13:49:00 +0300 Message-ID: <20230421104901.897946-4-dchumak@nvidia.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230421104901.897946-1-dchumak@nvidia.com> References: <20230421104901.897946-1-dchumak@nvidia.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT085:EE_|MN0PR12MB5905:EE_ X-MS-Office365-Filtering-Correlation-Id: 760624b5-0dae-49b1-9925-08db4256206e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: G7HlM5XQvX35ZwsIbSiPt2WqQk5BVnBtnWpWNcJfWnAJpqNI0JsOtijShSHu0cvl7ZzeQSirhO2gy1IFZNC/ZKPmg+tsDeQBk9jt6IQ2f0Kv+lyTGJlmxDi65oMlcN8Isr/M87cQZADywd241vjISHaqPIayMkqWFIV5yIPp3qvn1QFAYWF9B8wkJBsFbVnYPBTXQsHq+Xl7BuWSHv9TjG7vVTISLvUp410MmLNiiOjeE6ixFZogHIbcSx7UogFfuSIQBUP3xeEit4RgX7+CXxpxbnIuOThKdkDTBFbmxX5CMBdaBKdwer97+uY+zvuoPaswsQ1kas9A5Wl0dVYu9t9K4umoRoa4R9cdG2GvX/OiCm3FHEK7lApzAfaXLBi0d2oy5J8podOFU7C/DhIWGQrYdAB/7HI16qpaiDrsi9+vkpGLRpUduJjJspSXE+9jjJbmTvH0VZYxWulAJQLxyLhwbifLvP2n9Bs+hw4ASgMNDKleR6QEDvLKrgwN6/Pk9HPg0Tn1HI0n6+OnEw1lVOUTt/aH7cF3gPmySSW8wcqIB5siudptmA7nxkkhM/Da5zbStkYcwUP3HH/BRDMULrlZISB4ueVcCQiKqa6/kA4tV4H6NBxnhtqEWRGesS+MhWtBdD1i7qLn114FiEufw5DxVirogO5DuLVi/XtalAqvhQAgKVBCMCEm2cB/cwggVYHcH4CcnVJdDAjdLXEIqIda+PNO+4u+jlshB8VVdpT5jmDpxDR5eIXRDoFJg05J4hYjs/RyYW4c0sg9N5gjV5lKjaX6gOzDw5QYN7PSKtk= X-Forefront-Antispam-Report: CIP:216.228.118.233;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge2.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(396003)(39860400002)(346002)(136003)(376002)(451199021)(40470700004)(36840700001)(46966006)(5660300002)(7696005)(40460700003)(2906002)(4326008)(70206006)(36756003)(70586007)(8936002)(41300700001)(6666004)(7636003)(356005)(316002)(82310400005)(8676002)(34020700004)(86362001)(478600001)(82740400003)(40480700001)(54906003)(110136005)(1076003)(26005)(426003)(336012)(36860700001)(107886003)(83380400001)(186003)(2616005)(47076005);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Apr 2023 10:49:47.9922 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 760624b5-0dae-49b1-9925-08db4256206e X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.233];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT085.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR12MB5905 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Expose port function commands to enable / disable IPsec packet offloads, this is used to control the port IPsec capabilities. When IPsec packet is disabled for a function of the port (default), function cannot offload IPsec packet operations (encapsulation and XFRM policy offload). When enabled, IPsec packet operations can be offloaded by the function of the port, which includes crypto operation (Encrypt/Decrypt), IPsec encapsulation and XFRM state and policy offload. Example of a PCI VF port which supports IPsec packet offloads: $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable ipsec_packet disable $ devlink port function set pci/0000:06:00.0/1 ipsec_packet enable $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable ipsec_packet enable Signed-off-by: Dima Chumak Reviewed-by: Jiri Pirko --- .../networking/devlink/devlink-port.rst | 28 ++++++++++ include/net/devlink.h | 21 +++++++ include/uapi/linux/devlink.h | 2 + net/devlink/leftover.c | 55 +++++++++++++++++++ 4 files changed, 106 insertions(+) diff --git a/Documentation/networking/devlink/devlink-port.rst b/Documentation/networking/devlink/devlink-port.rst index 6983b11559cb..f5adb910427a 100644 --- a/Documentation/networking/devlink/devlink-port.rst +++ b/Documentation/networking/devlink/devlink-port.rst @@ -131,6 +131,9 @@ Users may also set the function as migratable using Users may also set the IPsec crypto capability of the function using `devlink port function set ipsec_crypto` command. +Users may also set the IPsec packet capability of the function using +`devlink port function set ipsec_packet` command. + Function attributes =================== @@ -267,6 +270,31 @@ processed in software by the kernel. function: hw_addr 00:00:00:00:00:00 ipsec_crypto enabled +IPsec packet capability setup +----------------------------- +When user enables IPsec packet capability for a VF, user application can offload +XFRM state and policy crypto operation (Encrypt/Decrypt) to this VF, as well as +IPsec encapsulation. + +When IPsec packet capability is disabled (default) for a VF, the XFRM state and +policy is processed in software by the kernel. + +- Get IPsec packet capability of the VF device:: + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:00:00:00:00:00 ipsec_packet disabled + +- Set IPsec packet capability of the VF device:: + + $ devlink port function set pci/0000:06:00.0/2 ipsec_packet enable + + $ devlink port show pci/0000:06:00.0/2 + pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1 + function: + hw_addr 00:00:00:00:00:00 ipsec_packet enabled + Subfunction ============ diff --git a/include/net/devlink.h b/include/net/devlink.h index 4e5f4aeca29d..772453b36c20 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1516,6 +1516,27 @@ struct devlink_ops { int (*port_fn_ipsec_crypto_set)(struct devlink_port *devlink_port, bool enable, struct netlink_ext_ack *extack); + /** + * @port_fn_ipsec_packet_get: Port function's ipsec_packet get function. + * + * Query ipsec_packet state of a function managed by the devlink port. + * Return -EOPNOTSUPP if port function IPsec packet offload is not + * supported. + */ + int (*port_fn_ipsec_packet_get)(struct devlink_port *devlink_port, + bool *is_enable, + struct netlink_ext_ack *extack); + /** + * @port_fn_ipsec_packet_set: Port function's ipsec_packet set function. + * + * Enable/Disable ipsec_packet state of a function managed by the devlink + * port. + * Return -EOPNOTSUPP if port function IPsec packet offload is not + * supported. + */ + int (*port_fn_ipsec_packet_set)(struct devlink_port *devlink_port, + bool enable, + struct netlink_ext_ack *extack); /** * port_new() - Add a new port function of a specified flavor * @devlink: Devlink instance diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index f9ae9a058ad2..03875e078be8 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -662,6 +662,7 @@ enum devlink_port_fn_attr_cap { DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT, DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT, DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT, + DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT, /* Add new caps above */ __DEVLINK_PORT_FN_ATTR_CAPS_MAX, @@ -671,6 +672,7 @@ enum devlink_port_fn_attr_cap { #define DEVLINK_PORT_FN_CAP_MIGRATABLE \ _BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT) #define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT) +#define DEVLINK_PORT_FN_CAP_IPSEC_PACKET _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT) enum devlink_port_function_attr { DEVLINK_PORT_FUNCTION_ATTR_UNSPEC, diff --git a/net/devlink/leftover.c b/net/devlink/leftover.c index 07761df2471d..8cadfeb285a9 100644 --- a/net/devlink/leftover.c +++ b/net/devlink/leftover.c @@ -515,6 +515,29 @@ static int devlink_port_fn_ipsec_crypto_fill(const struct devlink_ops *ops, return 0; } +static int devlink_port_fn_ipsec_packet_fill(const struct devlink_ops *ops, + struct devlink_port *devlink_port, + struct nla_bitfield32 *caps, + struct netlink_ext_ack *extack) +{ + bool is_enable; + int err; + + if (!ops->port_fn_ipsec_packet_get || + devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) + return 0; + + err = ops->port_fn_ipsec_packet_get(devlink_port, &is_enable, extack); + if (err) { + if (err == -EOPNOTSUPP) + return 0; + return err; + } + + devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_IPSEC_PACKET, is_enable); + return 0; +} + static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, struct devlink_port *devlink_port, struct sk_buff *msg, @@ -536,6 +559,10 @@ static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, if (err) return err; + err = devlink_port_fn_ipsec_packet_fill(ops, devlink_port, &caps, extack); + if (err) + return err; + if (!caps.selector) return 0; err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value, @@ -879,6 +906,15 @@ devlink_port_fn_ipsec_crypto_set(struct devlink_port *devlink_port, bool enable, return ops->port_fn_ipsec_crypto_set(devlink_port, enable, extack); } +static int +devlink_port_fn_ipsec_packet_set(struct devlink_port *devlink_port, bool enable, + struct netlink_ext_ack *extack) +{ + const struct devlink_ops *ops = devlink_port->devlink->ops; + + return ops->port_fn_ipsec_packet_set(devlink_port, enable, extack); +} + static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, const struct nlattr *attr, struct netlink_ext_ack *extack) @@ -910,6 +946,13 @@ static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, if (err) return err; } + if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_PACKET) { + err = devlink_port_fn_ipsec_packet_set(devlink_port, caps_value & + DEVLINK_PORT_FN_CAP_IPSEC_PACKET, + extack); + if (err) + return err; + } return 0; } @@ -1290,6 +1333,18 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port, return -EOPNOTSUPP; } } + if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_PACKET) { + if (!ops->port_fn_ipsec_packet_set) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "Port doesn't support ipsec_packet function attribute"); + return -EOPNOTSUPP; + } + if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "ipsec_packet function attribute supported for VFs only"); + return -EOPNOTSUPP; + } + } } return 0; } From patchwork Fri Apr 21 10:49:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dima Chumak X-Patchwork-Id: 13219801 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D5E4C7618E for ; Fri, 21 Apr 2023 10:50:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231478AbjDUKuC (ORCPT ); Fri, 21 Apr 2023 06:50:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231562AbjDUKtz (ORCPT ); Fri, 21 Apr 2023 06:49:55 -0400 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2041.outbound.protection.outlook.com [40.107.220.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91B13C166 for ; Fri, 21 Apr 2023 03:49:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VNm7+BHuANsfhVGuyHhu65e68K116zaWTwwFLdmmGx3QlldfRt50ZViATzTTCRj/FPQ82lS/wq4UliE83bhLhZG1tOG4x1ONkmfeE33kqSziEQjZm76PVWWrDYakBHsgs9s5xIBZh+O6U+/zUz85ACXOiP61eNhc4f453sLSc0wXgwaxJYLPhsRz7VMAnQN/KLKPN9ouv997YQZeePm8pJx/wFN0gu6tYt1ccnZeMr3OzzTgzeUysNrdZP3O5/L5TgfyRHAfehEb6yKf7s3/uk2P5vvKg7dfVfcdQCIIrpHdPI0KnJ0lQYp7RlF0UMKBvBJoJVF7kMFXHV4fagczHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=M/k7mkvDISXN2/xms8RX0SOk765W/UBxs6XS8Ua9Dcw=; b=VaoLGupTRg98ty5WV8IwVwe444ZB9OAsa2+tYD7keusyEOYmP61yuOfXOMV9DIeEQUy9pitsBqDWl/bjueTL+EBWPeTpnk44CvfyOeZfjgLtUaoxrEcaBp+WzIbO/JRflMjYaXDOxmP9Aae+mIxnEDdfrWKsc8pAQ4goE+xbpJuNUXJmIfD3fVeKyBPu5Ma2gvLtcKsEhcJy5Kkhpz91Wkv1xtCp6sFbDCPkQmO9uhcOvkNu2L4SmeIrh+x95DCkMZBuHDkT/RIy97TcJH+RMFHWGy7XAY3YqNdChseZBsDZbv7Abm017OHZFaaO85WoKWTjUGDCtHg8EPxnfiDzTQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.233) smtp.rcpttodomain=davemloft.net smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=M/k7mkvDISXN2/xms8RX0SOk765W/UBxs6XS8Ua9Dcw=; b=S800FCx9FBTrxGGd76OyphujkV4ybYJrKRzEyCfQWMXe3cL9lEVNNlQLEiaVXTCAC1ZyXLdoYGAFMfAH51eHwnCXNm7SCCcfIObnAzPToZG4Yu+k15WJ2ZdBrlxHSAvM+betv3w/dgaBiRkbRk4Vvwt2BD1KVdAHX/1NSFDINx2beLwzLRmTFoX5LjwrU9gF6YNuH7gwltDM1WfQjiD+6QLmHK8fb0nYJBOm1BNvKMJCxjhgDVNBHmRVu7S2PCvgjNBJvU5nBSiFVf3cYcwQR7+8N8zJ78COIQVIPLWtnajf4FXBcEktN373Z4NG4AsQwIqhz0kewgzRYc6jqLpzVw== Received: from BN1PR13CA0009.namprd13.prod.outlook.com (2603:10b6:408:e2::14) by DM4PR12MB6614.namprd12.prod.outlook.com (2603:10b6:8:bb::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.22; Fri, 21 Apr 2023 10:49:49 +0000 Received: from BN8NAM11FT085.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e2:cafe::9d) by BN1PR13CA0009.outlook.office365.com (2603:10b6:408:e2::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.11 via Frontend Transport; Fri, 21 Apr 2023 10:49:49 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.233) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.233 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.233; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.118.233) by BN8NAM11FT085.mail.protection.outlook.com (10.13.176.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.27 via Frontend Transport; Fri, 21 Apr 2023 10:49:49 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Fri, 21 Apr 2023 03:49:43 -0700 Received: from drhqmail202.nvidia.com (10.126.190.181) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Fri, 21 Apr 2023 03:49:43 -0700 Received: from vdi.nvidia.com (10.127.8.13) by mail.nvidia.com (10.126.190.181) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Fri, 21 Apr 2023 03:49:41 -0700 From: Dima Chumak To: "David S. Miller" , Jakub Kicinski , Eric Dumazet , Paolo Abeni CC: , Jiri Pirko , Leon Romanovsky , Saeed Mahameed , Dima Chumak Subject: [PATCH net-next V2 4/4] net/mlx5: Implement devlink port function cmds to control ipsec_packet Date: Fri, 21 Apr 2023 13:49:01 +0300 Message-ID: <20230421104901.897946-5-dchumak@nvidia.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230421104901.897946-1-dchumak@nvidia.com> References: <20230421104901.897946-1-dchumak@nvidia.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT085:EE_|DM4PR12MB6614:EE_ X-MS-Office365-Filtering-Correlation-Id: 5c8ed03b-0138-4133-3bfd-08db42562158 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yLfKZUXeY/G7TiP/IJQc6qGWM3IIyjB769vlADDJKmhDxXnxbW8Twm4yrtTOnX6EmGGD/EuFeUicXrnsq3ZDwHMcnfWbmF7BCkSOq1b8y8t58D3DQFtrcuAmol5o/aMlbrhBN4PGKcTwtCZu70V1faRBRHJckKfFQewpsH95Litxrju/xMdfNrCE25O8UKB5qN/wFTuePJ24lDJZcvrSWwgttkLHkyVbes2qN7RKOCB/TFpXZu5BcUid2kj+676ZuGZ2tu/gst1uZYfZm859g1ru02++9O0Q/LZYT2HtGxdNhs2cTPF10h4BwmaYoB0PO3C6VQqAkIxk8vDfBHE/INm0Op7qNJ/F9T4dSc6AXJV7rrS8mvmv3E9tCmzgfgiXJRWURpGkYf0KnHFk6gicxSTP1APgWysrPoOo+ZQ8Y2zgR4ia2pZDYszBkub9ZQ9ru9sFfCHSdknm3EstSV+P9DU9jglMrT95SagyOWhFxOFcjqwOZx4K7SMjU8/3ry2e4oLojGXu1NRbgeLTk9ZfSDKJCY2ygvTtLdiHt/qiIXI3V9r04Vf+avQvc8zSHQEUQPfSaAUZ0rv5HzFt+EZ3kEnHPoxByHtvS1Xq2fRue4vnLTpEKXKbnFC+EGuiL03Nq2iIrEmfg/z/4oXStjc1AICdo6qz5h8fA0OB7XRVTXTnTxvAKWACSSDNEMDC0Oj/ytfpjkO1rWflILOf9UnHndlUSiSFRVYSZaE3SNyLha4MwlATYxwQz/imzqWRM65BvVkw0EVu5Q1rc66H8cJJEFeFch1OfRGpdDQ60E2k68A= X-Forefront-Antispam-Report: CIP:216.228.118.233;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc7edge2.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(39860400002)(136003)(396003)(346002)(376002)(451199021)(46966006)(36840700001)(40470700004)(82310400005)(1076003)(26005)(40460700003)(40480700001)(82740400003)(186003)(110136005)(86362001)(70586007)(41300700001)(6666004)(7696005)(70206006)(36756003)(83380400001)(478600001)(54906003)(316002)(4326008)(7636003)(356005)(107886003)(36860700001)(8676002)(8936002)(2906002)(30864003)(336012)(5660300002)(2616005)(34020700004)(426003)(47076005);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Apr 2023 10:49:49.5233 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5c8ed03b-0138-4133-3bfd-08db42562158 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.233];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT085.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6614 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Implement devlink port function commands to enable / disable IPsec packet offloads. This is used to control the IPsec capability of the device. When ipsec_offload is enabled for a VF, it prevents adding IPsec packet offloads on the PF, because the two cannot be active simultaneously due to HW constraints. Conversely, if there are any active IPsec packet offloads on the PF, it's not allowed to enable ipsec_packet on a VF, until PF IPsec offloads are cleared. Signed-off-by: Dima Chumak --- v1 - >v2: - Fix build when CONFIG_XFRM is not set. - Perform additional capability checks to test if ipsec_packet offload is supported by the HW --- .../ethernet/mellanox/mlx5/switchdev.rst | 8 ++ .../net/ethernet/mellanox/mlx5/core/devlink.c | 2 + .../ethernet/mellanox/mlx5/core/esw/ipsec.c | 71 +++++++++++- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 11 +- .../net/ethernet/mellanox/mlx5/core/eswitch.h | 10 +- .../mellanox/mlx5/core/eswitch_offloads.c | 103 ++++++++++++++++++ 6 files changed, 195 insertions(+), 10 deletions(-) diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst index 9a41da6b33ff..ccfb02e7c2ad 100644 --- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst +++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst @@ -176,6 +176,14 @@ to explicitly enable the VF ipsec_crypto capability. mlx5 driver support devlink port function attr mechanism to setup ipsec_crypto capability. (refer to Documentation/networking/devlink/devlink-port.rst) +IPsec packet capability setup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User who wants mlx5 PCI VFs to be able to perform IPsec packet offloading need +to explicitly enable the VF ipsec_packet capability. + +mlx5 driver support devlink port function attr mechanism to setup ipsec_packet +capability. (refer to Documentation/networking/devlink/devlink-port.rst) + SF state setup -------------- diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index e1c7cd11444f..2c9ecbcb7687 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -327,6 +327,8 @@ static const struct devlink_ops mlx5_devlink_ops = { #ifdef CONFIG_XFRM .port_fn_ipsec_crypto_get = mlx5_devlink_port_fn_ipsec_crypto_get, .port_fn_ipsec_crypto_set = mlx5_devlink_port_fn_ipsec_crypto_set, + .port_fn_ipsec_packet_get = mlx5_devlink_port_fn_ipsec_packet_get, + .port_fn_ipsec_packet_set = mlx5_devlink_port_fn_ipsec_packet_set, #endif /* CONFIG_XFRM */ #endif /* CONFIG_MLX5_ESWITCH */ #ifdef CONFIG_MLX5_SF_MANAGER diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c index 5da5fc17cafb..d9fa154a2a3d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c @@ -38,9 +38,11 @@ static int esw_ipsec_vf_query_generic(struct mlx5_core_dev *dev, u16 vport_num, enum esw_vport_ipsec_offload { MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD, + MLX5_ESW_VPORT_IPSEC_PACKET_OFFLOAD, }; -static int esw_ipsec_vf_query(struct mlx5_core_dev *dev, struct mlx5_vport *vport, bool *crypto) +static int esw_ipsec_vf_query(struct mlx5_core_dev *dev, struct mlx5_vport *vport, + bool *crypto, bool *packet) { int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); void *hca_cap = NULL, *query_cap = NULL; @@ -55,6 +57,7 @@ static int esw_ipsec_vf_query(struct mlx5_core_dev *dev, struct mlx5_vport *vpor return err; if (!ipsec_enabled) { *crypto = false; + *packet = false; return 0; } @@ -68,6 +71,7 @@ static int esw_ipsec_vf_query(struct mlx5_core_dev *dev, struct mlx5_vport *vpor hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); *crypto = MLX5_GET(ipsec_cap, hca_cap, ipsec_crypto_offload); + *packet = MLX5_GET(ipsec_cap, hca_cap, ipsec_full_offload); out: kvfree(query_cap); return err; @@ -142,6 +146,9 @@ static int esw_ipsec_vf_set_bytype(struct mlx5_core_dev *dev, struct mlx5_vport case MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD: MLX5_SET(ipsec_cap, cap, ipsec_crypto_offload, enable); break; + case MLX5_ESW_VPORT_IPSEC_PACKET_OFFLOAD: + MLX5_SET(ipsec_cap, cap, ipsec_full_offload, enable); + break; default: ret = -EOPNOTSUPP; goto out; @@ -199,6 +206,7 @@ static int esw_ipsec_vf_offload_set_bytype(struct mlx5_eswitch *esw, struct mlx5 bool enable, enum esw_vport_ipsec_offload type) { struct mlx5_core_dev *dev = esw->dev; + bool crypto_enabled, packet_enabled; int err = 0; if (vport->index == MLX5_VPORT_PF) @@ -236,16 +244,28 @@ static int esw_ipsec_vf_offload_set_bytype(struct mlx5_eswitch *esw, struct mlx5 err); return err; } - err = esw_ipsec_vf_set_generic(dev, vport->index, enable); + err = mlx5_esw_ipsec_vf_offload_get(dev, vport, &crypto_enabled, &packet_enabled); if (err) { - mlx5_core_dbg(dev, "Failed to disable generic ipsec_offload: %d\n", - err); + mlx5_core_dbg(dev, "Failed to get ipsec_offload caps: %d\n", err); return err; } + /* The generic ipsec_offload cap can be disabled only if both + * ipsec_crypto_offload and ipsec_full_offload aren't enabled. + */ + if (!crypto_enabled && !packet_enabled) { + err = esw_ipsec_vf_set_generic(dev, vport->index, enable); + if (err) { + mlx5_core_dbg(dev, "Failed to disable generic ipsec_offload: %d\n", + err); + return err; + } + } } if (type == MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD) vport->info.ipsec_crypto_enabled = enable; + else if (type == MLX5_ESW_VPORT_IPSEC_PACKET_OFFLOAD) + vport->info.ipsec_packet_enabled = enable; return err; } @@ -316,9 +336,41 @@ bool mlx5_esw_ipsec_vf_crypto_offload_supported(struct mlx5_core_dev *dev, u16 v return false; } -int mlx5_esw_ipsec_vf_offload_get(struct mlx5_core_dev *dev, struct mlx5_vport *vport, bool *crypto) +bool mlx5_esw_ipsec_vf_packet_offload_supported(struct mlx5_core_dev *dev, u16 vport_num) { - return esw_ipsec_vf_query(dev, vport, crypto); + int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); + void *hca_cap = NULL, *query_cap = NULL; + int err; + + if (!mlx5_esw_ipsec_vf_offload_supported(dev)) + return false; + + if (!esw_ipsec_offload_supported(dev, vport_num)) + return false; + + query_cap = kvzalloc(query_sz, GFP_KERNEL); + if (!query_cap) + return false; + + err = mlx5_vport_get_other_func_cap(dev, vport_num, query_cap, MLX5_CAP_FLOW_TABLE); + if (err) + goto notsupported; + hca_cap = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + if (!MLX5_GET(flow_table_nic_cap, hca_cap, flow_table_properties_nic_receive.decap)) + goto notsupported; + + kvfree(query_cap); + return true; + +notsupported: + kvfree(query_cap); + return false; +} + +int mlx5_esw_ipsec_vf_offload_get(struct mlx5_core_dev *dev, struct mlx5_vport *vport, + bool *crypto, bool *packet) +{ + return esw_ipsec_vf_query(dev, vport, crypto, packet); } int mlx5_esw_ipsec_vf_crypto_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, @@ -327,3 +379,10 @@ int mlx5_esw_ipsec_vf_crypto_offload_set(struct mlx5_eswitch *esw, struct mlx5_v return esw_ipsec_vf_offload_set_bytype(esw, vport, enable, MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD); } + +int mlx5_esw_ipsec_vf_packet_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, + bool enable) +{ + return esw_ipsec_vf_offload_set_bytype(esw, vport, enable, + MLX5_ESW_VPORT_IPSEC_PACKET_OFFLOAD); +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index e3b492a84f1b..9d2ccb748d3b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -784,6 +784,7 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport * { int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); bool ipsec_crypto_enabled; + bool ipsec_packet_enabled; void *query_ctx; void *hca_caps; int err; @@ -812,10 +813,12 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport * hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); vport->info.mig_enabled = MLX5_GET(cmd_hca_cap_2, hca_caps, migratable); - err = mlx5_esw_ipsec_vf_offload_get(esw->dev, vport, &ipsec_crypto_enabled); + err = mlx5_esw_ipsec_vf_offload_get(esw->dev, vport, &ipsec_crypto_enabled, + &ipsec_packet_enabled); if (err) goto out_free; vport->info.ipsec_crypto_enabled = ipsec_crypto_enabled; + vport->info.ipsec_packet_enabled = ipsec_packet_enabled; out_free: kfree(query_ctx); return err; @@ -919,7 +922,8 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, /* Sync with current vport context */ vport->enabled_events = enabled_events; vport->enabled = true; - if (vport->vport != MLX5_VPORT_PF && vport->info.ipsec_crypto_enabled) + if (vport->vport != MLX5_VPORT_PF && + (vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled)) mlx5_esw_vport_ipsec_offload_enable(esw); /* Esw manager is trusted by default. Host PF (vport 0) is trusted as well @@ -979,7 +983,8 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num) MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) mlx5_esw_vport_vhca_id_clear(esw, vport_num); - if (vport->vport != MLX5_VPORT_PF && vport->info.ipsec_crypto_enabled) + if (vport->vport != MLX5_VPORT_PF && + (vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled)) mlx5_esw_vport_ipsec_offload_disable(esw); /* We don't assume VFs will cleanup after themselves. diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index d1f469ec284b..59cd0254498b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -158,6 +158,7 @@ struct mlx5_vport_info { u8 roce_enabled: 1; u8 mig_enabled: 1; u8 ipsec_crypto_enabled: 1; + u8 ipsec_packet_enabled: 1; }; /* Vport context events */ @@ -527,6 +528,10 @@ int mlx5_devlink_port_fn_ipsec_crypto_get(struct devlink_port *port, bool *is_en struct netlink_ext_ack *extack); int mlx5_devlink_port_fn_ipsec_crypto_set(struct devlink_port *port, bool enable, struct netlink_ext_ack *extack); +int mlx5_devlink_port_fn_ipsec_packet_get(struct devlink_port *port, bool *is_enabled, + struct netlink_ext_ack *extack); +int mlx5_devlink_port_fn_ipsec_packet_set(struct devlink_port *port, bool enable, + struct netlink_ext_ack *extack); #endif /* CONFIG_XFRM */ void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); @@ -664,10 +669,13 @@ void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw); bool mlx5_esw_ipsec_vf_offload_supported(struct mlx5_core_dev *dev); bool mlx5_esw_ipsec_vf_crypto_offload_supported(struct mlx5_core_dev *dev, u16 vport_num); +bool mlx5_esw_ipsec_vf_packet_offload_supported(struct mlx5_core_dev *dev, u16 vport_num); int mlx5_esw_ipsec_vf_offload_get(struct mlx5_core_dev *dev, struct mlx5_vport *vport, - bool *crypto); + bool *crypto, bool *packet); int mlx5_esw_ipsec_vf_crypto_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, bool enable); +int mlx5_esw_ipsec_vf_packet_offload_set(struct mlx5_eswitch *esw, struct mlx5_vport *vport, + bool enable); void mlx5_esw_vport_ipsec_offload_enable(struct mlx5_eswitch *esw); void mlx5_esw_vport_ipsec_offload_disable(struct mlx5_eswitch *esw); bool mlx5_esw_vport_ipsec_offload_enabled(struct mlx5_eswitch *esw); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index d0cb80714f00..4b82cd2dc427 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -4308,4 +4308,107 @@ int mlx5_devlink_port_fn_ipsec_crypto_set(struct devlink_port *port, bool enable mutex_unlock(&net->xfrm.xfrm_cfg_mutex); return err; } + +int mlx5_devlink_port_fn_ipsec_packet_get(struct devlink_port *port, bool *is_enabled, + struct netlink_ext_ack *extack) +{ + struct mlx5_eswitch *esw; + struct mlx5_vport *vport; + int err = -EOPNOTSUPP; + + esw = mlx5_devlink_eswitch_get(port->devlink); + if (IS_ERR(esw)) + return PTR_ERR(esw); + + vport = mlx5_devlink_port_fn_get_vport(port, esw); + if (IS_ERR(vport)) { + NL_SET_ERR_MSG_MOD(extack, "Invalid port"); + return PTR_ERR(vport); + } + + if (!mlx5_esw_ipsec_vf_offload_supported(esw->dev)) { + NL_SET_ERR_MSG_MOD(extack, "Device doesn't support ipsec_packet"); + return err; + } + + mutex_lock(&esw->state_lock); + if (vport->enabled) { + *is_enabled = vport->info.ipsec_packet_enabled; + err = 0; + } + mutex_unlock(&esw->state_lock); + return err; +} + +int mlx5_devlink_port_fn_ipsec_packet_set(struct devlink_port *port, bool enable, + struct netlink_ext_ack *extack) +{ + struct mlx5_eswitch *esw; + struct mlx5_vport *vport; + int err = -EOPNOTSUPP; + struct net *net; + u16 vport_num; + + esw = mlx5_devlink_eswitch_get(port->devlink); + if (IS_ERR(esw)) + return PTR_ERR(esw); + + vport = mlx5_devlink_port_fn_get_vport(port, esw); + if (IS_ERR(vport)) { + NL_SET_ERR_MSG_MOD(extack, "Invalid port"); + return PTR_ERR(vport); + } + + vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index); + if (!mlx5_esw_ipsec_vf_packet_offload_supported(esw->dev, vport_num)) { + NL_SET_ERR_MSG_MOD(extack, + "Device doesn't support ipsec_packet or capability is blocked"); + return err; + } + + /* xfrm_cfg lock is needed to avoid races with XFRM state being added to + * the PF net device. Netlink stack takes this lock for `ip xfrm` user + * commands, so here we need to take it before esw->state_lock to + * preserve the order. + */ + net = dev_net(esw->dev->mlx5e_res.uplink_netdev); + mutex_lock(&net->xfrm.xfrm_cfg_mutex); + + mutex_lock(&esw->state_lock); + if (!vport->enabled) { + NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled"); + goto out; + } + if (vport->info.ipsec_packet_enabled == enable) { + err = 0; + goto out; + } + + err = mlx5_esw_ipsec_vf_packet_offload_set(esw, vport, enable); + switch (err) { + case 0: + break; + case -EBUSY: + NL_SET_ERR_MSG_MOD(extack, + "Failed setting ipsec_packet. Make sure ip xfrm state/policy is cleared on the PF."); + goto out; + case -EINVAL: + NL_SET_ERR_MSG_MOD(extack, + "Failed setting ipsec_packet. Make sure to unbind the VF first"); + goto out; + default: + NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA ipsec_full_offload cap."); + goto out; + } + + vport->info.ipsec_packet_enabled = enable; + if (enable) + mlx5_esw_vport_ipsec_offload_enable(esw); + else + mlx5_esw_vport_ipsec_offload_disable(esw); +out: + mutex_unlock(&esw->state_lock); + mutex_unlock(&net->xfrm.xfrm_cfg_mutex); + return err; +} #endif /* CONFIG_XFRM */