From patchwork Thu Nov 23 16:13:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?N=C3=A9lio_Laranjeiro?= X-Patchwork-Id: 31598 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 0FFD43790; Thu, 23 Nov 2017 17:13:35 +0100 (CET) Received: from mail-wm0-f66.google.com (mail-wm0-f66.google.com [74.125.82.66]) by dpdk.org (Postfix) with ESMTP id 5E42E2BEF for ; Thu, 23 Nov 2017 17:13:30 +0100 (CET) Received: by mail-wm0-f66.google.com with SMTP id g130so17669132wme.0 for ; Thu, 23 Nov 2017 08:13:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=VbNKeo8CD7U84N+H/HEd9xkWbeaUDFB4AZF5eMg4wxg=; b=gqRU/Q1Ui8Hf5CL6iYSMERxcdFUHdolAY/kox3tROzY7Wnbjugn1IsESeHILgmZc0A n3a6W56B6CQj5ZID1W0FKWrgKDtoQVNzXicKFpYn4kONwfILFUsIyMsmKc7gBj2fYjDC Wf6iFqui6AV9HgEJ1PneFxlVuNpsRe+j9J9qrXibfcE6fo1bCQKPItwQ4ljkAXxRzGAD MWQ+V3jqy4ScbUWyasK0n7G4xN/YSA5q7ZqXAidg0ejlcBTyie7uG9Wibgh4xLtXaBoO buyaL7fsl8aMuf1m1tT5iD0j/V58UtMSTDRou9zKeTlt/J7H3ejSBEvOhDV8lJ95oQLE KyWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=VbNKeo8CD7U84N+H/HEd9xkWbeaUDFB4AZF5eMg4wxg=; b=Cd+MsyslpIW2rP8FYbTDPfs9Bbkuudehniok2FiJDt6AwIFFwki0DywXGDKVx5ee+d DpyNk0l9gyRlofF4MTqFHpekAPoERHXnA23yftDUWwaMPkAGiQAlWVebKRGiG8rg4wyx 4MwYy96WTilcDJaceQzbyPyQqRC07mjGY2mr0WilA9tXtE7QeO98RG17/btIqUDkcu0a 0wBheKLNkROWf8HdkPlnhNFkqtsJoqbmKs2oeYVTZNfw76NsLjs6LxiVaKjxixNyvVbB HITxevuOdnAAQCvw0GSB1Kr/8zzqGGdEYgK6rgyzJresHabOW+BDt5364SbWH1I7ZvUk deVw== X-Gm-Message-State: AJaThX5KpsHpIEc4mm4sEWPgum0y8Py2T5KOfgEiegOLjxjiNRKAIiYU WFjb+Fzlj7MG5vSkv/kRfT23tA+FSw== X-Google-Smtp-Source: AGs4zMZka27YjWZkIdTYmETuAmt8qQnz9I0NEpQllVqNXrVyHzb5JuOXK1GW7sLjRIvQqxhFX8UpfQ== X-Received: by 10.80.141.9 with SMTP id s9mr34368196eds.238.1511453609717; Thu, 23 Nov 2017 08:13:29 -0800 (PST) Received: from laranjeiro-vm.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id u10sm14663036edm.56.2017.11.23.08.13.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 Nov 2017 08:13:28 -0800 (PST) From: Nelio Laranjeiro To: dev@dpdk.org Cc: Aviad Yehezkel , Yongseok Koh , Adrien Mazarguil Date: Thu, 23 Nov 2017 17:13:06 +0100 Message-Id: <00d00234598a20dd78f102701eaadd63aba6603b.1511453340.git.nelio.laranjeiro@6wind.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v1 4/7] net/mlx5: add security capability 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: Aviad Yehezkel Signed-off-by: Aviad Yehezkel Signed-off-by: Nelio Laranjeiro --- drivers/net/mlx5/Makefile | 1 + drivers/net/mlx5/mlx5.c | 12 ++ drivers/net/mlx5/mlx5.h | 2 + drivers/net/mlx5/mlx5_ipsec.c | 322 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 drivers/net/mlx5/mlx5_ipsec.c diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index b2dd86796..839d208b1 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -53,6 +53,7 @@ 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_socket.c +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_ipsec.c # Basic CFLAGS. CFLAGS += -O3 diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 00480cef0..e74026caf 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "mlx5.h" #include "mlx5_utils.h" @@ -114,6 +115,9 @@ MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_SPI_RSS_ONLY) #endif +/* Dev ops structure defined in mlx5_ipsec.c */ +extern const struct rte_security_ops mlx5_security_ops; + struct mlx5_args { int cqe_comp; int txq_inline; @@ -942,6 +946,14 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) mlx5dv_set_context_attr(ctx, MLX5DV_CTX_ATTR_BUF_ALLOCATORS, (void *)((uintptr_t)&alctr)); + if (priv->ipsec_en) { + priv->security = (struct rte_security_ctx){ + .device = (void *)eth_dev, + .ops = &mlx5_security_ops, + .sess_cnt = 0, + }; + eth_dev->security_ctx = &priv->security; + } /* Bring Ethernet device up. */ DEBUG("forcing Ethernet interface up"); priv_set_flags(priv, ~IFF_UP, IFF_UP); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index c6a01d972..2927b851b 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -58,6 +58,7 @@ #include #include #include +#include #include "mlx5_utils.h" #include "mlx5_rxtx.h" @@ -150,6 +151,7 @@ struct priv { rte_spinlock_t lock; /* Lock for control functions. */ int primary_socket; /* Unix socket for primary process. */ struct rte_intr_handle intr_handle_socket; /* Interrupt handler. */ + struct rte_security_ctx security; /* Security context. */ }; /** diff --git a/drivers/net/mlx5/mlx5_ipsec.c b/drivers/net/mlx5/mlx5_ipsec.c new file mode 100644 index 000000000..52a3add7a --- /dev/null +++ b/drivers/net/mlx5/mlx5_ipsec.c @@ -0,0 +1,322 @@ +/*- + * BSD LICENSE + * + * Copyright 2017 Mellanox. + * Copyright 2017 6WIND S.A. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of 6WIND S.A. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Verbs header. */ +/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include +#include +#include +#include + +#include "mlx5.h" +#include "mlx5_utils.h" +#include "mlx5_autoconf.h" + +#ifdef HAVE_IBV_IPSEC_SUPPORT +#define MLX5_IPSEC_SUPPORT_ERROR(cond) \ + static_assert((cond), "Wrong verbs.h version for IPsec support," \ + " please contact Mellanox") + +/* Extra verifications, this API is not unstreamed yet. */ +MLX5_IPSEC_SUPPORT_ERROR(MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_REQ_METADATA == + 1u << 0); +MLX5_IPSEC_SUPPORT_ERROR(MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_RX == 1u << 1); +MLX5_IPSEC_SUPPORT_ERROR(MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_TX == 1u << 2); +MLX5_IPSEC_SUPPORT_ERROR(MLX5DV_CONTEXT_XFRM_FLAGS_ESP_AES_GCM_SPI_RSS_ONLY == + 1u << 3); +#endif + +/* Security session. */ +struct mlx5_security_session { + struct rte_security_ipsec_xform ipsec_xform; + struct rte_eth_dev *dev; + struct ibv_action_xfrm *ibv_action_xfrm; +}; + +/** MLX5 Crypto capabilities. */ +struct rte_cryptodev_capabilities mlx5_crypto_capabilities[] = { + /* AES GCM (128-bit) */ + { + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD, + .aead = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0, + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0, + }, + .aad_size = { + .min = 8, + .max = 8, + .increment = 0, + }, + .iv_size = { + .min = 12, + .max = 12, + .increment = 0, + }, + }, + }, + }, + /* AES GCM (256-bit) */ + { + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + .sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD, + .aead = { + .algo = RTE_CRYPTO_AEAD_AES_GCM, + .block_size = 16, + .key_size = { + .min = 32, + .max = 32, + .increment = 0, + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0, + }, + .aad_size = { + .min = 8, + .max = 8, + .increment = 0, + }, + .iv_size = { + .min = 12, + .max = 12, + .increment = 0, + }, + }, + }, + }, + /* None */ + { + .op = RTE_CRYPTO_OP_TYPE_UNDEFINED, + .sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED + }, + }, +}; + +/** MLX5 Security capabilities. */ +static const struct rte_security_capability mlx5_security_capabilities[] = { +#ifdef HAVE_IBV_IPSEC_SUPPORT + /* IPsec Inline Crypto ESP Transport Egress */ + { + .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + .protocol = RTE_SECURITY_PROTOCOL_IPSEC, + .ipsec = { + .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, + .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT, + .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS, + .options = {0}, + }, + .crypto_capabilities = mlx5_crypto_capabilities, + .ol_flags = RTE_SECURITY_TX_HW_TRAILER_OFFLOAD, + }, + /* IPsec Inline Crypto ESP Transport Ingress */ + { + .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + .protocol = RTE_SECURITY_PROTOCOL_IPSEC, + .ipsec = { + .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, + .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT, + .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS, + .options = {0}, + }, + .crypto_capabilities = mlx5_crypto_capabilities, + .ol_flags = 0, + }, + /* IPsec Inline Crypto ESP Tunnel Egress */ + { + .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + .protocol = RTE_SECURITY_PROTOCOL_IPSEC, + .ipsec = { + .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, + .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL, + .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS, + .options = {0}, + }, + .crypto_capabilities = mlx5_crypto_capabilities, + .ol_flags = RTE_SECURITY_TX_HW_TRAILER_OFFLOAD, + }, + /* IPsec Inline Crypto ESP Tunnel Ingress */ + { + .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, + .protocol = RTE_SECURITY_PROTOCOL_IPSEC, + .ipsec = { + .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, + .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL, + .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS, + .options = {0}, + }, + .crypto_capabilities = mlx5_crypto_capabilities, + .ol_flags = 0, + }, +#endif /* HAVE_IBV_IPSEC_SUPPORT */ + { + .action = RTE_SECURITY_ACTION_TYPE_NONE + } +}; + +/** + * Security capabilities. + * + * @see rte_security_capability(). + */ +static const struct rte_security_capability * +mlx5_security_get_capabilities(void *dev __rte_unused) +{ + return mlx5_security_capabilities; +} + +/** + * Create a security session. + * + * @see security_session_create_t(). + */ +static int +mlx5_security_create_session + (void *dev __rte_unused, + struct rte_security_session_conf *sess_conf __rte_unused, + struct rte_security_session *sess __rte_unused, + struct rte_mempool *mempool __rte_unused) +{ + int ret = -ENOTSUP; +#ifdef HAVE_IBV_IPSEC_SUPPORT + struct mlx5_security_session *mlx5_sess = NULL; + struct priv *priv = ((struct rte_eth_dev *)dev)->data->dev_private; + struct ibv_action_xfrm_attr_esp_aes_gcm esp_aes_gcm; + struct mlx5dv_action_xfrm_attr_esp_aes_gcm mlx5_attr = { + .xfrm_flags = MLX5DV_ACTION_XFRM_FLAGS_REQUIRE_METADATA, + .comp_mask = + MLX5DV_ACTION_XFRM_ATTR_ESP_AES_GCM_MASK_XFRM_FLAGS, + }; + + memset(&esp_aes_gcm, 0, sizeof(esp_aes_gcm)); + if (sess_conf->action_type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) { + ERROR("Unknown rte security session type %d", + sess_conf->action_type); + goto out; + } + if (sess_conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) { + ERROR("Unknown rte security session protocol %d", + sess_conf->protocol); + goto out; + } + if (sess_conf->crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { + ERROR("Unsupported IPsec XFORM"); + goto out; + } + if (sess_conf->crypto_xform->aead.algo != RTE_CRYPTO_AEAD_AES_GCM) { + ERROR("Unsupported IPsec AEAD algorithm"); + goto out; + } + ret = rte_mempool_get(mempool, (void **)&mlx5_sess); + if (ret) { + ERROR("Failed to allocate security session"); + ret = -ENOMEM; + goto out; + } + memcpy(&mlx5_sess->ipsec_xform, &sess_conf->ipsec, + sizeof(sess_conf->ipsec)); + mlx5_sess->dev = dev; + set_sec_session_private_data(sess, mlx5_sess); + /* create action xfrm */ + esp_aes_gcm.type = IBV_ACTION_XFRM_TYPE_ESP_AES_GCM; + esp_aes_gcm.key_length = sess_conf->crypto_xform->aead.key.length; + memcpy(esp_aes_gcm.key, sess_conf->crypto_xform->aead.key.data, + sess_conf->crypto_xform->aead.key.length); + memcpy(esp_aes_gcm.salt, &sess_conf->ipsec.salt, + sizeof(esp_aes_gcm.salt)); + mlx5_sess->ibv_action_xfrm = + mlx5dv_create_action_xfrm_esp_aes_gcm(priv->ctx, + &esp_aes_gcm, + &mlx5_attr); + if (!mlx5_sess->ibv_action_xfrm) { + ERROR("Failed to create an action_xfrm rule"); + ret = -EFAULT; + rte_free(mlx5_sess); + } +out: +#endif /* HAVE_IBV_IPSEC_SUPPORT */ + return ret; +} + +/** + * Destroy a security session. + * + * @see security_session_destroy_t(). + */ +static int +mlx5_security_destroy_session(void *dev __rte_unused, + struct rte_security_session *sess __rte_unused) +{ +#ifdef HAVE_IBV_IPSEC_SUPPORT + struct mlx5_security_session *mlx5_sess = + get_sec_session_private_data(sess); + + if (dev != mlx5_sess->dev) { + ERROR("Attempt to clear session from wrong device"); + return -EFAULT; + } + claim_zero(ibv_destroy_action_xfrm(mlx5_sess->ibv_action_xfrm)); + rte_free(mlx5_sess); + return 0; +#endif /* HAVE_IBV_IPSEC_SUPPORT */ + return -ENOTSUP; +} + +/* Security device operations. */ +const struct rte_security_ops mlx5_security_ops = { + .session_create = mlx5_security_create_session, + .session_destroy = mlx5_security_destroy_session, + .capabilities_get = mlx5_security_get_capabilities, +};