From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com, Chang Miao <chang.miao@corigine.com>,
Shihong Wang <shihong.wang@corigine.com>,
Chaoyong He <chaoyong.he@corigine.com>
Subject: [PATCH 07/10] net/nfp: create security session
Date: Mon, 25 Sep 2023 14:06:41 +0800 [thread overview]
Message-ID: <20230925060644.1458598-8-chaoyong.he@corigine.com> (raw)
In-Reply-To: <20230925060644.1458598-1-chaoyong.he@corigine.com>
From: Chang Miao <chang.miao@corigine.com>
Create security session to manage IPsec protocol specific message
and crypto parameters. This session support full protocol offload
and inline crypto operation with NIC devices.
Signed-off-by: Chang Miao <chang.miao@corigine.com>
Signed-off-by: Shihong Wang <shihong.wang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
---
drivers/net/nfp/nfp_ipsec.c | 711 ++++++++++++++++++++++++++++++++++++
1 file changed, 711 insertions(+)
diff --git a/drivers/net/nfp/nfp_ipsec.c b/drivers/net/nfp/nfp_ipsec.c
index d4292c3b90..d3fdef2d76 100644
--- a/drivers/net/nfp/nfp_ipsec.c
+++ b/drivers/net/nfp/nfp_ipsec.c
@@ -17,6 +17,8 @@
#include "nfp_logs.h"
#include "nfp_rxtx.h"
+#define NFP_UDP_ESP_PORT 4500
+
static const struct rte_cryptodev_capabilities nfp_crypto_caps[] = {
{
.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
@@ -375,6 +377,62 @@ enum nfp_ipsec_cfg_msg_rsp_codes {
NFP_IPSEC_CFG_MSG_SA_INVALID_CMD
};
+enum nfp_ipsec_mode {
+ NFP_IPSEC_MODE_TRANSPORT,
+ NFP_IPSEC_MODE_TUNNEL,
+};
+
+enum nfp_ipsec_protocal {
+ NFP_IPSEC_PROTOCOL_AH,
+ NFP_IPSEC_PROTOCOL_ESP,
+};
+
+/* Cipher modes */
+enum nfp_ipsec_cimode {
+ NFP_IPSEC_CIMODE_ECB,
+ NFP_IPSEC_CIMODE_CBC,
+ NFP_IPSEC_CIMODE_CFB,
+ NFP_IPSEC_CIMODE_OFB,
+ NFP_IPSEC_CIMODE_CTR,
+};
+
+/* Hash types */
+enum nfp_ipsec_hash_type {
+ NFP_IPSEC_HASH_NONE,
+ NFP_IPSEC_HASH_MD5_96,
+ NFP_IPSEC_HASH_SHA1_96,
+ NFP_IPSEC_HASH_SHA256_96,
+ NFP_IPSEC_HASH_SHA384_96,
+ NFP_IPSEC_HASH_SHA512_96,
+ NFP_IPSEC_HASH_MD5_128,
+ NFP_IPSEC_HASH_SHA1_80,
+ NFP_IPSEC_HASH_SHA256_128,
+ NFP_IPSEC_HASH_SHA384_192,
+ NFP_IPSEC_HASH_SHA512_256,
+ NFP_IPSEC_HASH_GF128_128,
+ NFP_IPSEC_HASH_POLY1305_128,
+};
+
+/* Cipher types */
+enum nfp_ipsec_cipher_type {
+ NFP_IPSEC_CIPHER_NULL,
+ NFP_IPSEC_CIPHER_3DES,
+ NFP_IPSEC_CIPHER_AES128,
+ NFP_IPSEC_CIPHER_AES192,
+ NFP_IPSEC_CIPHER_AES256,
+ NFP_IPSEC_CIPHER_AES128_NULL,
+ NFP_IPSEC_CIPHER_AES192_NULL,
+ NFP_IPSEC_CIPHER_AES256_NULL,
+ NFP_IPSEC_CIPHER_CHACHA20,
+};
+
+/* Don't Fragment types */
+enum nfp_ipsec_df_type {
+ NFP_IPSEC_DF_CLEAR,
+ NFP_IPSEC_DF_SET,
+ NFP_IPSEC_DF_COPY,
+};
+
static int
nfp_ipsec_cfg_cmd_issue(struct nfp_net_hw *hw,
struct nfp_ipsec_msg *msg)
@@ -427,6 +485,658 @@ nfp_ipsec_cfg_cmd_issue(struct nfp_net_hw *hw,
return ret;
}
+/**
+ * Get valid SA index from SA table
+ *
+ * @param data
+ * SA table pointer
+ * @param sa_idx
+ * SA table index pointer
+ *
+ * @return
+ * Negative number on full or repeat, 0 on success
+ *
+ * Note: multiple sockets may create same SA session.
+ */
+static void
+nfp_get_sa_entry(struct nfp_net_ipsec_data *data,
+ int *sa_idx)
+{
+ uint32_t i;
+
+ for (i = 0; i < NFP_NET_IPSEC_MAX_SA_CNT; i++) {
+ if (data->sa_entries[i] == NULL) {
+ *sa_idx = i;
+ break;
+ }
+ }
+}
+
+static void
+nfp_aesgcm_iv_update(struct ipsec_add_sa *cfg,
+ uint16_t iv_len,
+ const char *iv_string)
+{
+ int i;
+ char *save;
+ char *iv_b;
+ char *iv_str;
+ uint8_t *cfg_iv;
+
+ iv_str = strdup(iv_string);
+ cfg_iv = (uint8_t *)cfg->aesgcm_fields.iv;
+
+ for (i = 0; i < iv_len; i++) {
+ iv_b = strtok_r(i ? NULL : iv_str, ",", &save);
+ if (iv_b == NULL)
+ break;
+
+ cfg_iv[i] = strtoul(iv_b, NULL, 0);
+ }
+
+ *(uint32_t *)cfg_iv = rte_be_to_cpu_32(*(uint32_t *)cfg_iv);
+ *(uint32_t *)&cfg_iv[4] = rte_be_to_cpu_32(*(uint32_t *)&cfg_iv[4]);
+
+ free(iv_str);
+}
+
+static int
+set_aes_keylen(uint32_t key_length,
+ struct ipsec_add_sa *cfg)
+{
+ switch (key_length << 3) {
+ case 128:
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_AES128;
+ break;
+ case 192:
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_AES192;
+ break;
+ case 256:
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_AES256;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "AES cipher key length is illegal!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Map rte_security_session_conf aead algo to NFP aead algo */
+static int
+nfp_aead_map(struct rte_eth_dev *eth_dev,
+ struct rte_crypto_aead_xform *aead,
+ uint32_t key_length,
+ struct ipsec_add_sa *cfg)
+{
+ int ret;
+ uint32_t i;
+ uint32_t index;
+ uint16_t iv_len;
+ uint32_t offset;
+ uint32_t device_id;
+ const char *iv_str;
+ const uint32_t *key;
+ struct nfp_net_hw *hw;
+
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+ device_id = hw->device_id;
+ offset = 0;
+
+ switch (aead->algo) {
+ case RTE_CRYPTO_AEAD_AES_GCM:
+ if (aead->digest_length != 16) {
+ PMD_DRV_LOG(ERR, "ICV must be 128bit with RTE_CRYPTO_AEAD_AES_GCM!");
+ return -EINVAL;
+ }
+
+ cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CTR;
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_GF128_128;
+
+ ret = set_aes_keylen(key_length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to set AES_GCM key length!");
+ return -EINVAL;
+ }
+
+ break;
+ case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
+ if (device_id != PCI_DEVICE_ID_NFP3800_PF_NIC) {
+ PMD_DRV_LOG(ERR, "Unsupported aead CHACHA20_POLY1305 algorithm!");
+ return -EINVAL;
+ }
+
+ if (aead->digest_length != 16) {
+ PMD_DRV_LOG(ERR, "ICV must be 128bit with RTE_CRYPTO_AEAD_CHACHA20_POLY1305");
+ return -EINVAL;
+ }
+
+ /* Aead->alg_key_len includes 32-bit salt */
+ if (key_length != 32) {
+ PMD_DRV_LOG(ERR, "Unsupported CHACHA20 key length");
+ return -EINVAL;
+ }
+
+ /* The CHACHA20's mode is not configured */
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_POLY1305_128;
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_CHACHA20;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported aead algorithm!");
+ return -EINVAL;
+ }
+
+ key = (const uint32_t *)(aead->key.data);
+
+ /*
+ * The CHACHA20's key order needs to be adjusted based on hardware design.
+ * Unadjusted order: {K0, K1, K2, K3, K4, K5, K6, K7}
+ * Adjusted order: {K4, K5, K6, K7, K0, K1, K2, K3}
+ */
+ if (aead->algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305)
+ offset = key_length / sizeof(cfg->cipher_key[0]) << 1;
+
+ for (i = 0; i < key_length / sizeof(cfg->cipher_key[0]); i++) {
+ index = (i + offset) % (key_length / sizeof(cfg->cipher_key[0]));
+ cfg->cipher_key[index] = rte_cpu_to_be_32(*key++);
+ }
+
+ /*
+ * The iv of the FW is equal to ESN by default. Reading the
+ * iv of the configuration information is not supported.
+ */
+ iv_str = getenv("ETH_SEC_IV_OVR");
+ if (iv_str != NULL) {
+ iv_len = aead->iv.length;
+ nfp_aesgcm_iv_update(cfg, iv_len, iv_str);
+ }
+
+ return 0;
+}
+
+/* Map rte_security_session_conf cipher algo to NFP cipher algo */
+static int
+nfp_cipher_map(struct rte_eth_dev *eth_dev,
+ struct rte_crypto_cipher_xform *cipher,
+ uint32_t key_length,
+ struct ipsec_add_sa *cfg)
+{
+ int ret;
+ uint32_t i;
+ uint32_t device_id;
+ const uint32_t *key;
+ struct nfp_net_hw *hw;
+
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+ device_id = hw->device_id;
+
+ switch (cipher->algo) {
+ case RTE_CRYPTO_CIPHER_NULL:
+ cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_NULL;
+ break;
+ case RTE_CRYPTO_CIPHER_3DES_CBC:
+ if (device_id == PCI_DEVICE_ID_NFP3800_PF_NIC) {
+ PMD_DRV_LOG(ERR, "Unsupported 3DESCBC encryption algorithm!");
+ return -EINVAL;
+ }
+
+ cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
+ cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_3DES;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_CBC:
+ cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
+ ret = set_aes_keylen(key_length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to set cipher key length!");
+ return -EINVAL;
+ }
+
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported cipher alg!");
+ return -EINVAL;
+ }
+
+ key = (const uint32_t *)(cipher->key.data);
+ if (key_length > sizeof(cfg->cipher_key)) {
+ PMD_DRV_LOG(ERR, "Insufficient space for offloaded key");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < key_length / sizeof(cfg->cipher_key[0]); i++)
+ cfg->cipher_key[i] = rte_cpu_to_be_32(*key++);
+
+ return 0;
+}
+
+static void
+set_md5hmac(struct ipsec_add_sa *cfg,
+ uint32_t *digest_length)
+{
+ switch (*digest_length) {
+ case 96:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_MD5_96;
+ break;
+ case 128:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_MD5_128;
+ break;
+ default:
+ *digest_length = 0;
+ }
+}
+
+static void
+set_sha1hmac(struct ipsec_add_sa *cfg,
+ uint32_t *digest_length)
+{
+ switch (*digest_length) {
+ case 96:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA1_96;
+ break;
+ case 80:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA1_80;
+ break;
+ default:
+ *digest_length = 0;
+ }
+}
+
+static void
+set_sha2_256hmac(struct ipsec_add_sa *cfg,
+ uint32_t *digest_length)
+{
+ switch (*digest_length) {
+ case 96:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA256_96;
+ break;
+ case 128:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA256_128;
+ break;
+ default:
+ *digest_length = 0;
+ }
+}
+
+static void
+set_sha2_384hmac(struct ipsec_add_sa *cfg,
+ uint32_t *digest_length)
+{
+ switch (*digest_length) {
+ case 96:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA384_96;
+ break;
+ case 192:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA384_192;
+ break;
+ default:
+ *digest_length = 0;
+ }
+}
+
+static void
+set_sha2_512hmac(struct ipsec_add_sa *cfg,
+ uint32_t *digest_length)
+{
+ switch (*digest_length) {
+ case 96:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA512_96;
+ break;
+ case 256:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_SHA512_256;
+ break;
+ default:
+ *digest_length = 0;
+ }
+}
+
+/* Map rte_security_session_conf auth algo to NFP auth algo */
+static int
+nfp_auth_map(struct rte_eth_dev *eth_dev,
+ struct rte_crypto_auth_xform *auth,
+ uint32_t digest_length,
+ struct ipsec_add_sa *cfg)
+{
+ uint32_t i;
+ uint8_t key_length;
+ uint32_t device_id;
+ const uint32_t *key;
+ struct nfp_net_hw *hw;
+
+ if (digest_length == 0) {
+ PMD_DRV_LOG(ERR, "Auth digest length is illegal!");
+ return -EINVAL;
+ }
+
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+ device_id = hw->device_id;
+ digest_length = digest_length << 3;
+
+ switch (auth->algo) {
+ case RTE_CRYPTO_AUTH_NULL:
+ cfg->ctrl_word.hash = NFP_IPSEC_HASH_NONE;
+ digest_length = 1;
+ break;
+ case RTE_CRYPTO_AUTH_MD5_HMAC:
+ if (device_id == PCI_DEVICE_ID_NFP3800_PF_NIC) {
+ PMD_DRV_LOG(ERR, "Unsupported MD5HMAC authentication algorithm!");
+ return -EINVAL;
+ }
+
+ set_md5hmac(cfg, &digest_length);
+ break;
+ case RTE_CRYPTO_AUTH_SHA1_HMAC:
+ set_sha1hmac(cfg, &digest_length);
+ break;
+ case RTE_CRYPTO_AUTH_SHA256_HMAC:
+ set_sha2_256hmac(cfg, &digest_length);
+ break;
+ case RTE_CRYPTO_AUTH_SHA384_HMAC:
+ set_sha2_384hmac(cfg, &digest_length);
+ break;
+ case RTE_CRYPTO_AUTH_SHA512_HMAC:
+ set_sha2_512hmac(cfg, &digest_length);
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported auth alg!");
+ return -EINVAL;
+ }
+
+ if (digest_length == 0) {
+ PMD_DRV_LOG(ERR, "Unsupported authentication algorithm digest length");
+ return -EINVAL;
+ }
+
+ key = (const uint32_t *)(auth->key.data);
+ key_length = auth->key.length;
+ if (key_length > sizeof(cfg->auth_key)) {
+ PMD_DRV_LOG(ERR, "Insufficient space for offloaded auth key!");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < key_length / sizeof(cfg->auth_key[0]); i++)
+ cfg->auth_key[i] = rte_cpu_to_be_32(*key++);
+
+ return 0;
+}
+
+static int
+nfp_crypto_msg_build(struct rte_eth_dev *eth_dev,
+ struct rte_security_session_conf *conf,
+ struct nfp_ipsec_msg *msg)
+{
+ int ret;
+ struct ipsec_add_sa *cfg;
+ struct rte_crypto_sym_xform *cur;
+ struct rte_crypto_sym_xform *next;
+ enum rte_security_ipsec_sa_direction direction;
+
+ cur = conf->crypto_xform;
+ if (cur == NULL) {
+ PMD_DRV_LOG(ERR, "Unsupported crypto_xform is NULL!");
+ return -EINVAL;
+ }
+
+ next = cur->next;
+ direction = conf->ipsec.direction;
+ cfg = &msg->cfg_add_sa;
+
+ switch (cur->type) {
+ case RTE_CRYPTO_SYM_XFORM_AEAD:
+ /* Aead transforms can be used for either inbound/outbound IPsec SAs */
+ if (next != NULL) {
+ PMD_DRV_LOG(ERR, "Next crypto_xform type should be NULL!");
+ return -EINVAL;
+ }
+
+ ret = nfp_aead_map(eth_dev, &cur->aead, cur->aead.key.length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to map aead alg!");
+ return ret;
+ }
+
+ cfg->aesgcm_fields.salt = rte_cpu_to_be_32(conf->ipsec.salt);
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AUTH:
+ /* Only support Auth + Cipher for inbound */
+ if (direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+ PMD_DRV_LOG(ERR, "Direction should be INGRESS, but it is not!");
+ return -EINVAL;
+ }
+
+ if (next == NULL || next->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {
+ PMD_DRV_LOG(ERR, "Next crypto_xfrm should be cipher, but it is not!");
+ return -EINVAL;
+ }
+
+ ret = nfp_auth_map(eth_dev, &cur->auth, cur->auth.digest_length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to map auth alg!");
+ return ret;
+ }
+
+ ret = nfp_cipher_map(eth_dev, &next->cipher, next->cipher.key.length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to map cipher alg!");
+ return ret;
+ }
+
+ break;
+ case RTE_CRYPTO_SYM_XFORM_CIPHER:
+ /* Only support Cipher + Auth for outbound */
+ if (direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
+ PMD_DRV_LOG(ERR, "Direction should be EGRESS, but it is not!");
+ return -EINVAL;
+ }
+
+ if (next == NULL || next->type != RTE_CRYPTO_SYM_XFORM_AUTH) {
+ PMD_DRV_LOG(ERR, "Next crypto_xfrm should be auth, but it is not!");
+ return -EINVAL;
+ }
+
+ ret = nfp_cipher_map(eth_dev, &cur->cipher, cur->cipher.key.length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to map cipher alg!");
+ return ret;
+ }
+
+ ret = nfp_auth_map(eth_dev, &next->auth, next->auth.digest_length, cfg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to map auth alg!");
+ return ret;
+ }
+
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported crypto_xform type!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+nfp_ipsec_msg_build(struct rte_eth_dev *eth_dev,
+ struct rte_security_session_conf *conf,
+ struct nfp_ipsec_msg *msg)
+{
+ int ret;
+ uint32_t i;
+ uint32_t *src_ip;
+ uint32_t *dst_ip;
+ struct ipsec_add_sa *cfg;
+ enum rte_security_ipsec_tunnel_type type;
+
+ cfg = &msg->cfg_add_sa;
+ cfg->spi = conf->ipsec.spi;
+ cfg->pmtu_limit = 0xffff;
+
+ /*
+ * UDP encapsulation
+ *
+ * 1: Do UDP encapsulation/decapsulation
+ * 0: No UDP encapsulation
+ */
+ if (conf->ipsec.options.udp_encap == 1) {
+ cfg->udp_enable = 1;
+ cfg->natt_dst_port = NFP_UDP_ESP_PORT;
+ cfg->natt_src_port = NFP_UDP_ESP_PORT;
+ }
+
+ if (conf->ipsec.options.copy_df == 1)
+ cfg->df_ctrl = NFP_IPSEC_DF_COPY;
+ else if (conf->ipsec.tunnel.ipv4.df != 0)
+ cfg->df_ctrl = NFP_IPSEC_DF_SET;
+ else
+ cfg->df_ctrl = NFP_IPSEC_DF_CLEAR;
+
+ switch (conf->action_type) {
+ case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO:
+ cfg->ctrl_word.encap_dsbl = 1;
+ break;
+ case RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL:
+ cfg->ctrl_word.encap_dsbl = 0;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported IPsec action for offload, action: %d",
+ conf->action_type);
+ return -EINVAL;
+ }
+
+ switch (conf->ipsec.proto) {
+ case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
+ cfg->ctrl_word.proto = NFP_IPSEC_PROTOCOL_ESP;
+ break;
+ case RTE_SECURITY_IPSEC_SA_PROTO_AH:
+ cfg->ctrl_word.proto = NFP_IPSEC_PROTOCOL_AH;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported IPsec protocol for offload, protocol: %d",
+ conf->ipsec.proto);
+ return -EINVAL;
+ }
+
+ switch (conf->ipsec.mode) {
+ case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
+ type = conf->ipsec.tunnel.type;
+ cfg->ctrl_word.mode = NFP_IPSEC_MODE_TUNNEL;
+ if (type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
+ src_ip = &conf->ipsec.tunnel.ipv4.src_ip.s_addr;
+ dst_ip = &conf->ipsec.tunnel.ipv4.dst_ip.s_addr;
+ cfg->src_ip[0] = rte_cpu_to_be_32(*src_ip);
+ cfg->dst_ip[0] = rte_cpu_to_be_32(*dst_ip);
+ cfg->ipv6 = 0;
+ } else if (type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
+ src_ip = conf->ipsec.tunnel.ipv6.src_addr.__in6_u.__u6_addr32;
+ dst_ip = conf->ipsec.tunnel.ipv6.dst_addr.__in6_u.__u6_addr32;
+ for (i = 0; i < 4; i++) {
+ cfg->src_ip[i] = rte_cpu_to_be_32(src_ip[i]);
+ cfg->dst_ip[i] = rte_cpu_to_be_32(dst_ip[i]);
+ }
+ cfg->ipv6 = 1;
+ } else {
+ PMD_DRV_LOG(ERR, "Unsupported address family!");
+ return -EINVAL;
+ }
+
+ break;
+ case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
+ type = conf->ipsec.tunnel.type;
+ cfg->ctrl_word.mode = NFP_IPSEC_MODE_TRANSPORT;
+ if (type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
+ cfg->src_ip[0] = 0;
+ cfg->dst_ip[0] = 0;
+ cfg->ipv6 = 0;
+ } else if (type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
+ for (i = 0; i < 4; i++) {
+ cfg->src_ip[i] = 0;
+ cfg->dst_ip[i] = 0;
+ }
+ cfg->ipv6 = 1;
+ } else {
+ PMD_DRV_LOG(ERR, "Unsupported address family!");
+ return -EINVAL;
+ }
+
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Unsupported IPsec mode for offload, mode: %d",
+ conf->ipsec.mode);
+ return -EINVAL;
+ }
+
+ ret = nfp_crypto_msg_build(eth_dev, conf, msg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to build auth/crypto/aead msg!");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+nfp_crypto_create_session(void *device,
+ struct rte_security_session_conf *conf,
+ struct rte_security_session *session)
+{
+ int ret;
+ int sa_idx;
+ struct nfp_net_hw *hw;
+ struct nfp_ipsec_msg msg;
+ struct rte_eth_dev *eth_dev;
+ struct nfp_ipsec_session *priv_session;
+
+ /* Only support IPsec at present */
+ if (conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) {
+ PMD_DRV_LOG(ERR, "Unsupported non-IPsec offload!");
+ return -EINVAL;
+ }
+
+ sa_idx = -1;
+ eth_dev = device;
+ priv_session = SECURITY_GET_SESS_PRIV(session);
+ hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+
+ if (hw->ipsec_data->sa_free_cnt == 0) {
+ PMD_DRV_LOG(ERR, "No space in SA table, spi: %d", conf->ipsec.spi);
+ return -EINVAL;
+ }
+
+ nfp_get_sa_entry(hw->ipsec_data, &sa_idx);
+
+ if (sa_idx < 0) {
+ PMD_DRV_LOG(ERR, "Failed to get SA entry!");
+ return -EINVAL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ ret = nfp_ipsec_msg_build(eth_dev, conf, &msg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to build IPsec msg!");
+ return -EINVAL;
+ }
+
+ msg.cmd = NFP_IPSEC_CFG_MSG_ADD_SA;
+ msg.sa_idx = sa_idx;
+ ret = nfp_ipsec_cfg_cmd_issue(hw, &msg);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to add SA to nic");
+ return -EINVAL;
+ }
+
+ priv_session->action = conf->action_type;
+ priv_session->ipsec = conf->ipsec;
+ priv_session->msg = msg.cfg_add_sa;
+ priv_session->sa_index = sa_idx;
+ priv_session->dev = eth_dev;
+ priv_session->user_data = conf->userdata;
+
+ hw->ipsec_data->sa_free_cnt--;
+ hw->ipsec_data->sa_entries[sa_idx] = priv_session;
+
+ return 0;
+}
+
/**
* Get discards packet statistics for each SA
*
@@ -517,6 +1227,7 @@ nfp_security_session_get_size(void *device __rte_unused)
}
static const struct rte_security_ops nfp_security_ops = {
+ .session_create = nfp_crypto_create_session,
.session_get_size = nfp_security_session_get_size,
.session_stats_get = nfp_security_session_get_stats,
.capabilities_get = nfp_crypto_capabilities_get,
--
2.39.1
next prev parent reply other threads:[~2023-09-25 6:08 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-25 6:06 [PATCH 00/10] add the support of ipsec offload Chaoyong He
2023-09-25 6:06 ` [PATCH 01/10] mailmap: update contributor entry Chaoyong He
2023-09-27 14:19 ` Ferruh Yigit
2023-09-28 1:50 ` Chaoyong He
2023-09-25 6:06 ` [PATCH 02/10] net/nfp: add TLVs capability parsing Chaoyong He
2023-09-27 14:19 ` Ferruh Yigit
2023-09-28 2:02 ` Chaoyong He
2023-09-28 9:30 ` Ferruh Yigit
2023-09-25 6:06 ` [PATCH 03/10] net/nfp: add mailbox to support IPsec offload Chaoyong He
2023-09-25 6:06 ` [PATCH 04/10] net/nfp: initialize IPsec related content Chaoyong He
2023-09-25 6:06 ` [PATCH 05/10] net/nfp: get security capabilities and session size Chaoyong He
2023-09-25 6:06 ` [PATCH 06/10] net/nfp: get IPsec Rx/Tx packet statistics Chaoyong He
2023-09-25 6:06 ` Chaoyong He [this message]
2023-09-25 6:06 ` [PATCH 08/10] net/nfp: update security session Chaoyong He
2023-09-25 6:06 ` [PATCH 09/10] net/nfp: support IPsec Rx and Tx offload Chaoyong He
2023-09-25 6:06 ` [PATCH 10/10] net/nfp: destroy security session Chaoyong He
2023-09-26 2:49 ` [PATCH v2 00/10] add the support of ipsec offload Chaoyong He
2023-09-26 2:49 ` [PATCH v2 01/10] mailmap: update contributor entry Chaoyong He
2023-09-26 2:49 ` [PATCH v2 02/10] net/nfp: add TLVs capability parsing Chaoyong He
2023-09-26 2:49 ` [PATCH v2 03/10] net/nfp: add mailbox to support IPsec offload Chaoyong He
2023-09-26 2:49 ` [PATCH v2 04/10] net/nfp: initialize IPsec related content Chaoyong He
2023-09-26 2:49 ` [PATCH v2 05/10] net/nfp: get security capabilities and session size Chaoyong He
2023-09-26 2:49 ` [PATCH v2 06/10] net/nfp: get IPsec Rx/Tx packet statistics Chaoyong He
2023-09-26 2:49 ` [PATCH v2 07/10] net/nfp: create security session Chaoyong He
2023-09-26 2:49 ` [PATCH v2 08/10] net/nfp: update " Chaoyong He
2023-09-26 2:49 ` [PATCH v2 09/10] net/nfp: support IPsec Rx and Tx offload Chaoyong He
2023-09-26 2:49 ` [PATCH v2 10/10] net/nfp: destroy security session Chaoyong He
2023-09-27 14:20 ` [PATCH v2 00/10] add the support of ipsec offload Ferruh Yigit
2023-09-28 2:05 ` Chaoyong He
2023-09-28 9:33 ` Ferruh Yigit
2023-09-29 2:08 ` [PATCH v3 0/9] " Chaoyong He
2023-09-29 2:08 ` [PATCH v3 1/9] net/nfp: add TLVs capability parsing Chaoyong He
2023-09-29 2:08 ` [PATCH v3 2/9] net/nfp: add mailbox to support IPsec offload Chaoyong He
2023-09-29 2:08 ` [PATCH v3 3/9] net/nfp: initialize IPsec related content Chaoyong He
2023-09-29 10:00 ` Ferruh Yigit
2023-09-29 2:08 ` [PATCH v3 4/9] net/nfp: get security capabilities and session size Chaoyong He
2023-09-29 2:08 ` [PATCH v3 5/9] net/nfp: get IPsec Rx/Tx packet statistics Chaoyong He
2023-09-29 2:08 ` [PATCH v3 6/9] net/nfp: create security session Chaoyong He
2023-09-29 2:08 ` [PATCH v3 7/9] net/nfp: update " Chaoyong He
2023-09-29 2:08 ` [PATCH v3 8/9] net/nfp: support IPsec Rx and Tx offload Chaoyong He
2023-09-29 2:08 ` [PATCH v3 9/9] net/nfp: destroy security session Chaoyong He
2023-09-29 10:05 ` [PATCH v3 0/9] add the support of ipsec offload Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230925060644.1458598-8-chaoyong.he@corigine.com \
--to=chaoyong.he@corigine.com \
--cc=chang.miao@corigine.com \
--cc=dev@dpdk.org \
--cc=oss-drivers@corigine.com \
--cc=shihong.wang@corigine.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).