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
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Security Associations
|
|
|
|
*/
|
2016-03-31 12:43:10 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <netinet/in.h>
|
2016-03-11 02:12:40 +00:00
|
|
|
#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 <rte_memzone.h>
|
|
|
|
#include <rte_crypto.h>
|
2017-10-25 15:07:27 +00:00
|
|
|
#include <rte_security.h>
|
2016-03-11 02:12:40 +00:00
|
|
|
#include <rte_cryptodev.h>
|
|
|
|
#include <rte_byteorder.h>
|
|
|
|
#include <rte_errno.h>
|
2016-06-09 08:42:48 +00:00
|
|
|
#include <rte_ip.h>
|
2016-09-29 15:44:13 +00:00
|
|
|
#include <rte_random.h>
|
2017-10-25 15:07:27 +00:00
|
|
|
#include <rte_ethdev.h>
|
2019-01-10 21:09:10 +00:00
|
|
|
#include <rte_malloc.h>
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
#include "ipsec.h"
|
|
|
|
#include "esp.h"
|
2016-09-21 12:05:18 +00:00
|
|
|
#include "parser.h"
|
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
#define IPDEFTTL 64
|
|
|
|
|
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
|
|
|
#define IP4_FULL_MASK (sizeof(((struct ip_addr *)NULL)->ip.ip4) * CHAR_BIT)
|
|
|
|
|
|
|
|
#define IP6_FULL_MASK (sizeof(((struct ip_addr *)NULL)->ip.ip6.ip6) * CHAR_BIT)
|
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
#define MBUF_NO_SEC_OFFLOAD(m) ((m->ol_flags & PKT_RX_SEC_OFFLOAD) == 0)
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
struct supported_cipher_algo {
|
|
|
|
const char *keyword;
|
|
|
|
enum rte_crypto_cipher_algorithm algo;
|
|
|
|
uint16_t iv_len;
|
|
|
|
uint16_t block_size;
|
|
|
|
uint16_t key_len;
|
|
|
|
};
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
struct supported_auth_algo {
|
|
|
|
const char *keyword;
|
|
|
|
enum rte_crypto_auth_algorithm algo;
|
|
|
|
uint16_t digest_len;
|
|
|
|
uint16_t key_len;
|
2016-09-29 15:44:09 +00:00
|
|
|
uint8_t key_not_req;
|
2016-03-11 02:12:40 +00:00
|
|
|
};
|
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
struct supported_aead_algo {
|
|
|
|
const char *keyword;
|
|
|
|
enum rte_crypto_aead_algorithm algo;
|
|
|
|
uint16_t iv_len;
|
|
|
|
uint16_t block_size;
|
|
|
|
uint16_t digest_len;
|
|
|
|
uint16_t key_len;
|
|
|
|
uint8_t aad_len;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
const struct supported_cipher_algo cipher_algos[] = {
|
2016-06-09 08:42:49 +00:00
|
|
|
{
|
2016-09-21 12:05:18 +00:00
|
|
|
.keyword = "null",
|
|
|
|
.algo = RTE_CRYPTO_CIPHER_NULL,
|
|
|
|
.iv_len = 0,
|
|
|
|
.block_size = 4,
|
|
|
|
.key_len = 0
|
2016-06-09 08:42:49 +00:00
|
|
|
},
|
|
|
|
{
|
2016-09-21 12:05:18 +00:00
|
|
|
.keyword = "aes-128-cbc",
|
|
|
|
.algo = RTE_CRYPTO_CIPHER_AES_CBC,
|
|
|
|
.iv_len = 16,
|
|
|
|
.block_size = 16,
|
|
|
|
.key_len = 16
|
2016-09-29 15:44:09 +00:00
|
|
|
},
|
2018-02-08 06:12:42 +00:00
|
|
|
{
|
|
|
|
.keyword = "aes-256-cbc",
|
|
|
|
.algo = RTE_CRYPTO_CIPHER_AES_CBC,
|
|
|
|
.iv_len = 16,
|
|
|
|
.block_size = 16,
|
|
|
|
.key_len = 32
|
|
|
|
},
|
2016-09-29 15:44:10 +00:00
|
|
|
{
|
|
|
|
.keyword = "aes-128-ctr",
|
|
|
|
.algo = RTE_CRYPTO_CIPHER_AES_CTR,
|
|
|
|
.iv_len = 8,
|
2019-03-05 14:40:41 +00:00
|
|
|
.block_size = 4,
|
2016-09-29 15:44:13 +00:00
|
|
|
.key_len = 20
|
2018-07-25 09:49:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.keyword = "3des-cbc",
|
|
|
|
.algo = RTE_CRYPTO_CIPHER_3DES_CBC,
|
|
|
|
.iv_len = 8,
|
|
|
|
.block_size = 8,
|
|
|
|
.key_len = 24
|
2016-09-21 12:05:18 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct supported_auth_algo auth_algos[] = {
|
2016-06-09 08:42:48 +00:00
|
|
|
{
|
2016-09-21 12:05:18 +00:00
|
|
|
.keyword = "null",
|
|
|
|
.algo = RTE_CRYPTO_AUTH_NULL,
|
|
|
|
.digest_len = 0,
|
2016-09-29 15:44:09 +00:00
|
|
|
.key_len = 0,
|
|
|
|
.key_not_req = 1
|
2016-06-09 08:42:45 +00:00
|
|
|
},
|
|
|
|
{
|
2016-09-21 12:05:18 +00:00
|
|
|
.keyword = "sha1-hmac",
|
|
|
|
.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
|
|
|
|
.digest_len = 12,
|
|
|
|
.key_len = 20
|
2016-09-29 15:44:09 +00:00
|
|
|
},
|
2017-01-12 14:52:37 +00:00
|
|
|
{
|
|
|
|
.keyword = "sha256-hmac",
|
|
|
|
.algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
|
2019-11-06 09:53:22 +00:00
|
|
|
.digest_len = 16,
|
2017-01-12 14:52:37 +00:00
|
|
|
.key_len = 32
|
2017-07-02 05:41:26 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct supported_aead_algo aead_algos[] = {
|
2016-09-29 15:44:09 +00:00
|
|
|
{
|
|
|
|
.keyword = "aes-128-gcm",
|
2017-07-02 05:41:26 +00:00
|
|
|
.algo = RTE_CRYPTO_AEAD_AES_GCM,
|
|
|
|
.iv_len = 8,
|
|
|
|
.block_size = 4,
|
|
|
|
.key_len = 20,
|
2016-09-29 15:44:09 +00:00
|
|
|
.digest_len = 16,
|
|
|
|
.aad_len = 8,
|
2016-09-21 12:05:18 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
};
|
|
|
|
|
2019-04-04 12:13:26 +00:00
|
|
|
static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES];
|
|
|
|
static uint32_t nb_sa_out;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-04-04 12:13:26 +00:00
|
|
|
static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES];
|
|
|
|
static uint32_t nb_sa_in;
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
static const struct supported_cipher_algo *
|
|
|
|
find_match_cipher_algo(const char *cipher_keyword)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < RTE_DIM(cipher_algos); i++) {
|
|
|
|
const struct supported_cipher_algo *algo =
|
|
|
|
&cipher_algos[i];
|
|
|
|
|
|
|
|
if (strcmp(cipher_keyword, algo->keyword) == 0)
|
|
|
|
return algo;
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct supported_auth_algo *
|
|
|
|
find_match_auth_algo(const char *auth_keyword)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < RTE_DIM(auth_algos); i++) {
|
|
|
|
const struct supported_auth_algo *algo =
|
|
|
|
&auth_algos[i];
|
|
|
|
|
|
|
|
if (strcmp(auth_keyword, algo->keyword) == 0)
|
|
|
|
return algo;
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
static const struct supported_aead_algo *
|
|
|
|
find_match_aead_algo(const char *aead_keyword)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < RTE_DIM(aead_algos); i++) {
|
|
|
|
const struct supported_aead_algo *algo =
|
|
|
|
&aead_algos[i];
|
|
|
|
|
|
|
|
if (strcmp(aead_keyword, algo->keyword) == 0)
|
|
|
|
return algo;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
/** parse_key_string
|
|
|
|
* parse x:x:x:x.... hex number key string into uint8_t *key
|
|
|
|
* return:
|
|
|
|
* > 0: number of bytes parsed
|
|
|
|
* 0: failed
|
|
|
|
*/
|
|
|
|
static uint32_t
|
|
|
|
parse_key_string(const char *key_str, uint8_t *key)
|
|
|
|
{
|
|
|
|
const char *pt_start = key_str, *pt_end = key_str;
|
|
|
|
uint32_t nb_bytes = 0;
|
|
|
|
|
|
|
|
while (pt_end != NULL) {
|
2016-11-07 14:21:06 +00:00
|
|
|
char sub_str[3] = {0};
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
pt_end = strchr(pt_start, ':');
|
|
|
|
|
2016-11-07 14:21:06 +00:00
|
|
|
if (pt_end == NULL) {
|
|
|
|
if (strlen(pt_start) > 2)
|
|
|
|
return 0;
|
|
|
|
strncpy(sub_str, pt_start, 2);
|
|
|
|
} else {
|
2016-09-21 12:05:18 +00:00
|
|
|
if (pt_end - pt_start > 2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
strncpy(sub_str, pt_start, pt_end - pt_start);
|
|
|
|
pt_start = pt_end + 1;
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
key[nb_bytes++] = strtol(sub_str, NULL, 16);
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
return nb_bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
parse_sa_tokens(char **tokens, uint32_t n_tokens,
|
|
|
|
struct parse_status *status)
|
|
|
|
{
|
|
|
|
struct ipsec_sa *rule = NULL;
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2016-09-21 12:05:18 +00:00
|
|
|
uint32_t ti; /*token index*/
|
|
|
|
uint32_t *ri /*rule index*/;
|
|
|
|
uint32_t cipher_algo_p = 0;
|
|
|
|
uint32_t auth_algo_p = 0;
|
2017-07-02 05:41:24 +00:00
|
|
|
uint32_t aead_algo_p = 0;
|
2016-09-21 12:05:18 +00:00
|
|
|
uint32_t src_p = 0;
|
|
|
|
uint32_t dst_p = 0;
|
|
|
|
uint32_t mode_p = 0;
|
2017-10-25 15:07:27 +00:00
|
|
|
uint32_t type_p = 0;
|
|
|
|
uint32_t portid_p = 0;
|
2019-10-14 13:48:40 +00:00
|
|
|
uint32_t fallback_p = 0;
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
if (strcmp(tokens[0], "in") == 0) {
|
|
|
|
ri = &nb_sa_in;
|
|
|
|
|
|
|
|
APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
|
|
|
|
"too many sa rules, abort insertion\n");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rule = &sa_in[*ri];
|
2019-10-14 13:48:40 +00:00
|
|
|
rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
|
2016-09-21 12:05:18 +00:00
|
|
|
} else {
|
|
|
|
ri = &nb_sa_out;
|
|
|
|
|
|
|
|
APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
|
|
|
|
"too many sa rules, abort insertion\n");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rule = &sa_out[*ri];
|
2019-10-14 13:48:40 +00:00
|
|
|
rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
/* spi number */
|
|
|
|
APP_CHECK_TOKEN_IS_NUM(tokens, 1, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
2018-01-11 11:55:36 +00:00
|
|
|
if (atoi(tokens[1]) == INVALID_SPI)
|
|
|
|
return;
|
2016-09-21 12:05:18 +00:00
|
|
|
rule->spi = atoi(tokens[1]);
|
2019-10-14 13:48:40 +00:00
|
|
|
ips = ipsec_get_primary_session(rule);
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
for (ti = 2; ti < n_tokens; ti++) {
|
|
|
|
if (strcmp(tokens[ti], "mode") == 0) {
|
|
|
|
APP_CHECK_PRESENCE(mode_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "ipv4-tunnel") == 0)
|
|
|
|
rule->flags = IP4_TUNNEL;
|
|
|
|
else if (strcmp(tokens[ti], "ipv6-tunnel") == 0)
|
|
|
|
rule->flags = IP6_TUNNEL;
|
|
|
|
else if (strcmp(tokens[ti], "transport") == 0)
|
|
|
|
rule->flags = TRANSPORT;
|
|
|
|
else {
|
|
|
|
APP_CHECK(0, status, "unrecognized "
|
|
|
|
"input \"%s\"", tokens[ti]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mode_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "cipher_algo") == 0) {
|
|
|
|
const struct supported_cipher_algo *algo;
|
|
|
|
uint32_t key_len;
|
|
|
|
|
|
|
|
APP_CHECK_PRESENCE(cipher_algo_p, tokens[ti],
|
|
|
|
status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
algo = find_match_cipher_algo(tokens[ti]);
|
|
|
|
|
|
|
|
APP_CHECK(algo != NULL, status, "unrecognized "
|
|
|
|
"input \"%s\"", tokens[ti]);
|
|
|
|
|
|
|
|
rule->cipher_algo = algo->algo;
|
|
|
|
rule->block_size = algo->block_size;
|
|
|
|
rule->iv_len = algo->iv_len;
|
|
|
|
rule->cipher_key_len = algo->key_len;
|
|
|
|
|
2016-09-29 15:44:09 +00:00
|
|
|
/* for NULL algorithm, no cipher key required */
|
2016-09-21 12:05:18 +00:00
|
|
|
if (rule->cipher_algo == RTE_CRYPTO_CIPHER_NULL) {
|
|
|
|
cipher_algo_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
APP_CHECK(strcmp(tokens[ti], "cipher_key") == 0,
|
|
|
|
status, "unrecognized input \"%s\", "
|
|
|
|
"expect \"cipher_key\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
key_len = parse_key_string(tokens[ti],
|
|
|
|
rule->cipher_key);
|
|
|
|
APP_CHECK(key_len == rule->cipher_key_len, status,
|
|
|
|
"unrecognized input \"%s\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
2018-07-25 09:49:43 +00:00
|
|
|
if (algo->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
|
|
|
|
algo->algo == RTE_CRYPTO_CIPHER_3DES_CBC)
|
2016-09-29 15:44:13 +00:00
|
|
|
rule->salt = (uint32_t)rte_rand();
|
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
if (algo->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
|
2016-09-29 15:44:13 +00:00
|
|
|
key_len -= 4;
|
|
|
|
rule->cipher_key_len = key_len;
|
|
|
|
memcpy(&rule->salt,
|
|
|
|
&rule->cipher_key[key_len], 4);
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
cipher_algo_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "auth_algo") == 0) {
|
|
|
|
const struct supported_auth_algo *algo;
|
|
|
|
uint32_t key_len;
|
|
|
|
|
|
|
|
APP_CHECK_PRESENCE(auth_algo_p, tokens[ti],
|
|
|
|
status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
algo = find_match_auth_algo(tokens[ti]);
|
|
|
|
APP_CHECK(algo != NULL, status, "unrecognized "
|
|
|
|
"input \"%s\"", tokens[ti]);
|
|
|
|
|
|
|
|
rule->auth_algo = algo->algo;
|
|
|
|
rule->auth_key_len = algo->key_len;
|
|
|
|
rule->digest_len = algo->digest_len;
|
|
|
|
|
2016-09-29 15:44:09 +00:00
|
|
|
/* NULL algorithm and combined algos do not
|
|
|
|
* require auth key
|
|
|
|
*/
|
|
|
|
if (algo->key_not_req) {
|
2016-09-21 12:05:18 +00:00
|
|
|
auth_algo_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
APP_CHECK(strcmp(tokens[ti], "auth_key") == 0,
|
|
|
|
status, "unrecognized input \"%s\", "
|
|
|
|
"expect \"auth_key\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
key_len = parse_key_string(tokens[ti],
|
|
|
|
rule->auth_key);
|
|
|
|
APP_CHECK(key_len == rule->auth_key_len, status,
|
|
|
|
"unrecognized input \"%s\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auth_algo_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
if (strcmp(tokens[ti], "aead_algo") == 0) {
|
|
|
|
const struct supported_aead_algo *algo;
|
|
|
|
uint32_t key_len;
|
|
|
|
|
|
|
|
APP_CHECK_PRESENCE(aead_algo_p, tokens[ti],
|
|
|
|
status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
algo = find_match_aead_algo(tokens[ti]);
|
|
|
|
|
|
|
|
APP_CHECK(algo != NULL, status, "unrecognized "
|
|
|
|
"input \"%s\"", tokens[ti]);
|
|
|
|
|
|
|
|
rule->aead_algo = algo->algo;
|
|
|
|
rule->cipher_key_len = algo->key_len;
|
|
|
|
rule->digest_len = algo->digest_len;
|
2017-10-24 12:48:59 +00:00
|
|
|
rule->aad_len = algo->aad_len;
|
2017-07-02 05:41:24 +00:00
|
|
|
rule->block_size = algo->block_size;
|
|
|
|
rule->iv_len = algo->iv_len;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
APP_CHECK(strcmp(tokens[ti], "aead_key") == 0,
|
|
|
|
status, "unrecognized input \"%s\", "
|
|
|
|
"expect \"aead_key\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
key_len = parse_key_string(tokens[ti],
|
|
|
|
rule->cipher_key);
|
|
|
|
APP_CHECK(key_len == rule->cipher_key_len, status,
|
|
|
|
"unrecognized input \"%s\"", tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
key_len -= 4;
|
|
|
|
rule->cipher_key_len = key_len;
|
|
|
|
memcpy(&rule->salt,
|
|
|
|
&rule->cipher_key[key_len], 4);
|
|
|
|
|
|
|
|
aead_algo_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
if (strcmp(tokens[ti], "src") == 0) {
|
|
|
|
APP_CHECK_PRESENCE(src_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
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 (IS_IP4_TUNNEL(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
struct in_addr ip;
|
|
|
|
|
|
|
|
APP_CHECK(parse_ipv4_addr(tokens[ti],
|
|
|
|
&ip, NULL) == 0, status,
|
|
|
|
"unrecognized input \"%s\", "
|
|
|
|
"expect valid ipv4 addr",
|
|
|
|
tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
rule->src.ip.ip4 = rte_bswap32(
|
|
|
|
(uint32_t)ip.s_addr);
|
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(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
struct in6_addr ip;
|
|
|
|
|
|
|
|
APP_CHECK(parse_ipv6_addr(tokens[ti], &ip,
|
|
|
|
NULL) == 0, status,
|
|
|
|
"unrecognized input \"%s\", "
|
|
|
|
"expect valid ipv6 addr",
|
|
|
|
tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
memcpy(rule->src.ip.ip6.ip6_b,
|
|
|
|
ip.s6_addr, 16);
|
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(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
APP_CHECK(0, status, "unrecognized input "
|
|
|
|
"\"%s\"", tokens[ti]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "dst") == 0) {
|
|
|
|
APP_CHECK_PRESENCE(dst_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
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 (IS_IP4_TUNNEL(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
struct in_addr ip;
|
|
|
|
|
|
|
|
APP_CHECK(parse_ipv4_addr(tokens[ti],
|
|
|
|
&ip, NULL) == 0, status,
|
|
|
|
"unrecognized input \"%s\", "
|
|
|
|
"expect valid ipv4 addr",
|
|
|
|
tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
rule->dst.ip.ip4 = rte_bswap32(
|
|
|
|
(uint32_t)ip.s_addr);
|
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(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
struct in6_addr ip;
|
|
|
|
|
|
|
|
APP_CHECK(parse_ipv6_addr(tokens[ti], &ip,
|
|
|
|
NULL) == 0, status,
|
|
|
|
"unrecognized input \"%s\", "
|
|
|
|
"expect valid ipv6 addr",
|
|
|
|
tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
memcpy(rule->dst.ip.ip6.ip6_b, ip.s6_addr, 16);
|
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(rule->flags)) {
|
2016-09-21 12:05:18 +00:00
|
|
|
APP_CHECK(0, status, "unrecognized "
|
|
|
|
"input \"%s\"", tokens[ti]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dst_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
if (strcmp(tokens[ti], "type") == 0) {
|
|
|
|
APP_CHECK_PRESENCE(type_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "inline-crypto-offload") == 0)
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type =
|
2017-10-25 15:07:27 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO;
|
|
|
|
else if (strcmp(tokens[ti],
|
|
|
|
"inline-protocol-offload") == 0)
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type =
|
2017-10-25 15:07:27 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
|
|
|
|
else if (strcmp(tokens[ti],
|
|
|
|
"lookaside-protocol-offload") == 0)
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type =
|
2017-10-25 15:07:27 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
|
|
|
|
else if (strcmp(tokens[ti], "no-offload") == 0)
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
|
2017-10-25 15:07:27 +00:00
|
|
|
else {
|
|
|
|
APP_CHECK(0, status, "Invalid input \"%s\"",
|
|
|
|
tokens[ti]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
type_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(tokens[ti], "port_id") == 0) {
|
|
|
|
APP_CHECK_PRESENCE(portid_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
rule->portid = atoi(tokens[ti]);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
portid_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
if (strcmp(tokens[ti], "fallback") == 0) {
|
|
|
|
struct rte_ipsec_session *fb;
|
|
|
|
|
|
|
|
APP_CHECK(app_sa_prm.enable, status, "Fallback session "
|
|
|
|
"not allowed for legacy mode.");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
APP_CHECK(ips->type ==
|
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, status,
|
|
|
|
"Fallback session allowed if primary session "
|
|
|
|
"is of type inline-crypto-offload only.");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
APP_CHECK(rule->direction ==
|
|
|
|
RTE_SECURITY_IPSEC_SA_DIR_INGRESS, status,
|
|
|
|
"Fallback session not allowed for egress "
|
|
|
|
"rule");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
APP_CHECK_PRESENCE(fallback_p, tokens[ti], status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
fb = ipsec_get_fallback_session(rule);
|
|
|
|
if (strcmp(tokens[ti], "lookaside-none") == 0) {
|
|
|
|
fb->type = RTE_SECURITY_ACTION_TYPE_NONE;
|
|
|
|
} else {
|
|
|
|
APP_CHECK(0, status, "unrecognized fallback "
|
|
|
|
"type %s.", tokens[ti]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rule->fallback_sessions = 1;
|
|
|
|
fallback_p = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
/* unrecognizeable input */
|
|
|
|
APP_CHECK(0, status, "unrecognized input \"%s\"",
|
|
|
|
tokens[ti]);
|
|
|
|
return;
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
if (aead_algo_p) {
|
|
|
|
APP_CHECK(cipher_algo_p == 0, status,
|
|
|
|
"AEAD used, no need for cipher options");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
2016-09-21 12:05:18 +00:00
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
APP_CHECK(auth_algo_p == 0, status,
|
|
|
|
"AEAD used, no need for auth options");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
APP_CHECK(cipher_algo_p == 1, status, "missing cipher or AEAD options");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
APP_CHECK(auth_algo_p == 1, status, "missing auth or AEAD options");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
APP_CHECK(mode_p == 1, status, "missing mode option");
|
|
|
|
if (status->status < 0)
|
|
|
|
return;
|
|
|
|
|
2019-10-14 13:48:39 +00:00
|
|
|
if ((ips->type != RTE_SECURITY_ACTION_TYPE_NONE) && (portid_p == 0))
|
2017-10-25 15:07:27 +00:00
|
|
|
printf("Missing portid option, falling back to non-offload\n");
|
|
|
|
|
|
|
|
if (!type_p || !portid_p) {
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
|
2017-10-25 15:07:27 +00:00
|
|
|
rule->portid = -1;
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
*ri = *ri + 1;
|
|
|
|
}
|
|
|
|
|
2019-04-04 12:13:26 +00:00
|
|
|
static void
|
2016-09-21 12:05:18 +00:00
|
|
|
print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
|
|
|
|
{
|
|
|
|
uint32_t i;
|
|
|
|
uint8_t a, b, c, d;
|
2019-10-14 13:48:39 +00:00
|
|
|
const struct rte_ipsec_session *ips;
|
2019-10-14 13:48:40 +00:00
|
|
|
const struct rte_ipsec_session *fallback_ips;
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
printf("\tspi_%s(%3u):", inbound?"in":"out", sa->spi);
|
|
|
|
|
|
|
|
for (i = 0; i < RTE_DIM(cipher_algos); i++) {
|
2018-02-09 10:40:05 +00:00
|
|
|
if (cipher_algos[i].algo == sa->cipher_algo &&
|
|
|
|
cipher_algos[i].key_len == sa->cipher_key_len) {
|
2016-09-21 12:05:18 +00:00
|
|
|
printf("%s ", cipher_algos[i].keyword);
|
|
|
|
break;
|
|
|
|
}
|
2016-04-08 17:01:09 +00:00
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
|
|
|
|
for (i = 0; i < RTE_DIM(auth_algos); i++) {
|
|
|
|
if (auth_algos[i].algo == sa->auth_algo) {
|
|
|
|
printf("%s ", auth_algos[i].keyword);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-02 05:41:24 +00:00
|
|
|
for (i = 0; i < RTE_DIM(aead_algos); i++) {
|
|
|
|
if (aead_algos[i].algo == sa->aead_algo) {
|
|
|
|
printf("%s ", aead_algos[i].keyword);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
printf("mode:");
|
|
|
|
|
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-09-21 12:05:18 +00:00
|
|
|
case IP4_TUNNEL:
|
|
|
|
printf("IP4Tunnel ");
|
|
|
|
uint32_t_to_char(sa->src.ip.ip4, &a, &b, &c, &d);
|
|
|
|
printf("%hhu.%hhu.%hhu.%hhu ", d, c, b, a);
|
|
|
|
uint32_t_to_char(sa->dst.ip.ip4, &a, &b, &c, &d);
|
|
|
|
printf("%hhu.%hhu.%hhu.%hhu", d, c, b, a);
|
|
|
|
break;
|
|
|
|
case IP6_TUNNEL:
|
|
|
|
printf("IP6Tunnel ");
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
if (i % 2 && i != 15)
|
|
|
|
printf("%.2x:", sa->src.ip.ip6.ip6_b[i]);
|
|
|
|
else
|
|
|
|
printf("%.2x", sa->src.ip.ip6.ip6_b[i]);
|
|
|
|
}
|
|
|
|
printf(" ");
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
if (i % 2 && i != 15)
|
|
|
|
printf("%.2x:", sa->dst.ip.ip6.ip6_b[i]);
|
|
|
|
else
|
|
|
|
printf("%.2x", sa->dst.ip.ip6.ip6_b[i]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TRANSPORT:
|
2019-03-07 10:34:52 +00:00
|
|
|
printf("Transport ");
|
|
|
|
break;
|
|
|
|
}
|
2019-10-14 13:48:39 +00:00
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
ips = &sa->sessions[IPSEC_SESSION_PRIMARY];
|
2019-03-07 10:34:52 +00:00
|
|
|
printf(" type:");
|
2019-10-14 13:48:39 +00:00
|
|
|
switch (ips->type) {
|
2019-03-07 10:34:52 +00:00
|
|
|
case RTE_SECURITY_ACTION_TYPE_NONE:
|
|
|
|
printf("no-offload ");
|
|
|
|
break;
|
|
|
|
case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO:
|
|
|
|
printf("inline-crypto-offload ");
|
|
|
|
break;
|
|
|
|
case RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL:
|
|
|
|
printf("inline-protocol-offload ");
|
|
|
|
break;
|
|
|
|
case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
|
|
|
|
printf("lookaside-protocol-offload ");
|
2016-09-21 12:05:18 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-10-14 13:48:40 +00:00
|
|
|
|
|
|
|
fallback_ips = &sa->sessions[IPSEC_SESSION_FALLBACK];
|
|
|
|
if (fallback_ips != NULL && sa->fallback_sessions > 0) {
|
|
|
|
printf("inline fallback: ");
|
|
|
|
if (fallback_ips->type == RTE_SECURITY_ACTION_TYPE_NONE)
|
|
|
|
printf("lookaside-none");
|
|
|
|
else
|
|
|
|
printf("invalid");
|
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
printf("\n");
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
struct sa_ctx {
|
2019-01-10 21:09:10 +00:00
|
|
|
void *satbl; /* pointer to array of rte_ipsec_sa objects*/
|
2016-03-11 02:12:40 +00:00
|
|
|
struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES];
|
2017-10-25 15:07:27 +00:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
struct rte_crypto_sym_xform a;
|
|
|
|
struct rte_crypto_sym_xform b;
|
|
|
|
};
|
2016-03-11 02:12:40 +00:00
|
|
|
} xf[IPSEC_SA_MAX_ENTRIES];
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct sa_ctx *
|
2016-06-09 08:42:48 +00:00
|
|
|
sa_create(const char *name, int32_t socket_id)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
|
|
|
char s[PATH_MAX];
|
|
|
|
struct sa_ctx *sa_ctx;
|
2016-06-09 08:42:48 +00:00
|
|
|
uint32_t mz_size;
|
2016-03-11 02:12:40 +00:00
|
|
|
const struct rte_memzone *mz;
|
|
|
|
|
|
|
|
snprintf(s, sizeof(s), "%s_%u", name, socket_id);
|
|
|
|
|
|
|
|
/* Create SA array table */
|
2019-03-07 10:34:52 +00:00
|
|
|
printf("Creating SA context with %u maximum entries on socket %d\n",
|
|
|
|
IPSEC_SA_MAX_ENTRIES, socket_id);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
mz_size = sizeof(struct sa_ctx);
|
|
|
|
mz = rte_memzone_reserve(s, mz_size, socket_id,
|
|
|
|
RTE_MEMZONE_1GB | RTE_MEMZONE_SIZE_HINT_ONLY);
|
|
|
|
if (mz == NULL) {
|
|
|
|
printf("Failed to allocate SA DB memory\n");
|
2019-07-05 12:18:09 +00:00
|
|
|
rte_errno = ENOMEM;
|
2016-03-11 02:12:40 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sa_ctx = (struct sa_ctx *)mz->addr;
|
|
|
|
|
|
|
|
return sa_ctx;
|
|
|
|
}
|
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
static int
|
|
|
|
check_eth_dev_caps(uint16_t portid, uint32_t inbound)
|
|
|
|
{
|
|
|
|
struct rte_eth_dev_info dev_info;
|
2019-09-12 16:42:58 +00:00
|
|
|
int retval;
|
2017-10-25 15:07:27 +00:00
|
|
|
|
2019-09-12 16:42:58 +00:00
|
|
|
retval = rte_eth_dev_info_get(portid, &dev_info);
|
|
|
|
if (retval != 0) {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"Error during getting device (port %u) info: %s\n",
|
|
|
|
portid, strerror(-retval));
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2017-10-25 15:07:27 +00:00
|
|
|
|
|
|
|
if (inbound) {
|
|
|
|
if ((dev_info.rx_offload_capa &
|
|
|
|
DEV_RX_OFFLOAD_SECURITY) == 0) {
|
|
|
|
RTE_LOG(WARNING, PORT,
|
|
|
|
"hardware RX IPSec offload is not supported\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else { /* outbound */
|
|
|
|
if ((dev_info.tx_offload_capa &
|
|
|
|
DEV_TX_OFFLOAD_SECURITY) == 0) {
|
|
|
|
RTE_LOG(WARNING, PORT,
|
|
|
|
"hardware TX IPSec offload is not supported\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/*
|
|
|
|
* Helper function, tries to determine next_proto for SPI
|
|
|
|
* by searching though SP rules.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
get_spi_proto(uint32_t spi, enum rte_security_ipsec_sa_direction dir,
|
|
|
|
struct ip_addr ip_addr[2], uint32_t mask[2])
|
|
|
|
{
|
|
|
|
int32_t rc4, rc6;
|
|
|
|
|
|
|
|
rc4 = sp4_spi_present(spi, dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
|
|
|
|
ip_addr, mask);
|
|
|
|
rc6 = sp6_spi_present(spi, dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
|
|
|
|
ip_addr, mask);
|
|
|
|
|
|
|
|
if (rc4 >= 0) {
|
|
|
|
if (rc6 >= 0) {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"%s: SPI %u used simultaeously by "
|
|
|
|
"IPv4(%d) and IPv6 (%d) SP rules\n",
|
|
|
|
__func__, spi, rc4, rc6);
|
|
|
|
return -EINVAL;
|
|
|
|
} else
|
|
|
|
return IPPROTO_IPIP;
|
|
|
|
} else if (rc6 < 0) {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"%s: SPI %u is not used by any SP rule\n",
|
|
|
|
__func__, spi);
|
|
|
|
return -EINVAL;
|
|
|
|
} else
|
|
|
|
return IPPROTO_IPV6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper function for getting source and destination IP addresses
|
|
|
|
* from SP. Needed for inline crypto transport mode, as addresses are not
|
|
|
|
* provided in config file for that mode. It checks if SP for current SA exists,
|
|
|
|
* and based on what type of protocol is returned, it stores appropriate
|
|
|
|
* addresses got from SP into SA.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
sa_add_address_inline_crypto(struct ipsec_sa *sa)
|
|
|
|
{
|
|
|
|
int protocol;
|
|
|
|
struct ip_addr ip_addr[2];
|
|
|
|
uint32_t mask[2];
|
|
|
|
|
|
|
|
protocol = get_spi_proto(sa->spi, sa->direction, ip_addr, mask);
|
|
|
|
if (protocol < 0)
|
|
|
|
return protocol;
|
|
|
|
else if (protocol == IPPROTO_IPIP) {
|
|
|
|
sa->flags |= IP4_TRANSPORT;
|
|
|
|
if (mask[0] == IP4_FULL_MASK &&
|
|
|
|
mask[1] == IP4_FULL_MASK &&
|
|
|
|
ip_addr[0].ip.ip4 != 0 &&
|
|
|
|
ip_addr[1].ip.ip4 != 0) {
|
|
|
|
|
|
|
|
sa->src.ip.ip4 = ip_addr[0].ip.ip4;
|
|
|
|
sa->dst.ip.ip4 = ip_addr[1].ip.ip4;
|
|
|
|
} else {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"%s: No valid address or mask entry in"
|
|
|
|
" IPv4 SP rule for SPI %u\n",
|
|
|
|
__func__, sa->spi);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
} else if (protocol == IPPROTO_IPV6) {
|
|
|
|
sa->flags |= IP6_TRANSPORT;
|
|
|
|
if (mask[0] == IP6_FULL_MASK &&
|
|
|
|
mask[1] == IP6_FULL_MASK &&
|
|
|
|
(ip_addr[0].ip.ip6.ip6[0] != 0 ||
|
|
|
|
ip_addr[0].ip.ip6.ip6[1] != 0) &&
|
|
|
|
(ip_addr[1].ip.ip6.ip6[0] != 0 ||
|
|
|
|
ip_addr[1].ip.ip6.ip6[1] != 0)) {
|
|
|
|
|
|
|
|
sa->src.ip.ip6 = ip_addr[0].ip.ip6;
|
|
|
|
sa->dst.ip.ip6 = ip_addr[1].ip.ip6;
|
|
|
|
} else {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"%s: No valid address or mask entry in"
|
|
|
|
" IPv6 SP rule for SPI %u\n",
|
|
|
|
__func__, sa->spi);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2017-10-25 15:07:27 +00:00
|
|
|
|
2016-03-11 02:12:40 +00:00
|
|
|
static int
|
|
|
|
sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
|
2019-07-19 12:22:32 +00:00
|
|
|
uint32_t nb_entries, uint32_t inbound,
|
|
|
|
struct socket_ctx *skt_ctx)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
|
|
|
struct ipsec_sa *sa;
|
2016-06-09 08:42:48 +00:00
|
|
|
uint32_t i, idx;
|
2019-01-10 21:09:10 +00:00
|
|
|
uint16_t iv_length, aad_length;
|
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
|
|
|
int inline_status;
|
2019-07-19 12:22:32 +00:00
|
|
|
int32_t rc;
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2019-01-10 21:09:10 +00:00
|
|
|
|
|
|
|
/* for ESN upper 32 bits of SQN also need to be part of AAD */
|
|
|
|
aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nb_entries; i++) {
|
|
|
|
idx = SPI2IDX(entries[i].spi);
|
|
|
|
sa = &sa_ctx->sa[idx];
|
|
|
|
if (sa->spi != 0) {
|
|
|
|
printf("Index %u already in use by SPI %u\n",
|
|
|
|
idx, sa->spi);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
*sa = entries[i];
|
2016-06-09 08:42:48 +00:00
|
|
|
sa->seq = 0;
|
2019-10-14 13:48:40 +00:00
|
|
|
ips = ipsec_get_primary_session(sa);
|
2016-06-09 08:42:48 +00:00
|
|
|
|
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 (check_eth_dev_caps(sa->portid, inbound))
|
|
|
|
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
|
|
|
switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
|
2016-06-09 08:42:48 +00:00
|
|
|
case IP4_TUNNEL:
|
2016-07-19 11:06:00 +00:00
|
|
|
sa->src.ip.ip4 = rte_cpu_to_be_32(sa->src.ip.ip4);
|
|
|
|
sa->dst.ip.ip4 = rte_cpu_to_be_32(sa->dst.ip.ip4);
|
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
|
|
|
break;
|
|
|
|
case TRANSPORT:
|
2019-10-14 13:48:39 +00:00
|
|
|
if (ips->type ==
|
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_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
|
|
|
|
inline_status =
|
|
|
|
sa_add_address_inline_crypto(sa);
|
|
|
|
if (inline_status < 0)
|
|
|
|
return inline_status;
|
|
|
|
}
|
|
|
|
break;
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2019-10-31 14:04:45 +00:00
|
|
|
iv_length = 12;
|
2017-07-02 05:41:14 +00:00
|
|
|
|
2017-10-25 15:07:27 +00:00
|
|
|
sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
|
|
|
|
sa_ctx->xf[idx].a.aead.algo = sa->aead_algo;
|
|
|
|
sa_ctx->xf[idx].a.aead.key.data = sa->cipher_key;
|
|
|
|
sa_ctx->xf[idx].a.aead.key.length =
|
|
|
|
sa->cipher_key_len;
|
|
|
|
sa_ctx->xf[idx].a.aead.op = (inbound == 1) ?
|
|
|
|
RTE_CRYPTO_AEAD_OP_DECRYPT :
|
|
|
|
RTE_CRYPTO_AEAD_OP_ENCRYPT;
|
|
|
|
sa_ctx->xf[idx].a.next = NULL;
|
|
|
|
sa_ctx->xf[idx].a.aead.iv.offset = IV_OFFSET;
|
|
|
|
sa_ctx->xf[idx].a.aead.iv.length = iv_length;
|
|
|
|
sa_ctx->xf[idx].a.aead.aad_length =
|
2019-01-10 21:09:10 +00:00
|
|
|
sa->aad_len + aad_length;
|
2017-10-25 15:07:27 +00:00
|
|
|
sa_ctx->xf[idx].a.aead.digest_length =
|
|
|
|
sa->digest_len;
|
2016-09-21 12:05:18 +00:00
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
sa->xforms = &sa_ctx->xf[idx].a;
|
2016-09-21 12:05:18 +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 ==
|
2019-07-19 12:22:32 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
|
2019-10-14 13:48:39 +00:00
|
|
|
ips->type ==
|
2019-07-19 12:22:32 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
|
2019-10-14 13:48:39 +00:00
|
|
|
rc = create_inline_session(skt_ctx, sa, ips);
|
2019-07-19 12:22:32 +00:00
|
|
|
if (rc != 0) {
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP,
|
|
|
|
"create_inline_session() failed\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 05:41:26 +00:00
|
|
|
print_one_sa_rule(sa, inbound);
|
|
|
|
} 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:
|
|
|
|
iv_length = sa->iv_len;
|
|
|
|
break;
|
|
|
|
case RTE_CRYPTO_CIPHER_AES_CTR:
|
|
|
|
iv_length = 16;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTE_LOG(ERR, IPSEC_ESP,
|
|
|
|
"unsupported cipher algorithm %u\n",
|
|
|
|
sa->cipher_algo);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inbound) {
|
|
|
|
sa_ctx->xf[idx].b.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
|
|
|
|
sa_ctx->xf[idx].b.cipher.algo = sa->cipher_algo;
|
|
|
|
sa_ctx->xf[idx].b.cipher.key.data = sa->cipher_key;
|
|
|
|
sa_ctx->xf[idx].b.cipher.key.length =
|
|
|
|
sa->cipher_key_len;
|
|
|
|
sa_ctx->xf[idx].b.cipher.op =
|
|
|
|
RTE_CRYPTO_CIPHER_OP_DECRYPT;
|
|
|
|
sa_ctx->xf[idx].b.next = NULL;
|
|
|
|
sa_ctx->xf[idx].b.cipher.iv.offset = IV_OFFSET;
|
|
|
|
sa_ctx->xf[idx].b.cipher.iv.length = iv_length;
|
|
|
|
|
|
|
|
sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AUTH;
|
|
|
|
sa_ctx->xf[idx].a.auth.algo = sa->auth_algo;
|
|
|
|
sa_ctx->xf[idx].a.auth.key.data = sa->auth_key;
|
|
|
|
sa_ctx->xf[idx].a.auth.key.length =
|
|
|
|
sa->auth_key_len;
|
|
|
|
sa_ctx->xf[idx].a.auth.digest_length =
|
|
|
|
sa->digest_len;
|
|
|
|
sa_ctx->xf[idx].a.auth.op =
|
|
|
|
RTE_CRYPTO_AUTH_OP_VERIFY;
|
|
|
|
} else { /* outbound */
|
|
|
|
sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
|
|
|
|
sa_ctx->xf[idx].a.cipher.algo = sa->cipher_algo;
|
|
|
|
sa_ctx->xf[idx].a.cipher.key.data = sa->cipher_key;
|
|
|
|
sa_ctx->xf[idx].a.cipher.key.length =
|
|
|
|
sa->cipher_key_len;
|
|
|
|
sa_ctx->xf[idx].a.cipher.op =
|
|
|
|
RTE_CRYPTO_CIPHER_OP_ENCRYPT;
|
|
|
|
sa_ctx->xf[idx].a.next = NULL;
|
|
|
|
sa_ctx->xf[idx].a.cipher.iv.offset = IV_OFFSET;
|
|
|
|
sa_ctx->xf[idx].a.cipher.iv.length = iv_length;
|
|
|
|
|
|
|
|
sa_ctx->xf[idx].b.type = RTE_CRYPTO_SYM_XFORM_AUTH;
|
|
|
|
sa_ctx->xf[idx].b.auth.algo = sa->auth_algo;
|
|
|
|
sa_ctx->xf[idx].b.auth.key.data = sa->auth_key;
|
|
|
|
sa_ctx->xf[idx].b.auth.key.length =
|
|
|
|
sa->auth_key_len;
|
|
|
|
sa_ctx->xf[idx].b.auth.digest_length =
|
|
|
|
sa->digest_len;
|
|
|
|
sa_ctx->xf[idx].b.auth.op =
|
|
|
|
RTE_CRYPTO_AUTH_OP_GENERATE;
|
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
|
2017-07-02 05:41:26 +00:00
|
|
|
sa_ctx->xf[idx].a.next = &sa_ctx->xf[idx].b;
|
|
|
|
sa_ctx->xf[idx].b.next = NULL;
|
|
|
|
sa->xforms = &sa_ctx->xf[idx].a;
|
|
|
|
|
|
|
|
print_one_sa_rule(sa, inbound);
|
|
|
|
}
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
sa_out_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
|
2019-07-19 12:22:32 +00:00
|
|
|
uint32_t nb_entries, struct socket_ctx *skt_ctx)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2019-07-19 12:22:32 +00:00
|
|
|
return sa_add_rules(sa_ctx, entries, nb_entries, 0, skt_ctx);
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
sa_in_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
|
2019-07-19 12:22:32 +00:00
|
|
|
uint32_t nb_entries, struct socket_ctx *skt_ctx)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2019-07-19 12:22:32 +00:00
|
|
|
return sa_add_rules(sa_ctx, entries, nb_entries, 1, skt_ctx);
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
2019-01-10 21:09:10 +00:00
|
|
|
/*
|
|
|
|
* helper function, fills parameters that are identical for all SAs
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
fill_ipsec_app_sa_prm(struct rte_ipsec_sa_prm *prm,
|
|
|
|
const struct app_sa_prm *app_prm)
|
|
|
|
{
|
|
|
|
memset(prm, 0, sizeof(*prm));
|
|
|
|
|
|
|
|
prm->flags = app_prm->flags;
|
|
|
|
prm->ipsec_xform.options.esn = app_prm->enable_esn;
|
2019-11-06 06:54:13 +00:00
|
|
|
prm->ipsec_xform.replay_win_sz = app_prm->window_size;
|
2019-01-10 21:09:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
fill_ipsec_sa_prm(struct rte_ipsec_sa_prm *prm, const struct ipsec_sa *ss,
|
2019-05-21 16:13:10 +00:00
|
|
|
const struct rte_ipv4_hdr *v4, struct rte_ipv6_hdr *v6)
|
2019-01-10 21:09:10 +00:00
|
|
|
{
|
|
|
|
int32_t rc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to get SPI next proto by searching that SPI in SPD.
|
|
|
|
* probably not the optimal way, but there seems nothing
|
|
|
|
* better right now.
|
|
|
|
*/
|
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
|
|
|
rc = get_spi_proto(ss->spi, ss->direction, NULL, NULL);
|
2019-01-10 21:09:10 +00:00
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
fill_ipsec_app_sa_prm(prm, &app_sa_prm);
|
|
|
|
prm->userdata = (uintptr_t)ss;
|
|
|
|
|
|
|
|
/* setup ipsec xform */
|
|
|
|
prm->ipsec_xform.spi = ss->spi;
|
|
|
|
prm->ipsec_xform.salt = ss->salt;
|
|
|
|
prm->ipsec_xform.direction = ss->direction;
|
|
|
|
prm->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
|
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
|
|
|
prm->ipsec_xform.mode = (IS_TRANSPORT(ss->flags)) ?
|
2019-01-10 21:09:10 +00:00
|
|
|
RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT :
|
|
|
|
RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
|
2019-07-04 10:42:36 +00:00
|
|
|
prm->ipsec_xform.options.ecn = 1;
|
|
|
|
prm->ipsec_xform.options.copy_dscp = 1;
|
2019-01-10 21:09:10 +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 (IS_IP4_TUNNEL(ss->flags)) {
|
2019-01-10 21:09:10 +00:00
|
|
|
prm->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
|
|
|
|
prm->tun.hdr_len = sizeof(*v4);
|
|
|
|
prm->tun.next_proto = rc;
|
|
|
|
prm->tun.hdr = v4;
|
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(ss->flags)) {
|
2019-01-10 21:09:10 +00:00
|
|
|
prm->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV6;
|
|
|
|
prm->tun.hdr_len = sizeof(*v6);
|
|
|
|
prm->tun.next_proto = rc;
|
|
|
|
prm->tun.hdr = v6;
|
|
|
|
} else {
|
|
|
|
/* transport mode */
|
|
|
|
prm->trs.proto = rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup crypto section */
|
|
|
|
prm->crypto_xform = ss->xforms;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-07-19 12:22:32 +00:00
|
|
|
static int
|
2019-10-14 13:48:39 +00:00
|
|
|
fill_ipsec_session(struct rte_ipsec_session *ss, struct rte_ipsec_sa *sa)
|
2019-01-10 21:09:10 +00:00
|
|
|
{
|
2019-07-19 12:22:32 +00:00
|
|
|
int32_t rc = 0;
|
|
|
|
|
2019-01-10 21:09:10 +00:00
|
|
|
ss->sa = sa;
|
2019-07-19 12:22:32 +00:00
|
|
|
|
|
|
|
if (ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
|
|
|
|
ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
|
|
|
|
if (ss->security.ses != NULL) {
|
|
|
|
rc = rte_ipsec_session_prepare(ss);
|
|
|
|
if (rc != 0)
|
|
|
|
memset(ss, 0, sizeof(*ss));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
2019-01-10 21:09:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialise related rte_ipsec_sa object.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct rte_ipsec_sa_prm prm;
|
2019-10-14 13:48:39 +00:00
|
|
|
struct rte_ipsec_session *ips;
|
2019-05-21 16:13:10 +00:00
|
|
|
struct rte_ipv4_hdr v4 = {
|
2019-01-10 21:09:10 +00:00
|
|
|
.version_ihl = IPVERSION << 4 |
|
2019-05-21 16:13:11 +00:00
|
|
|
sizeof(v4) / RTE_IPV4_IHL_MULTIPLIER,
|
2019-01-10 21:09:10 +00:00
|
|
|
.time_to_live = IPDEFTTL,
|
|
|
|
.next_proto_id = IPPROTO_ESP,
|
|
|
|
.src_addr = lsa->src.ip.ip4,
|
|
|
|
.dst_addr = lsa->dst.ip.ip4,
|
|
|
|
};
|
2019-05-21 16:13:10 +00:00
|
|
|
struct rte_ipv6_hdr v6 = {
|
2019-01-10 21:09:10 +00:00
|
|
|
.vtc_flow = htonl(IP6_VERSION << 28),
|
|
|
|
.proto = IPPROTO_ESP,
|
|
|
|
};
|
|
|
|
|
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 (IS_IP6_TUNNEL(lsa->flags)) {
|
2019-01-10 21:09:10 +00:00
|
|
|
memcpy(v6.src_addr, lsa->src.ip.ip6.ip6_b, sizeof(v6.src_addr));
|
|
|
|
memcpy(v6.dst_addr, lsa->dst.ip.ip6.ip6_b, sizeof(v6.dst_addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = fill_ipsec_sa_prm(&prm, lsa, &v4, &v6);
|
|
|
|
if (rc == 0)
|
|
|
|
rc = rte_ipsec_sa_init(sa, &prm, sa_size);
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
/* init primary processing session */
|
|
|
|
ips = ipsec_get_primary_session(lsa);
|
2019-10-14 13:48:39 +00:00
|
|
|
rc = fill_ipsec_session(ips, sa);
|
2019-10-14 13:48:40 +00:00
|
|
|
if (rc != 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
/* init inline fallback processing session */
|
|
|
|
if (lsa->fallback_sessions == 1)
|
|
|
|
rc = fill_ipsec_session(ipsec_get_fallback_session(lsa), sa);
|
2019-10-14 13:48:39 +00:00
|
|
|
|
2019-07-19 12:22:32 +00:00
|
|
|
return rc;
|
2019-01-10 21:09:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate space and init rte_ipsec_sa strcutures,
|
|
|
|
* one per session.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent,
|
|
|
|
uint32_t nb_ent, int32_t socket)
|
|
|
|
{
|
|
|
|
int32_t rc, sz;
|
|
|
|
uint32_t i, idx;
|
|
|
|
size_t tsz;
|
|
|
|
struct rte_ipsec_sa *sa;
|
|
|
|
struct ipsec_sa *lsa;
|
|
|
|
struct rte_ipsec_sa_prm prm;
|
|
|
|
|
|
|
|
/* determine SA size */
|
|
|
|
idx = SPI2IDX(ent[0].spi);
|
|
|
|
fill_ipsec_sa_prm(&prm, ctx->sa + idx, NULL, NULL);
|
|
|
|
sz = rte_ipsec_sa_size(&prm);
|
|
|
|
if (sz < 0) {
|
|
|
|
RTE_LOG(ERR, IPSEC, "%s(%p, %u, %d): "
|
|
|
|
"failed to determine SA size, error code: %d\n",
|
|
|
|
__func__, ctx, nb_ent, socket, sz);
|
|
|
|
return sz;
|
|
|
|
}
|
|
|
|
|
|
|
|
tsz = sz * nb_ent;
|
|
|
|
|
|
|
|
ctx->satbl = rte_zmalloc_socket(NULL, tsz, RTE_CACHE_LINE_SIZE, socket);
|
|
|
|
if (ctx->satbl == NULL) {
|
|
|
|
RTE_LOG(ERR, IPSEC,
|
|
|
|
"%s(%p, %u, %d): failed to allocate %zu bytes\n",
|
|
|
|
__func__, ctx, nb_ent, socket, tsz);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
for (i = 0; i != nb_ent && rc == 0; i++) {
|
|
|
|
|
|
|
|
idx = SPI2IDX(ent[i].spi);
|
|
|
|
|
|
|
|
sa = (struct rte_ipsec_sa *)((uintptr_t)ctx->satbl + sz * i);
|
|
|
|
lsa = ctx->sa + idx;
|
|
|
|
|
|
|
|
rc = ipsec_sa_init(lsa, sa, sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2019-04-04 12:13:26 +00:00
|
|
|
/*
|
|
|
|
* Walk through all SA rules to find an SA with given SPI
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
sa_spi_present(uint32_t spi, int inbound)
|
|
|
|
{
|
|
|
|
uint32_t i, num;
|
|
|
|
const struct ipsec_sa *sar;
|
|
|
|
|
|
|
|
if (inbound != 0) {
|
|
|
|
sar = sa_in;
|
|
|
|
num = nb_sa_in;
|
|
|
|
} else {
|
|
|
|
sar = sa_out;
|
|
|
|
num = nb_sa_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i != num; i++) {
|
|
|
|
if (sar[i].spi == spi)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
2016-03-11 02:12:40 +00:00
|
|
|
void
|
2016-09-21 12:05:18 +00:00
|
|
|
sa_init(struct socket_ctx *ctx, int32_t socket_id)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2019-01-10 21:09:10 +00:00
|
|
|
int32_t rc;
|
2016-03-11 02:12:40 +00:00
|
|
|
const char *name;
|
|
|
|
|
|
|
|
if (ctx == NULL)
|
|
|
|
rte_exit(EXIT_FAILURE, "NULL context.\n");
|
|
|
|
|
2016-06-09 08:42:48 +00:00
|
|
|
if (ctx->sa_in != NULL)
|
2016-03-11 02:12:40 +00:00
|
|
|
rte_exit(EXIT_FAILURE, "Inbound SA DB for socket %u already "
|
|
|
|
"initialized\n", socket_id);
|
|
|
|
|
2016-06-09 08:42:48 +00:00
|
|
|
if (ctx->sa_out != NULL)
|
2016-03-11 02:12:40 +00:00
|
|
|
rte_exit(EXIT_FAILURE, "Outbound SA DB for socket %u already "
|
|
|
|
"initialized\n", socket_id);
|
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
if (nb_sa_in > 0) {
|
|
|
|
name = "sa_in";
|
|
|
|
ctx->sa_in = sa_create(name, socket_id);
|
|
|
|
if (ctx->sa_in == NULL)
|
|
|
|
rte_exit(EXIT_FAILURE, "Error [%d] creating SA "
|
|
|
|
"context %s in socket %d\n", rte_errno,
|
|
|
|
name, socket_id);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-07-19 12:22:32 +00:00
|
|
|
sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx);
|
2019-01-10 21:09:10 +00:00
|
|
|
|
|
|
|
if (app_sa_prm.enable != 0) {
|
|
|
|
rc = ipsec_satbl_init(ctx->sa_in, sa_in, nb_sa_in,
|
|
|
|
socket_id);
|
|
|
|
if (rc != 0)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"failed to init inbound SAs\n");
|
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
} else
|
|
|
|
RTE_LOG(WARNING, IPSEC, "No SA Inbound rule specified\n");
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-09-21 12:05:18 +00:00
|
|
|
if (nb_sa_out > 0) {
|
|
|
|
name = "sa_out";
|
|
|
|
ctx->sa_out = sa_create(name, socket_id);
|
|
|
|
if (ctx->sa_out == NULL)
|
|
|
|
rte_exit(EXIT_FAILURE, "Error [%d] creating SA "
|
|
|
|
"context %s in socket %d\n", rte_errno,
|
|
|
|
name, socket_id);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-07-19 12:22:32 +00:00
|
|
|
sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx);
|
2019-01-10 21:09:10 +00:00
|
|
|
|
|
|
|
if (app_sa_prm.enable != 0) {
|
|
|
|
rc = ipsec_satbl_init(ctx->sa_out, sa_out, nb_sa_out,
|
|
|
|
socket_id);
|
|
|
|
if (rc != 0)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"failed to init outbound SAs\n");
|
|
|
|
}
|
2016-09-21 12:05:18 +00:00
|
|
|
} else
|
|
|
|
RTE_LOG(WARNING, IPSEC, "No SA Outbound rule "
|
|
|
|
"specified\n");
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)
|
|
|
|
{
|
|
|
|
struct ipsec_mbuf_metadata *priv;
|
2019-01-10 21:09:09 +00:00
|
|
|
struct ipsec_sa *sa;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2018-06-18 23:36:18 +00:00
|
|
|
priv = get_priv(m);
|
2019-01-10 21:09:09 +00:00
|
|
|
sa = priv->sa;
|
|
|
|
if (sa != NULL)
|
|
|
|
return (sa_ctx->sa[sa_idx].spi == sa->spi);
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2019-01-10 21:09:09 +00:00
|
|
|
RTE_LOG(ERR, IPSEC, "SA not saved in private data\n");
|
|
|
|
return 0;
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
2016-06-09 08:42:48 +00:00
|
|
|
static inline void
|
|
|
|
single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
|
2019-10-14 13:48:40 +00:00
|
|
|
void **sa_ret)
|
2016-06-09 08:42:48 +00:00
|
|
|
{
|
2019-05-21 16:13:06 +00:00
|
|
|
struct rte_esp_hdr *esp;
|
2016-06-09 08:42:48 +00:00
|
|
|
struct ip *ip;
|
|
|
|
uint32_t *src4_addr;
|
|
|
|
uint8_t *src6_addr;
|
|
|
|
struct ipsec_sa *sa;
|
2019-10-14 13:48:40 +00:00
|
|
|
void *result_sa;
|
2016-06-09 08:42:48 +00:00
|
|
|
|
|
|
|
*sa_ret = NULL;
|
|
|
|
|
|
|
|
ip = rte_pktmbuf_mtod(pkt, struct ip *);
|
2019-06-24 13:39:59 +00:00
|
|
|
esp = rte_pktmbuf_mtod_offset(pkt, struct rte_esp_hdr *, pkt->l3_len);
|
2016-06-09 08:42:48 +00:00
|
|
|
|
|
|
|
if (esp->spi == INVALID_SPI)
|
|
|
|
return;
|
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
result_sa = sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
|
2016-06-09 08:42:48 +00:00
|
|
|
if (rte_be_to_cpu_32(esp->spi) != sa->spi)
|
|
|
|
return;
|
|
|
|
|
2019-10-14 13:48:40 +00:00
|
|
|
/*
|
|
|
|
* Mark need for inline offload fallback on the LSB of SA pointer.
|
|
|
|
* Thanks to packet grouping mechanism which ipsec_process is using
|
|
|
|
* packets marked for fallback processing will form separate group.
|
|
|
|
*
|
|
|
|
* Because it is not safe to use SA pointer it is casted to generic
|
|
|
|
* pointer to prevent from unintentional use. Use ipsec_mask_saptr
|
|
|
|
* to get valid struct pointer.
|
|
|
|
*/
|
|
|
|
if (MBUF_NO_SEC_OFFLOAD(pkt) && sa->fallback_sessions > 0) {
|
|
|
|
uintptr_t intsa = (uintptr_t)sa;
|
|
|
|
intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
|
|
|
|
result_sa = (void *)intsa;
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src));
|
|
|
|
if ((ip->ip_v == IPVERSION) &&
|
2016-07-19 11:06:00 +00:00
|
|
|
(sa->src.ip.ip4 == *src4_addr) &&
|
|
|
|
(sa->dst.ip.ip4 == *(src4_addr + 1)))
|
2019-10-14 13:48:40 +00:00
|
|
|
*sa_ret = result_sa;
|
2016-06-09 08:42:48 +00:00
|
|
|
break;
|
|
|
|
case IP6_TUNNEL:
|
|
|
|
src6_addr = RTE_PTR_ADD(ip, offsetof(struct ip6_hdr, ip6_src));
|
|
|
|
if ((ip->ip_v == IP6_VERSION) &&
|
2016-07-19 11:06:00 +00:00
|
|
|
!memcmp(&sa->src.ip.ip6.ip6, src6_addr, 16) &&
|
|
|
|
!memcmp(&sa->dst.ip.ip6.ip6, src6_addr + 16, 16))
|
2019-10-14 13:48:40 +00:00
|
|
|
*sa_ret = result_sa;
|
2016-06-09 08:42:49 +00:00
|
|
|
break;
|
|
|
|
case TRANSPORT:
|
2019-10-14 13:48:40 +00:00
|
|
|
*sa_ret = result_sa;
|
2016-06-09 08:42:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-11 02:12:40 +00:00
|
|
|
void
|
|
|
|
inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
|
2019-10-14 13:48:40 +00:00
|
|
|
void *sa[], uint16_t nb_pkts)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2016-06-09 08:42:48 +00:00
|
|
|
uint32_t i;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
2016-06-09 08:42:48 +00:00
|
|
|
for (i = 0; i < nb_pkts; i++)
|
|
|
|
single_inbound_lookup(sa_ctx->sa, pkts[i], &sa[i]);
|
2016-03-11 02:12:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
|
2019-10-14 13:48:40 +00:00
|
|
|
void *sa[], uint16_t nb_pkts)
|
2016-03-11 02:12:40 +00:00
|
|
|
{
|
2016-06-09 08:42:48 +00:00
|
|
|
uint32_t i;
|
2016-03-11 02:12:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nb_pkts; i++)
|
|
|
|
sa[i] = &sa_ctx->sa[sa_idx[i]];
|
|
|
|
}
|
2019-01-10 21:09:04 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Select HW offloads to be used.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
|
|
|
|
uint64_t *tx_offloads)
|
|
|
|
{
|
|
|
|
struct ipsec_sa *rule;
|
|
|
|
uint32_t idx_sa;
|
2019-10-14 13:48:39 +00:00
|
|
|
enum rte_security_session_action_type rule_type;
|
2019-01-10 21:09:04 +00:00
|
|
|
|
|
|
|
*rx_offloads = 0;
|
|
|
|
*tx_offloads = 0;
|
|
|
|
|
|
|
|
/* Check for inbound rules that use offloads and use this port */
|
|
|
|
for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) {
|
|
|
|
rule = &sa_in[idx_sa];
|
2019-10-14 13:48:39 +00:00
|
|
|
rule_type = ipsec_get_action_type(rule);
|
|
|
|
if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
|
|
|
|
rule_type ==
|
2019-01-10 21:09:04 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
|
|
|
|
&& rule->portid == port_id)
|
|
|
|
*rx_offloads |= DEV_RX_OFFLOAD_SECURITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for outbound rules that use offloads and use this port */
|
|
|
|
for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) {
|
|
|
|
rule = &sa_out[idx_sa];
|
2019-10-14 13:48:39 +00:00
|
|
|
rule_type = ipsec_get_action_type(rule);
|
|
|
|
if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
|
|
|
|
rule_type ==
|
2019-01-10 21:09:04 +00:00
|
|
|
RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
|
|
|
|
&& rule->portid == port_id)
|
|
|
|
*tx_offloads |= DEV_TX_OFFLOAD_SECURITY;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|