X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_ipsec.c;h=48f5082d49204b1c78acde43251981645363b8ba;hb=8716f9942a408a79a114ac0496e4e7d55bc9944c;hp=99c0a7314dd16a9e3729403d56da84abc8baef86;hpb=9a0752f498d2725428480b4b004feeedd852c395;p=dpdk.git diff --git a/drivers/net/ixgbe/ixgbe_ipsec.c b/drivers/net/ixgbe/ixgbe_ipsec.c index 99c0a7314d..48f5082d49 100644 --- a/drivers/net/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ixgbe/ixgbe_ipsec.c @@ -1,37 +1,8 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. - * All rights reserved. - * - * 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 Intel Corporation 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. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2017 Intel Corporation */ -#include +#include #include #include #include @@ -70,6 +41,8 @@ static void ixgbe_crypto_clear_ipsec_tables(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct ixgbe_ipsec *priv = IXGBE_DEV_PRIVATE_TO_IPSEC( + dev->data->dev_private); int i = 0; /* clear Rx IP table*/ @@ -106,6 +79,10 @@ ixgbe_crypto_clear_ipsec_tables(struct rte_eth_dev *dev) IXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, 0); IXGBE_WAIT_TWRITE; } + + memset(priv->rx_ip_tbl, 0, sizeof(priv->rx_ip_tbl)); + memset(priv->rx_sa_tbl, 0, sizeof(priv->rx_sa_tbl)); + memset(priv->tx_sa_tbl, 0, sizeof(priv->tx_sa_tbl)); } static int @@ -120,6 +97,7 @@ ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session) if (ic_session->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) { int i, ip_index = -1; + uint8_t *key; /* Find a match in the IP table*/ for (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) { @@ -173,22 +151,16 @@ ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session) priv->rx_sa_tbl[sa_index].spi = rte_cpu_to_be_32(ic_session->spi); priv->rx_sa_tbl[sa_index].ip_index = ip_index; - priv->rx_sa_tbl[sa_index].key[3] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[0]); - priv->rx_sa_tbl[sa_index].key[2] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[4]); - priv->rx_sa_tbl[sa_index].key[1] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[8]); - priv->rx_sa_tbl[sa_index].key[0] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[12]); - priv->rx_sa_tbl[sa_index].salt = - rte_cpu_to_be_32(ic_session->salt); priv->rx_sa_tbl[sa_index].mode = IPSRXMOD_VALID; if (ic_session->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) priv->rx_sa_tbl[sa_index].mode |= (IPSRXMOD_PROTO | IPSRXMOD_DECRYPT); - if (ic_session->dst_ip.type == IPv6) + if (ic_session->dst_ip.type == IPv6) { priv->rx_sa_tbl[sa_index].mode |= IPSRXMOD_IPV6; + priv->rx_ip_tbl[ip_index].ip.type = IPv6; + } else if (ic_session->dst_ip.type == IPv4) + priv->rx_ip_tbl[ip_index].ip.type = IPv4; + priv->rx_sa_tbl[sa_index].used = 1; /* write IP table entry*/ @@ -222,23 +194,32 @@ ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session) IXGBE_WAIT_RWRITE; /* write Key table entry*/ + key = malloc(ic_session->key_len); + if (!key) + return -ENOMEM; + + memcpy(key, ic_session->key, ic_session->key_len); + reg_val = IPSRXIDX_RX_EN | IPSRXIDX_WRITE | IPSRXIDX_TABLE_KEY | (sa_index << 3); IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(0), - priv->rx_sa_tbl[sa_index].key[0]); + rte_cpu_to_be_32(*(uint32_t *)&key[12])); IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(1), - priv->rx_sa_tbl[sa_index].key[1]); + rte_cpu_to_be_32(*(uint32_t *)&key[8])); IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(2), - priv->rx_sa_tbl[sa_index].key[2]); + rte_cpu_to_be_32(*(uint32_t *)&key[4])); IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(3), - priv->rx_sa_tbl[sa_index].key[3]); + rte_cpu_to_be_32(*(uint32_t *)&key[0])); IXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT, - priv->rx_sa_tbl[sa_index].salt); + rte_cpu_to_be_32(ic_session->salt)); IXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD, priv->rx_sa_tbl[sa_index].mode); IXGBE_WAIT_RWRITE; + free(key); + } else { /* sess->dir == RTE_CRYPTO_OUTBOUND */ + uint8_t *key; int i; /* Find a free entry in the SA table*/ @@ -257,32 +238,30 @@ ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session) priv->tx_sa_tbl[sa_index].spi = rte_cpu_to_be_32(ic_session->spi); - priv->tx_sa_tbl[sa_index].key[3] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[0]); - priv->tx_sa_tbl[sa_index].key[2] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[4]); - priv->tx_sa_tbl[sa_index].key[1] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[8]); - priv->tx_sa_tbl[sa_index].key[0] = - rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[12]); - priv->tx_sa_tbl[sa_index].salt = - rte_cpu_to_be_32(ic_session->salt); + priv->tx_sa_tbl[i].used = 1; + ic_session->sa_index = sa_index; + + key = malloc(ic_session->key_len); + if (!key) + return -ENOMEM; + + memcpy(key, ic_session->key, ic_session->key_len); + /* write Key table entry*/ reg_val = IPSRXIDX_RX_EN | IPSRXIDX_WRITE | (sa_index << 3); IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(0), - priv->tx_sa_tbl[sa_index].key[0]); + rte_cpu_to_be_32(*(uint32_t *)&key[12])); IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(1), - priv->tx_sa_tbl[sa_index].key[1]); + rte_cpu_to_be_32(*(uint32_t *)&key[8])); IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(2), - priv->tx_sa_tbl[sa_index].key[2]); + rte_cpu_to_be_32(*(uint32_t *)&key[4])); IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(3), - priv->tx_sa_tbl[sa_index].key[3]); + rte_cpu_to_be_32(*(uint32_t *)&key[0])); IXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, - priv->tx_sa_tbl[sa_index].salt); + rte_cpu_to_be_32(ic_session->salt)); IXGBE_WAIT_TWRITE; - priv->tx_sa_tbl[i].used = 1; - ic_session->sa_index = sa_index; + free(key); } return 0; @@ -407,6 +386,7 @@ ixgbe_crypto_create_session(void *device, conf->crypto_xform->aead.algo != RTE_CRYPTO_AEAD_AES_GCM) { PMD_DRV_LOG(ERR, "Unsupported crypto transformation mode\n"); + rte_mempool_put(mempool, (void *)ic_session); return -ENOTSUP; } aead_xform = &conf->crypto_xform->aead; @@ -416,6 +396,7 @@ ixgbe_crypto_create_session(void *device, ic_session->op = IXGBE_OP_AUTHENTICATED_DECRYPTION; } else { PMD_DRV_LOG(ERR, "IPsec decryption not enabled\n"); + rte_mempool_put(mempool, (void *)ic_session); return -ENOTSUP; } } else { @@ -423,11 +404,13 @@ ixgbe_crypto_create_session(void *device, ic_session->op = IXGBE_OP_AUTHENTICATED_ENCRYPTION; } else { PMD_DRV_LOG(ERR, "IPsec encryption not enabled\n"); + rte_mempool_put(mempool, (void *)ic_session); return -ENOTSUP; } } ic_session->key = aead_xform->key.data; + ic_session->key_len = aead_xform->key.length; memcpy(&ic_session->salt, &aead_xform->key.data[aead_xform->key.length], 4); ic_session->spi = conf->ipsec.spi; @@ -438,6 +421,7 @@ ixgbe_crypto_create_session(void *device, if (ic_session->op == IXGBE_OP_AUTHENTICATED_ENCRYPTION) { if (ixgbe_crypto_add_sa(ic_session)) { PMD_DRV_LOG(ERR, "Failed to add SA\n"); + rte_mempool_put(mempool, (void *)ic_session); return -EPERM; } } @@ -445,6 +429,12 @@ ixgbe_crypto_create_session(void *device, return 0; } +static unsigned int +ixgbe_crypto_session_get_size(__rte_unused void *device) +{ + return sizeof(struct ixgbe_crypto_session); +} + static int ixgbe_crypto_remove_session(void *device, struct rte_security_session *session) @@ -576,48 +566,48 @@ ixgbe_crypto_capabilities_get(void *device __rte_unused) { /* IPsec Inline Crypto ESP Transport Egress */ .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, .protocol = RTE_SECURITY_PROTOCOL_IPSEC, - .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 = aes_gcm_gmac_crypto_capabilities, .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA }, { /* IPsec Inline Crypto ESP Transport Ingress */ .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, .protocol = RTE_SECURITY_PROTOCOL_IPSEC, - .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 = aes_gcm_gmac_crypto_capabilities, .ol_flags = 0 }, { /* IPsec Inline Crypto ESP Tunnel Egress */ .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, .protocol = RTE_SECURITY_PROTOCOL_IPSEC, - .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 = aes_gcm_gmac_crypto_capabilities, .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA }, { /* IPsec Inline Crypto ESP Tunnel Ingress */ .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, .protocol = RTE_SECURITY_PROTOCOL_IPSEC, - .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 = aes_gcm_gmac_crypto_capabilities, .ol_flags = 0 }, @@ -635,13 +625,18 @@ ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint32_t reg; + uint64_t rx_offloads; + uint64_t tx_offloads; + + rx_offloads = dev->data->dev_conf.rxmode.offloads; + tx_offloads = dev->data->dev_conf.txmode.offloads; /* sanity checks */ - if (dev->data->dev_conf.rxmode.enable_lro) { + if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) { PMD_DRV_LOG(ERR, "RSC and IPsec not supported"); return -1; } - if (!dev->data->dev_conf.rxmode.hw_strip_crc) { + if (rx_offloads & DEV_RX_OFFLOAD_KEEP_CRC) { PMD_DRV_LOG(ERR, "HW CRC strip needs to be enabled for IPsec"); return -1; } @@ -661,7 +656,7 @@ ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev) reg |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_RXCRCSTRP; IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg); - if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SECURITY) { + if (rx_offloads & DEV_RX_OFFLOAD_SECURITY) { IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0); reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); if (reg != 0) { @@ -669,7 +664,7 @@ ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev) return -1; } } - if (dev->data->dev_conf.txmode.offloads & DEV_TX_OFFLOAD_SECURITY) { + if (tx_offloads & DEV_TX_OFFLOAD_SECURITY) { IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_STORE_FORWARD); reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL); @@ -717,21 +712,44 @@ ixgbe_crypto_add_ingress_sa_from_flow(const void *sess, static struct rte_security_ops ixgbe_security_ops = { .session_create = ixgbe_crypto_create_session, .session_update = NULL, + .session_get_size = ixgbe_crypto_session_get_size, .session_stats_get = NULL, .session_destroy = ixgbe_crypto_remove_session, .set_pkt_metadata = ixgbe_crypto_update_mb, .capabilities_get = ixgbe_crypto_capabilities_get }; -struct rte_security_ctx * +static int +ixgbe_crypto_capable(struct rte_eth_dev *dev) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t reg_i, reg, capable = 1; + /* test if rx crypto can be enabled and then write back initial value*/ + reg_i = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0); + reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + if (reg != 0) + capable = 0; + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg_i); + return capable; +} + +int ixgbe_ipsec_ctx_create(struct rte_eth_dev *dev) { - struct rte_security_ctx *ctx = rte_malloc("rte_security_instances_ops", - sizeof(struct rte_security_ctx), 0); - if (ctx) { - ctx->device = (void *)dev; - ctx->ops = &ixgbe_security_ops; - ctx->sess_cnt = 0; + struct rte_security_ctx *ctx = NULL; + + if (ixgbe_crypto_capable(dev)) { + ctx = rte_malloc("rte_security_instances_ops", + sizeof(struct rte_security_ctx), 0); + if (ctx) { + ctx->device = (void *)dev; + ctx->ops = &ixgbe_security_ops; + ctx->sess_cnt = 0; + dev->security_ctx = ctx; + } else { + return -ENOMEM; + } } - return ctx; + return 0; }