ipsec: add inbound SAD API
According to RFC 4301 IPSec implementation needs an inbound SA database (SAD). For each incoming inbound IPSec-protected packet (ESP or AH) it has to perform a lookup within it's SAD. Lookup should be performed by: Security Parameters Index (SPI) + destination IP (DIP) + source IP (SIP) or SPI + DIP or SPI only and an implementation has to return the 'longest' existing match. This patch extend DPDK IPsec library with inbound security association database (SAD) API implementation that: - conforms to the RFC requirements above - can scale up to millions of entries - supports fast lookups - supports incremental updates Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This commit is contained in:
parent
65beb9abca
commit
401633d9c1
@ -143,6 +143,21 @@ In that mode the library functions perform
|
||||
To accommodate future custom implementations function pointers
|
||||
model is used for both *crypto_prepare* and *process* implementations.
|
||||
|
||||
SA database API
|
||||
----------------
|
||||
|
||||
SA database(SAD) is a table with <key, value> pairs.
|
||||
|
||||
Value is an opaque user provided pointer to the user defined SA data structure.
|
||||
|
||||
According to RFC4301 each SA can be uniquely identified by a key
|
||||
which is either:
|
||||
|
||||
- security parameter index(SPI)
|
||||
- or SPI and destination IP(DIP)
|
||||
- or SPI, DIP and source IP(SIP)
|
||||
|
||||
In case of multiple matches, longest matching key will be returned.
|
||||
|
||||
Supported features
|
||||
------------------
|
||||
|
@ -136,6 +136,10 @@ New Features
|
||||
and use memory zones as external buffers instead of keeping the data directly
|
||||
in mbuf areas.
|
||||
|
||||
* **Updated the IPSec library.**
|
||||
|
||||
Added SA Database API to ``librte_ipsec``.
|
||||
|
||||
* **Introduced FIFO for NTB PMD.**
|
||||
|
||||
Introduced FIFO for NTB (Non-transparent Bridge) PMD to support
|
||||
|
@ -21,10 +21,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += esp_inb.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += esp_outb.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += sa.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += ses.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += ipsec_sad.c
|
||||
|
||||
# install header files
|
||||
SYMLINK-$(CONFIG_RTE_LIBRTE_IPSEC)-include += rte_ipsec.h
|
||||
SYMLINK-$(CONFIG_RTE_LIBRTE_IPSEC)-include += rte_ipsec_group.h
|
||||
SYMLINK-$(CONFIG_RTE_LIBRTE_IPSEC)-include += rte_ipsec_sa.h
|
||||
SYMLINK-$(CONFIG_RTE_LIBRTE_IPSEC)-include += rte_ipsec_sad.h
|
||||
|
||||
include $(RTE_SDK)/mk/rte.lib.mk
|
||||
|
50
lib/librte_ipsec/ipsec_sad.c
Normal file
50
lib/librte_ipsec/ipsec_sad.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <rte_errno.h>
|
||||
|
||||
#include "rte_ipsec_sad.h"
|
||||
|
||||
int
|
||||
rte_ipsec_sad_add(__rte_unused struct rte_ipsec_sad *sad,
|
||||
__rte_unused const union rte_ipsec_sad_key *key,
|
||||
__rte_unused int key_type, __rte_unused void *sa)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ipsec_sad_del(__rte_unused struct rte_ipsec_sad *sad,
|
||||
__rte_unused const union rte_ipsec_sad_key *key,
|
||||
__rte_unused int key_type)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
struct rte_ipsec_sad *
|
||||
rte_ipsec_sad_create(__rte_unused const char *name,
|
||||
__rte_unused const struct rte_ipsec_sad_conf *conf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct rte_ipsec_sad *
|
||||
rte_ipsec_sad_find_existing(__rte_unused const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
rte_ipsec_sad_destroy(__rte_unused struct rte_ipsec_sad *sad)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ipsec_sad_lookup(__rte_unused const struct rte_ipsec_sad *sad,
|
||||
__rte_unused const union rte_ipsec_sad_key *keys[],
|
||||
__rte_unused void *sa[], __rte_unused uint32_t n)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
|
||||
allow_experimental_apis = true
|
||||
|
||||
sources = files('esp_inb.c', 'esp_outb.c', 'sa.c', 'ses.c')
|
||||
sources = files('esp_inb.c', 'esp_outb.c', 'sa.c', 'ses.c', 'ipsec_sad.c')
|
||||
|
||||
headers = files('rte_ipsec.h', 'rte_ipsec_group.h', 'rte_ipsec_sa.h')
|
||||
headers = files('rte_ipsec.h', 'rte_ipsec_group.h', 'rte_ipsec_sa.h', 'rte_ipsec_sad.h')
|
||||
|
||||
deps += ['mbuf', 'net', 'cryptodev', 'security']
|
||||
|
176
lib/librte_ipsec/rte_ipsec_sad.h
Normal file
176
lib/librte_ipsec/rte_ipsec_sad.h
Normal file
@ -0,0 +1,176 @@
|
||||
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _RTE_IPSEC_SAD_H_
|
||||
#define _RTE_IPSEC_SAD_H_
|
||||
|
||||
#include <rte_compat.h>
|
||||
|
||||
/**
|
||||
* @file rte_ipsec_sad.h
|
||||
* @b EXPERIMENTAL: this API may change without prior notice
|
||||
*
|
||||
* RTE IPsec security association database (SAD) support.
|
||||
* Contains helper functions to lookup and maintain SAD
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rte_ipsec_sad;
|
||||
|
||||
/** Type of key */
|
||||
enum {
|
||||
RTE_IPSEC_SAD_SPI_ONLY = 0,
|
||||
RTE_IPSEC_SAD_SPI_DIP,
|
||||
RTE_IPSEC_SAD_SPI_DIP_SIP,
|
||||
RTE_IPSEC_SAD_KEY_TYPE_MASK,
|
||||
};
|
||||
|
||||
struct rte_ipsec_sadv4_key {
|
||||
uint32_t spi;
|
||||
uint32_t dip;
|
||||
uint32_t sip;
|
||||
};
|
||||
|
||||
struct rte_ipsec_sadv6_key {
|
||||
uint32_t spi;
|
||||
uint8_t dip[16];
|
||||
uint8_t sip[16];
|
||||
};
|
||||
|
||||
union rte_ipsec_sad_key {
|
||||
struct rte_ipsec_sadv4_key v4;
|
||||
struct rte_ipsec_sadv6_key v6;
|
||||
};
|
||||
|
||||
/** Flag to create SAD with ipv6 dip and sip addresses */
|
||||
#define RTE_IPSEC_SAD_FLAG_IPV6 0x1
|
||||
/** Flag to support reader writer concurrency */
|
||||
#define RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY 0x2
|
||||
|
||||
/** IPsec SAD configuration structure */
|
||||
struct rte_ipsec_sad_conf {
|
||||
/** CPU socket ID where rte_ipsec_sad should be allocated */
|
||||
int socket_id;
|
||||
/** maximum number of SA for each type of key */
|
||||
uint32_t max_sa[RTE_IPSEC_SAD_KEY_TYPE_MASK];
|
||||
/** RTE_IPSEC_SAD_FLAG_* flags */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a rule into the SAD. Could be safely called with concurrent lookups
|
||||
* if RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY flag was configured on creation time.
|
||||
* While with this flag multi-reader - one-writer model Is MT safe,
|
||||
* multi-writer model is not and required extra synchronisation.
|
||||
*
|
||||
* @param sad
|
||||
* SAD object handle
|
||||
* @param key
|
||||
* pointer to the key
|
||||
* @param key_type
|
||||
* key type (spi only/spi+dip/spi+dip+sip)
|
||||
* @param sa
|
||||
* Pointer associated with the key to save in a SAD
|
||||
* Must be 4 bytes aligned.
|
||||
* @return
|
||||
* 0 on success, negative value otherwise
|
||||
*/
|
||||
__rte_experimental
|
||||
int
|
||||
rte_ipsec_sad_add(struct rte_ipsec_sad *sad,
|
||||
const union rte_ipsec_sad_key *key,
|
||||
int key_type, void *sa);
|
||||
|
||||
/**
|
||||
* Delete a rule from the SAD. Could be safely called with concurrent lookups
|
||||
* if RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY flag was configured on creation time.
|
||||
* While with this flag multi-reader - one-writer model Is MT safe,
|
||||
* multi-writer model is not and required extra synchronisation.
|
||||
*
|
||||
* @param sad
|
||||
* SAD object handle
|
||||
* @param key
|
||||
* pointer to the key
|
||||
* @param key_type
|
||||
* key type (spi only/spi+dip/spi+dip+sip)
|
||||
* @return
|
||||
* 0 on success, negative value otherwise
|
||||
*/
|
||||
__rte_experimental
|
||||
int
|
||||
rte_ipsec_sad_del(struct rte_ipsec_sad *sad,
|
||||
const union rte_ipsec_sad_key *key,
|
||||
int key_type);
|
||||
/*
|
||||
* Create SAD
|
||||
*
|
||||
* @param name
|
||||
* SAD name
|
||||
* @param conf
|
||||
* Structure containing the configuration
|
||||
* @return
|
||||
* Handle to SAD object on success
|
||||
* NULL otherwise with rte_errno set to an appropriate values.
|
||||
*/
|
||||
__rte_experimental
|
||||
struct rte_ipsec_sad *
|
||||
rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf);
|
||||
|
||||
/**
|
||||
* Find an existing SAD object and return a pointer to it.
|
||||
*
|
||||
* @param name
|
||||
* Name of the SAD object as passed to rte_ipsec_sad_create()
|
||||
* @return
|
||||
* Pointer to sad object or NULL if object not found with rte_errno
|
||||
* set appropriately. Possible rte_errno values include:
|
||||
* - ENOENT - required entry not available to return.
|
||||
*/
|
||||
__rte_experimental
|
||||
struct rte_ipsec_sad *
|
||||
rte_ipsec_sad_find_existing(const char *name);
|
||||
|
||||
/**
|
||||
* Destroy SAD object.
|
||||
*
|
||||
* @param sad
|
||||
* pointer to the SAD object
|
||||
* @return
|
||||
* None
|
||||
*/
|
||||
__rte_experimental
|
||||
void
|
||||
rte_ipsec_sad_destroy(struct rte_ipsec_sad *sad);
|
||||
|
||||
/**
|
||||
* Lookup multiple keys in the SAD.
|
||||
*
|
||||
* @param sad
|
||||
* SAD object handle
|
||||
* @param keys
|
||||
* Array of keys to be looked up in the SAD
|
||||
* @param sa
|
||||
* Pointer assocoated with the keys.
|
||||
* If the lookup for the given key failed, then corresponding sa
|
||||
* will be NULL
|
||||
* @param n
|
||||
* Number of elements in keys array to lookup.
|
||||
* @return
|
||||
* -EINVAL for incorrect arguments, otherwise number of successful lookups.
|
||||
*/
|
||||
__rte_experimental
|
||||
int
|
||||
rte_ipsec_sad_lookup(const struct rte_ipsec_sad *sad,
|
||||
const union rte_ipsec_sad_key *keys[],
|
||||
void *sa[], uint32_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTE_IPSEC_SAD_H_ */
|
@ -8,6 +8,12 @@ EXPERIMENTAL {
|
||||
rte_ipsec_sa_init;
|
||||
rte_ipsec_sa_size;
|
||||
rte_ipsec_sa_type;
|
||||
rte_ipsec_sad_add;
|
||||
rte_ipsec_sad_create;
|
||||
rte_ipsec_sad_del;
|
||||
rte_ipsec_sad_destroy;
|
||||
rte_ipsec_sad_find_existing;
|
||||
rte_ipsec_sad_lookup;
|
||||
rte_ipsec_ses_from_crypto;
|
||||
rte_ipsec_session_prepare;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user