2017-12-19 15:49:02 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright(c) 2016-2017 Intel Corporation
|
2016-03-11 02:12:40 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2016-03-31 12:43:10 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/ip.h>
|
2016-06-09 08:42:48 +00:00
|
|
|
#include <netinet/ip6.h>
|
2016-03-11 02:12:40 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <rte_common.h>
|
|
|
|
#include <rte_crypto.h>
|
|
|
|
#include <rte_cryptodev.h>
|
|
|
|
#include <rte_random.h>
|
|
|
|
|
|
|
|
#include "ipsec.h"
|
|
|
|
#include "esp.h"
|
|
|
|
#include "ipip.h"
|
|
|
|
|
|
|
|
int
|
2016-06-09 08:42:45 +00:00
|
|
|
esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
|
2016-03-11 02:12:40 +00:00
|
|
|
struct rte_crypto_op *cop)
|
|
|
|
{
|
2016-06-09 08:42:49 +00:00
|
|
|
struct ip *ip4;
|
2016-03-11 02:12:40 +00:00
|
|
|
struct rte_crypto_sym_op *sym_cop;
|
2016-06-09 08:42:49 +00:00
|
|
|
int32_t payload_len, ip_hdr_len;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-04-22 12:21:26 +00:00
|
|
|
RTE_ASSERT(sa != NULL);
|
2019-10-14 13:48:39 +00:00
|
|
|
if (ipsec_get_action_type(sa) ==
|
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
|
2017-10-25 15:07:27 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
RTE_ASSERT(m != NULL);
|
2016-04-22 12:21:26 +00:00
|
|
|
RTE_ASSERT(cop != NULL);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-06-09 08:42:49 +00:00
|
|
|
ip4 = rte_pktmbuf_mtod(m, struct ip *);
|
|
|
|
if (likely(ip4->ip_v == IPVERSION))
|
|
|
|
ip_hdr_len = ip4->ip_hl * 4;
|
|
|
|
else if (ip4->ip_v == IP6_VERSION)
|
|
|
|
/* XXX No option headers supported */
|
2016-06-09 08:42:48 +00:00
|
|
|
ip_hdr_len = sizeof(struct ip6_hdr);
|
2016-06-09 08:42:49 +00:00
|
|
|
else {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "invalid IP packet type %d\n",
|
|
|
|
ip4->ip_v);
|
|
|
|
return -EINVAL;
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
payload_len = rte_pktmbuf_pkt_len(m) - ip_hdr_len -
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr) - sa->iv_len - sa->digest_len;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
if ((payload_len & (sa->block_size - 1)) || (payload_len <= 0)) {
|
2016-11-23 15:34:25 +00:00
|
|
|
RTE_LOG_DP(DEBUG, IPSEC_ESP, "payload %d not multiple of %u\n",
|
2016-03-11 02:12:40 +00:00
|
|
|
payload_len, sa->block_size);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2016-09-29 15:44:07 +00:00
|
|
|
sym_cop = get_sym_cop(cop);
|
2016-03-11 02:12:40 +00:00
|
|
|
sym_cop->m_src = m;
|
2017-07-02 05:41:26 +00:00
|
|
|
|
|
|
|
if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
|
2019-05-21 16:13:06 +00:00
|
|
|
sym_cop->aead.data.offset =
|
|
|
|
ip_hdr_len + sizeof(struct rte_esp_hdr) + sa->iv_len;
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.data.length = payload_len;
|
|
|
|
|
|
|
|
struct cnt_blk *icb;
|
|
|
|
uint8_t *aad;
|
2019-05-21 16:13:06 +00:00
|
|
|
uint8_t *iv = RTE_PTR_ADD(ip4, ip_hdr_len +
|
|
|
|
sizeof(struct rte_esp_hdr));
|
2017-07-02 05:41:26 +00:00
|
|
|
|
2016-09-29 15:44:09 +00:00
|
|
|
icb = get_cnt_blk(m);
|
|
|
|
icb->salt = sa->salt;
|
|
|
|
memcpy(&icb->iv, iv, 8);
|
|
|
|
icb->cnt = rte_cpu_to_be_32(1);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-29 15:44:09 +00:00
|
|
|
aad = get_aad(m);
|
2019-05-21 16:13:06 +00:00
|
|
|
memcpy(aad, iv - sizeof(struct rte_esp_hdr), 8);
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.aad.data = aad;
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->aead.aad.phys_addr = rte_pktmbuf_iova_offset(m,
|
2016-09-29 15:44:09 +00:00
|
|
|
aad - rte_pktmbuf_mtod(m, uint8_t *));
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.digest.data = rte_pktmbuf_mtod_offset(m, void*,
|
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->aead.digest.phys_addr = rte_pktmbuf_iova_offset(m,
|
2017-07-02 05:41:26 +00:00
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
|
|
|
} else {
|
2019-05-21 16:13:06 +00:00
|
|
|
sym_cop->cipher.data.offset = ip_hdr_len +
|
|
|
|
sizeof(struct rte_esp_hdr) +
|
2017-07-02 05:41:26 +00:00
|
|
|
sa->iv_len;
|
|
|
|
sym_cop->cipher.data.length = payload_len;
|
|
|
|
|
|
|
|
struct cnt_blk *icb;
|
2019-05-21 16:13:06 +00:00
|
|
|
uint8_t *iv = RTE_PTR_ADD(ip4, ip_hdr_len +
|
|
|
|
sizeof(struct rte_esp_hdr));
|
2017-07-02 05:41:26 +00:00
|
|
|
uint8_t *iv_ptr = rte_crypto_op_ctod_offset(cop,
|
|
|
|
uint8_t *, IV_OFFSET);
|
|
|
|
|
|
|
|
switch (sa->cipher_algo) {
|
|
|
|
case RTE_CRYPTO_CIPHER_NULL:
|
2018-07-25 09:49:43 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_3DES_CBC:
|
2017-07-02 05:41:26 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_AES_CBC:
|
|
|
|
/* Copy IV at the end of crypto operation */
|
|
|
|
rte_memcpy(iv_ptr, iv, sa->iv_len);
|
|
|
|
break;
|
|
|
|
case RTE_CRYPTO_CIPHER_AES_CTR:
|
|
|
|
icb = get_cnt_blk(m);
|
|
|
|
icb->salt = sa->salt;
|
|
|
|
memcpy(&icb->iv, iv, 8);
|
|
|
|
icb->cnt = rte_cpu_to_be_32(1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
|
|
|
|
sa->cipher_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (sa->auth_algo) {
|
|
|
|
case RTE_CRYPTO_AUTH_NULL:
|
|
|
|
case RTE_CRYPTO_AUTH_SHA1_HMAC:
|
|
|
|
case RTE_CRYPTO_AUTH_SHA256_HMAC:
|
|
|
|
sym_cop->auth.data.offset = ip_hdr_len;
|
2019-05-21 16:13:06 +00:00
|
|
|
sym_cop->auth.data.length = sizeof(struct rte_esp_hdr) +
|
2017-07-02 05:41:26 +00:00
|
|
|
sa->iv_len + payload_len;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "unsupported auth algorithm %u\n",
|
|
|
|
sa->auth_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sym_cop->auth.digest.data = rte_pktmbuf_mtod_offset(m, void*,
|
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->auth.digest.phys_addr = rte_pktmbuf_iova_offset(m,
|
2017-07-02 05:41:26 +00:00
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2016-06-09 08:42:45 +00:00
|
|
|
esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
|
2016-03-11 02:12:40 +00:00
|
|
|
struct rte_crypto_op *cop)
|
|
|
|
{
|
2016-06-09 08:42:49 +00:00
|
|
|
struct ip *ip4, *ip;
|
|
|
|
struct ip6_hdr *ip6;
|
2016-03-11 02:12:40 +00:00
|
|
|
uint8_t *nexthdr, *pad_len;
|
|
|
|
uint8_t *padding;
|
|
|
|
uint16_t i;
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-04-22 12:21:26 +00:00
|
|
|
RTE_ASSERT(m != NULL);
|
|
|
|
RTE_ASSERT(sa != NULL);
|
|
|
|
RTE_ASSERT(cop != NULL);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
ips = ipsec_get_primary_session(sa);
|
2019-10-14 13:48:39 +00:00
|
|
|
|
|
|
|
if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
|
|
|
|
(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
|
2017-10-25 15:07:27 +00:00
|
|
|
if (m->ol_flags & PKT_RX_SEC_OFFLOAD) {
|
|
|
|
if (m->ol_flags & PKT_RX_SEC_OFFLOAD_FAILED)
|
|
|
|
cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
|
|
|
|
else
|
|
|
|
cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
|
|
|
|
} else
|
|
|
|
cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
|
|
|
|
}
|
|
|
|
|
2016-03-11 02:12:40 +00:00
|
|
|
if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
|
2019-03-07 10:34:52 +00:00
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "%s() failed crypto op\n", __func__);
|
2016-03-11 02:12:40 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-10-14 13:48:39 +00:00
|
|
|
if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
|
|
|
|
ips->security.ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
|
2017-10-25 15:07:27 +00:00
|
|
|
nexthdr = &m->inner_esp_next_proto;
|
|
|
|
} else {
|
|
|
|
nexthdr = rte_pktmbuf_mtod_offset(m, uint8_t*,
|
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len - 1);
|
|
|
|
pad_len = nexthdr - 1;
|
|
|
|
|
|
|
|
padding = pad_len - *pad_len;
|
|
|
|
for (i = 0; i < *pad_len; i++) {
|
|
|
|
if (padding[i] != i + 1) {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "invalid padding\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
if (rte_pktmbuf_trim(m, *pad_len + 2 + sa->digest_len)) {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP,
|
|
|
|
"failed to remove pad_len + digest\n");
|
2016-03-11 02:12:40 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
if (unlikely(IS_TRANSPORT(sa->flags))) {
|
2016-06-09 08:42:49 +00:00
|
|
|
ip = rte_pktmbuf_mtod(m, struct ip *);
|
|
|
|
ip4 = (struct ip *)rte_pktmbuf_adj(m,
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr) + sa->iv_len);
|
2016-06-09 08:42:49 +00:00
|
|
|
if (likely(ip->ip_v == IPVERSION)) {
|
|
|
|
memmove(ip4, ip, ip->ip_hl * 4);
|
|
|
|
ip4->ip_p = *nexthdr;
|
|
|
|
ip4->ip_len = htons(rte_pktmbuf_data_len(m));
|
|
|
|
} else {
|
|
|
|
ip6 = (struct ip6_hdr *)ip4;
|
|
|
|
/* XXX No option headers supported */
|
|
|
|
memmove(ip6, ip, sizeof(struct ip6_hdr));
|
|
|
|
ip6->ip6_nxt = *nexthdr;
|
2017-10-13 08:04:36 +00:00
|
|
|
ip6->ip6_plen = htons(rte_pktmbuf_data_len(m) -
|
|
|
|
sizeof(struct ip6_hdr));
|
2016-06-09 08:42:49 +00:00
|
|
|
}
|
|
|
|
} else
|
2019-05-21 16:13:06 +00:00
|
|
|
ipip_inbound(m, sizeof(struct rte_esp_hdr) + sa->iv_len);
|
2016-06-09 08:42:48 +00:00
|
|
|
|
|
|
|
return 0;
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2016-06-09 08:42:45 +00:00
|
|
|
esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
|
2016-03-11 02:12:40 +00:00
|
|
|
struct rte_crypto_op *cop)
|
|
|
|
{
|
2016-06-09 08:42:48 +00:00
|
|
|
struct ip *ip4;
|
|
|
|
struct ip6_hdr *ip6;
|
2019-05-21 16:13:06 +00:00
|
|
|
struct rte_esp_hdr *esp = NULL;
|
2017-10-25 15:07:27 +00:00
|
|
|
uint8_t *padding = NULL, *new_ip, nlp;
|
2016-03-11 02:12:40 +00:00
|
|
|
struct rte_crypto_sym_op *sym_cop;
|
2016-06-09 08:42:49 +00:00
|
|
|
int32_t i;
|
|
|
|
uint16_t pad_payload_len, pad_len, ip_hdr_len;
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-04-22 12:21:26 +00:00
|
|
|
RTE_ASSERT(m != NULL);
|
|
|
|
RTE_ASSERT(sa != NULL);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
ips = ipsec_get_primary_session(sa);
|
2016-06-09 08:42:48 +00:00
|
|
|
ip_hdr_len = 0;
|
2016-06-09 08:42:49 +00:00
|
|
|
|
|
|
|
ip4 = rte_pktmbuf_mtod(m, struct ip *);
|
|
|
|
if (likely(ip4->ip_v == IPVERSION)) {
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
if (unlikely(IS_TRANSPORT(sa->flags))) {
|
2016-06-09 08:42:49 +00:00
|
|
|
ip_hdr_len = ip4->ip_hl * 4;
|
|
|
|
nlp = ip4->ip_p;
|
|
|
|
} else
|
|
|
|
nlp = IPPROTO_IPIP;
|
|
|
|
} else if (ip4->ip_v == IP6_VERSION) {
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
if (unlikely(IS_TRANSPORT(sa->flags))) {
|
2016-06-09 08:42:49 +00:00
|
|
|
/* XXX No option headers supported */
|
|
|
|
ip_hdr_len = sizeof(struct ip6_hdr);
|
|
|
|
ip6 = (struct ip6_hdr *)ip4;
|
|
|
|
nlp = ip6->ip6_nxt;
|
|
|
|
} else
|
|
|
|
nlp = IPPROTO_IPV6;
|
|
|
|
} else {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "invalid IP packet type %d\n",
|
|
|
|
ip4->ip_v);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Padded payload length */
|
|
|
|
pad_payload_len = RTE_ALIGN_CEIL(rte_pktmbuf_pkt_len(m) -
|
|
|
|
ip_hdr_len + 2, sa->block_size);
|
|
|
|
pad_len = pad_payload_len + ip_hdr_len - rte_pktmbuf_pkt_len(m);
|
|
|
|
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
RTE_ASSERT(IS_TUNNEL(sa->flags) || IS_TRANSPORT(sa->flags));
|
2016-06-09 08:42:49 +00:00
|
|
|
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
if (likely(IS_IP4_TUNNEL(sa->flags)))
|
2016-06-09 08:42:48 +00:00
|
|
|
ip_hdr_len = sizeof(struct ip);
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
else if (IS_IP6_TUNNEL(sa->flags))
|
2016-06-09 08:42:48 +00:00
|
|
|
ip_hdr_len = sizeof(struct ip6_hdr);
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
else if (!IS_TRANSPORT(sa->flags)) {
|
2016-06-09 08:42:49 +00:00
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "Unsupported SA flags: 0x%x\n",
|
|
|
|
sa->flags);
|
|
|
|
return -EINVAL;
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
/* Check maximum packet size */
|
2019-05-21 16:13:06 +00:00
|
|
|
if (unlikely(ip_hdr_len + sizeof(struct rte_esp_hdr) + sa->iv_len +
|
2016-06-09 08:42:48 +00:00
|
|
|
pad_payload_len + sa->digest_len > IP_MAXPACKET)) {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "ipsec packet is too big\n");
|
2016-03-11 02:12:40 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
/* Add trailer padding if it is not constructed by HW */
|
2019-10-14 13:48:39 +00:00
|
|
|
if (ips->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
|
|
|
|
(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
|
|
|
|
!(ips->security.ol_flags &
|
|
|
|
RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
|
2017-10-25 15:07:27 +00:00
|
|
|
padding = (uint8_t *)rte_pktmbuf_append(m, pad_len +
|
|
|
|
sa->digest_len);
|
|
|
|
if (unlikely(padding == NULL)) {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP,
|
|
|
|
"not enough mbuf trailing space\n");
|
|
|
|
return -ENOSPC;
|
|
|
|
}
|
|
|
|
rte_prefetch0(padding);
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
|
|
|
|
examples/ipsec-secgw: fix inline modes
Application ipsec-secgw is not working for IPv4 transport mode and for
IPv6 both transport and tunnel mode.
IPv6 tunnel mode is not working due to wrongly assigned fields of
security association patterns, as it was IPv4, during creation of
inline crypto session.
IPv6 and IPv4 transport mode is iterating through security capabilities
until it reaches tunnel, which causes session to be created as tunnel,
instead of transport. Another issue, is that config file does not
provide source and destination ip addresses for transport mode, which
are required by NIC to perform inline crypto. It uses default addresses
stored in security association (all zeroes), which causes dropped
packages.
To fix that, reorganization of code in create_session() is needed,
to behave appropriately to given protocol (IPv6/IPv4). Change in
iteration through security capabilities is also required, to check
for expected mode (not only tunnel).
For lack of addresses issue, some resolving mechanism is needed.
Approach is to store addresses in security association, as it is
for tunnel mode. Difference is that they are obtained from sp rules,
instead of config file. To do that, sp[4/6]_spi_present() function
is used to find addresses based on spi value, and then stored in
corresponding sa rule. This approach assumes, that every sp rule
for inline crypto have valid addresses, as well as range of addresses
is not supported.
New flags for ipsec_sa structure are required to distinguish between
IPv4 and IPv6 transport modes. Because of that, there is need to
change all checks done on these flags, so they work as expected.
Fixes: ec17993a145a ("examples/ipsec-secgw: support security offload")
Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: stable@dpdk.org
Signed-off-by: Mariusz Drost <mariuszx.drost@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2019-06-26 13:26:17 +00:00
|
|
|
switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
|
2016-06-09 08:42:48 +00:00
|
|
|
case IP4_TUNNEL:
|
2019-05-21 16:13:06 +00:00
|
|
|
ip4 = ip4ip_outbound(m, sizeof(struct rte_esp_hdr) + sa->iv_len,
|
2016-06-09 08:42:48 +00:00
|
|
|
&sa->src, &sa->dst);
|
2019-05-21 16:13:06 +00:00
|
|
|
esp = (struct rte_esp_hdr *)(ip4 + 1);
|
2016-06-09 08:42:48 +00:00
|
|
|
break;
|
|
|
|
case IP6_TUNNEL:
|
2019-05-21 16:13:06 +00:00
|
|
|
ip6 = ip6ip_outbound(m, sizeof(struct rte_esp_hdr) + sa->iv_len,
|
2016-06-09 08:42:48 +00:00
|
|
|
&sa->src, &sa->dst);
|
2019-05-21 16:13:06 +00:00
|
|
|
esp = (struct rte_esp_hdr *)(ip6 + 1);
|
2016-06-09 08:42:48 +00:00
|
|
|
break;
|
2016-06-09 08:42:49 +00:00
|
|
|
case TRANSPORT:
|
|
|
|
new_ip = (uint8_t *)rte_pktmbuf_prepend(m,
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr) + sa->iv_len);
|
2016-06-09 08:42:49 +00:00
|
|
|
memmove(new_ip, ip4, ip_hdr_len);
|
2019-05-21 16:13:06 +00:00
|
|
|
esp = (struct rte_esp_hdr *)(new_ip + ip_hdr_len);
|
2017-10-13 12:50:09 +00:00
|
|
|
ip4 = (struct ip *)new_ip;
|
2016-06-09 08:42:49 +00:00
|
|
|
if (likely(ip4->ip_v == IPVERSION)) {
|
|
|
|
ip4->ip_p = IPPROTO_ESP;
|
|
|
|
ip4->ip_len = htons(rte_pktmbuf_data_len(m));
|
|
|
|
} else {
|
|
|
|
ip6 = (struct ip6_hdr *)new_ip;
|
|
|
|
ip6->ip6_nxt = IPPROTO_ESP;
|
2017-10-13 08:04:36 +00:00
|
|
|
ip6->ip6_plen = htons(rte_pktmbuf_data_len(m) -
|
|
|
|
sizeof(struct ip6_hdr));
|
2016-06-09 08:42:49 +00:00
|
|
|
}
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-06-09 08:42:48 +00:00
|
|
|
sa->seq++;
|
|
|
|
esp->spi = rte_cpu_to_be_32(sa->spi);
|
2016-09-29 15:44:07 +00:00
|
|
|
esp->seq = rte_cpu_to_be_32((uint32_t)sa->seq);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
/* set iv */
|
2016-09-29 15:44:07 +00:00
|
|
|
uint64_t *iv = (uint64_t *)(esp + 1);
|
2017-10-25 15:07:27 +00:00
|
|
|
if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
|
|
|
|
*iv = rte_cpu_to_be_64(sa->seq);
|
|
|
|
} else {
|
|
|
|
switch (sa->cipher_algo) {
|
|
|
|
case RTE_CRYPTO_CIPHER_NULL:
|
2018-07-25 09:49:43 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_3DES_CBC:
|
2017-10-25 15:07:27 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_AES_CBC:
|
|
|
|
memset(iv, 0, sa->iv_len);
|
|
|
|
break;
|
|
|
|
case RTE_CRYPTO_CIPHER_AES_CTR:
|
|
|
|
*iv = rte_cpu_to_be_64(sa->seq);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP,
|
|
|
|
"unsupported cipher algorithm %u\n",
|
|
|
|
sa->cipher_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-14 13:48:39 +00:00
|
|
|
if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
|
|
|
|
if (ips->security.ol_flags &
|
|
|
|
RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
|
2017-10-25 15:07:27 +00:00
|
|
|
/* Set the inner esp next protocol for HW trailer */
|
|
|
|
m->inner_esp_next_proto = nlp;
|
|
|
|
m->packet_type |= RTE_PTYPE_TUNNEL_ESP;
|
|
|
|
} else {
|
|
|
|
padding[pad_len - 2] = pad_len - 2;
|
|
|
|
padding[pad_len - 1] = nlp;
|
|
|
|
}
|
|
|
|
goto done;
|
|
|
|
}
|
2016-09-29 15:44:07 +00:00
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
RTE_ASSERT(cop != NULL);
|
2016-09-29 15:44:07 +00:00
|
|
|
sym_cop = get_sym_cop(cop);
|
|
|
|
sym_cop->m_src = m;
|
2017-07-02 05:41:26 +00:00
|
|
|
|
|
|
|
if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
|
|
|
|
uint8_t *aad;
|
|
|
|
|
|
|
|
sym_cop->aead.data.offset = ip_hdr_len +
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr) + sa->iv_len;
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.data.length = pad_payload_len;
|
|
|
|
|
|
|
|
/* Fill pad_len using default sequential scheme */
|
|
|
|
for (i = 0; i < pad_len - 2; i++)
|
|
|
|
padding[i] = i + 1;
|
|
|
|
padding[pad_len - 2] = pad_len - 2;
|
|
|
|
padding[pad_len - 1] = nlp;
|
|
|
|
|
|
|
|
struct cnt_blk *icb = get_cnt_blk(m);
|
|
|
|
icb->salt = sa->salt;
|
2017-10-24 12:49:00 +00:00
|
|
|
icb->iv = rte_cpu_to_be_64(sa->seq);
|
2017-07-02 05:41:26 +00:00
|
|
|
icb->cnt = rte_cpu_to_be_32(1);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-29 15:44:09 +00:00
|
|
|
aad = get_aad(m);
|
|
|
|
memcpy(aad, esp, 8);
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.aad.data = aad;
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->aead.aad.phys_addr = rte_pktmbuf_iova_offset(m,
|
2016-09-29 15:44:09 +00:00
|
|
|
aad - rte_pktmbuf_mtod(m, uint8_t *));
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->aead.digest.data = rte_pktmbuf_mtod_offset(m, uint8_t *,
|
2016-06-09 08:42:48 +00:00
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->aead.digest.phys_addr = rte_pktmbuf_iova_offset(m,
|
2016-06-09 08:42:48 +00:00
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
2017-07-02 05:41:26 +00:00
|
|
|
} else {
|
|
|
|
switch (sa->cipher_algo) {
|
|
|
|
case RTE_CRYPTO_CIPHER_NULL:
|
2018-07-25 09:49:43 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_3DES_CBC:
|
2017-07-02 05:41:26 +00:00
|
|
|
case RTE_CRYPTO_CIPHER_AES_CBC:
|
|
|
|
sym_cop->cipher.data.offset = ip_hdr_len +
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr);
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->cipher.data.length = pad_payload_len + sa->iv_len;
|
|
|
|
break;
|
|
|
|
case RTE_CRYPTO_CIPHER_AES_CTR:
|
|
|
|
sym_cop->cipher.data.offset = ip_hdr_len +
|
2019-05-21 16:13:06 +00:00
|
|
|
sizeof(struct rte_esp_hdr) + sa->iv_len;
|
2017-07-02 05:41:26 +00:00
|
|
|
sym_cop->cipher.data.length = pad_payload_len;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
|
|
|
|
sa->cipher_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill pad_len using default sequential scheme */
|
|
|
|
for (i = 0; i < pad_len - 2; i++)
|
|
|
|
padding[i] = i + 1;
|
|
|
|
padding[pad_len - 2] = pad_len - 2;
|
|
|
|
padding[pad_len - 1] = nlp;
|
|
|
|
|
|
|
|
struct cnt_blk *icb = get_cnt_blk(m);
|
|
|
|
icb->salt = sa->salt;
|
2017-10-24 12:49:00 +00:00
|
|
|
icb->iv = rte_cpu_to_be_64(sa->seq);
|
2017-07-02 05:41:26 +00:00
|
|
|
icb->cnt = rte_cpu_to_be_32(1);
|
|
|
|
|
|
|
|
switch (sa->auth_algo) {
|
|
|
|
case RTE_CRYPTO_AUTH_NULL:
|
|
|
|
case RTE_CRYPTO_AUTH_SHA1_HMAC:
|
|
|
|
case RTE_CRYPTO_AUTH_SHA256_HMAC:
|
|
|
|
sym_cop->auth.data.offset = ip_hdr_len;
|
2019-05-21 16:13:06 +00:00
|
|
|
sym_cop->auth.data.length = sizeof(struct rte_esp_hdr) +
|
2017-07-02 05:41:26 +00:00
|
|
|
sa->iv_len + pad_payload_len;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "unsupported auth algorithm %u\n",
|
|
|
|
sa->auth_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sym_cop->auth.digest.data = rte_pktmbuf_mtod_offset(m, uint8_t *,
|
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
2017-11-05 23:22:55 +00:00
|
|
|
sym_cop->auth.digest.phys_addr = rte_pktmbuf_iova_offset(m,
|
2017-07-02 05:41:26 +00:00
|
|
|
rte_pktmbuf_pkt_len(m) - sa->digest_len);
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
done:
|
2016-03-11 02:12:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2017-10-25 15:07:27 +00:00
|
|
|
esp_outbound_post(struct rte_mbuf *m,
|
|
|
|
struct ipsec_sa *sa,
|
|
|
|
struct rte_crypto_op *cop)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2019-10-14 13:48:39 +00:00
|
|
|
enum rte_security_session_action_type type;
|
2016-04-22 12:21:26 +00:00
|
|
|
RTE_ASSERT(m != NULL);
|
|
|
|
RTE_ASSERT(sa != NULL);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-10-14 13:48:39 +00:00
|
|
|
type = ipsec_get_action_type(sa);
|
|
|
|
|
|
|
|
if ((type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
|
|
|
|
(type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
|
2017-10-25 15:07:27 +00:00
|
|
|
m->ol_flags |= PKT_TX_SEC_OFFLOAD;
|
|
|
|
} else {
|
|
|
|
RTE_ASSERT(cop != NULL);
|
|
|
|
if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
|
2019-03-07 10:34:52 +00:00
|
|
|
RTE_LOG(ERR, IPSEC_ESP, "%s() failed crypto op\n",
|
|
|
|
__func__);
|
2017-10-25 15:07:27 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|