mirror of https://github.com/F-Stack/f-stack.git
381 lines
9.4 KiB
C
381 lines
9.4 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(c) 2022 Intel Corporation
|
|
*/
|
|
#ifndef __INCLUDE_RTE_SWX_IPSEC_H__
|
|
#define __INCLUDE_RTE_SWX_IPSEC_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @file
|
|
* RTE SWX Internet Protocol Security (IPsec)
|
|
*
|
|
* The IPsec block is a companion block for the SWX pipeline used to provide IPsec support to the
|
|
* pipeline. The block is external to the pipeline, hence it needs to be explicitly instantiated by
|
|
* the user and connected to a pipeline instance through the pipeline I/O ports.
|
|
*
|
|
* Main features:
|
|
* - IPsec inbound (encrypted input packets -> clear text output packets) and outbound (clear text
|
|
* input packets -> encrypted output packets) processing support for tunnel and transport modes.
|
|
*
|
|
* Security Association (SA):
|
|
* - Each IPsec block instance has its own set of SAs used to process the input packets. Each SA is
|
|
* identified by its unique SA ID. The IPsec inbound and outbound SAs share the same ID space.
|
|
* - Each input packet is first mapped to one of the existing SAs by using the SA ID and then
|
|
* processed according to the identified SA. The SA ID is read from input packet. The SA ID field
|
|
* is typically written by the pipeline before sending the packet to the IPsec block.
|
|
*
|
|
* Packet format:
|
|
* - IPsec block input packet (i.e. pipeline output packet):
|
|
* - IPsec block meta-data header: @see struct rte_swx_ipsec_input_packet_metadata.
|
|
* - IPv4 header.
|
|
* - IPv4 payload: on the inbound path, it includes the encrypted ESP packet.
|
|
* - IPsec block output packet (i.e. pipeline input packet):
|
|
* - IPv4 header.
|
|
* - IPv4 payload: on the outbound path, it includes the encrypted ESP packet.
|
|
*
|
|
* SA update procedure:
|
|
* - To add a new SA, @see function rte_swx_ipsec_sa_add().
|
|
* - To delete an existing SA, @see function rte_swx_ipsec_sa_delete().
|
|
* - To update an existing SA, the control plane has to follow the following steps:
|
|
* 1. Add a new SA with potentially a different set of configuration parameters. This step can
|
|
* fail, for example when the SA table is full.
|
|
* 2. Wait until no more packets are using the old SA.
|
|
* 3. Delete the old SA.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <rte_compat.h>
|
|
#include <rte_crypto_sym.h>
|
|
|
|
/**
|
|
* IPsec Setup API
|
|
*/
|
|
|
|
/** IPsec instance opaque data structure. */
|
|
struct rte_swx_ipsec;
|
|
|
|
/** Name size. */
|
|
#ifndef RTE_SWX_IPSEC_NAME_SIZE
|
|
#define RTE_SWX_IPSEC_NAME_SIZE 64
|
|
#endif
|
|
|
|
/** Maximum burst size. */
|
|
#ifndef RTE_SWX_IPSEC_BURST_SIZE_MAX
|
|
#define RTE_SWX_IPSEC_BURST_SIZE_MAX 256
|
|
#endif
|
|
|
|
/** IPsec burst sizes. */
|
|
struct rte_swx_ipsec_burst_size {
|
|
/** Input ring read burst size. */
|
|
uint32_t ring_rd;
|
|
|
|
/** Output ring write burst size. */
|
|
uint32_t ring_wr;
|
|
|
|
/** Crypto device request queue write burst size. */
|
|
uint32_t crypto_wr;
|
|
|
|
/** Crypto device response queue read burst size. */
|
|
uint32_t crypto_rd;
|
|
};
|
|
|
|
/**
|
|
* IPsec instance configuration parameters
|
|
*/
|
|
struct rte_swx_ipsec_params {
|
|
/** Input packet queue. */
|
|
const char *ring_in_name;
|
|
|
|
/** Output packet queue. */
|
|
const char *ring_out_name;
|
|
|
|
/** Crypto device name. */
|
|
const char *crypto_dev_name;
|
|
|
|
/** Crypto device queue pair ID. */
|
|
uint32_t crypto_dev_queue_pair_id;
|
|
|
|
/** Burst size. */
|
|
struct rte_swx_ipsec_burst_size bsz;
|
|
|
|
/** Maximum number of SAs. */
|
|
uint32_t n_sa_max;
|
|
};
|
|
|
|
/**
|
|
* IPsec input packet meta-data
|
|
*/
|
|
struct rte_swx_ipsec_input_packet_metadata {
|
|
/* SA ID. */
|
|
uint32_t sa_id;
|
|
};
|
|
|
|
/**
|
|
* IPsec instance find
|
|
*
|
|
* @param[in] name
|
|
* IPsec instance name.
|
|
* @return
|
|
* Valid IPsec instance handle if found or NULL otherwise.
|
|
*/
|
|
__rte_experimental
|
|
struct rte_swx_ipsec *
|
|
rte_swx_ipsec_find(const char *name);
|
|
|
|
/**
|
|
* IPsec instance create
|
|
*
|
|
* @param[out] ipsec
|
|
* IPsec instance handle. Must point to valid memory. Contains valid pipeline handle once this
|
|
* function returns successfully.
|
|
* @param[in] name
|
|
* IPsec instance unique name.
|
|
* @param[in] params
|
|
* IPsec instance configuration parameters.
|
|
* @param[in] numa_node
|
|
* Non-Uniform Memory Access (NUMA) node.
|
|
* @return
|
|
* 0 on success or the following error codes otherwise:
|
|
* -EINVAL: Invalid argument;
|
|
* -ENOMEM: Not enough space/cannot allocate memory;
|
|
* -EEXIST: Pipeline with this name already exists.
|
|
*/
|
|
__rte_experimental
|
|
int
|
|
rte_swx_ipsec_create(struct rte_swx_ipsec **ipsec,
|
|
const char *name,
|
|
struct rte_swx_ipsec_params *params,
|
|
int numa_node);
|
|
|
|
/**
|
|
* IPsec instance free
|
|
*
|
|
* @param[in] ipsec
|
|
* IPsec instance handle.
|
|
*/
|
|
__rte_experimental
|
|
void
|
|
rte_swx_ipsec_free(struct rte_swx_ipsec *ipsec);
|
|
|
|
/**
|
|
* IPsec Data Plane API
|
|
*/
|
|
|
|
/**
|
|
* IPsec instance run
|
|
*
|
|
* @param[in] ipsec
|
|
* IPsec instance handle.
|
|
*/
|
|
__rte_experimental
|
|
void
|
|
rte_swx_ipsec_run(struct rte_swx_ipsec *ipsec);
|
|
|
|
/*
|
|
* IPsec Control Plane API
|
|
*/
|
|
|
|
/** Maximum key size in bytes. */
|
|
#define RTE_SWX_IPSEC_KEY_SIZE_MAX 64
|
|
|
|
/** IPsec SA crypto cipher parameters. */
|
|
struct rte_swx_ipsec_sa_cipher_params {
|
|
/** Cipher algorithm. */
|
|
enum rte_crypto_cipher_algorithm alg;
|
|
|
|
/** Cipher key. */
|
|
uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
|
|
|
|
/** Cipher key size in bytes. */
|
|
uint32_t key_size;
|
|
};
|
|
|
|
/** IPsec SA crypto authentication parameters. */
|
|
struct rte_swx_ipsec_sa_authentication_params {
|
|
/** Authentication algorithm. */
|
|
enum rte_crypto_auth_algorithm alg;
|
|
|
|
/** Authentication key. */
|
|
uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
|
|
|
|
/** Authentication key size in bytes. */
|
|
uint32_t key_size;
|
|
};
|
|
|
|
/** IPsec SA crypto Authenticated Encryption with Associated Data (AEAD) parameters. */
|
|
struct rte_swx_ipsec_sa_aead_params {
|
|
/** AEAD algorithm. */
|
|
enum rte_crypto_aead_algorithm alg;
|
|
|
|
/** AEAD key. */
|
|
uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
|
|
|
|
/** AEAD key size in bytes. */
|
|
uint32_t key_size;
|
|
};
|
|
|
|
/** IPsec protocol encapsulation parameters. */
|
|
struct rte_swx_ipsec_sa_encap_params {
|
|
/** Encapsulating Security Payload (ESP) header. */
|
|
struct {
|
|
/** Security Parameters Index (SPI) field. */
|
|
uint32_t spi;
|
|
} esp;
|
|
|
|
/** Tunnel mode when non-zero, transport mode when zero. */
|
|
int tunnel_mode;
|
|
|
|
/** Tunnel type: Non-zero for IPv4, zero for IPv6. Valid for tunnel mode only. */
|
|
int tunnel_ipv4;
|
|
|
|
/** Tunnel parameters. Valid for tunnel mode only. */
|
|
union {
|
|
/** IPv4 header. */
|
|
struct {
|
|
/** Source address. */
|
|
struct in_addr src_addr;
|
|
|
|
/** Destination address. */
|
|
struct in_addr dst_addr;
|
|
} ipv4;
|
|
|
|
/** IPv6 header. */
|
|
struct {
|
|
/** Source address. */
|
|
struct in6_addr src_addr;
|
|
|
|
/** Destination address. */
|
|
struct in6_addr dst_addr;
|
|
} ipv6;
|
|
} tunnel;
|
|
};
|
|
|
|
/** IPsec Security Association (SA) parameters. */
|
|
struct rte_swx_ipsec_sa_params {
|
|
/** Crypto operation: encrypt when non-zero, decrypt when zero. */
|
|
int encrypt;
|
|
|
|
/** Crypto operation parameters. */
|
|
struct {
|
|
union {
|
|
struct {
|
|
/** Crypto cipher operation parameters. */
|
|
struct rte_swx_ipsec_sa_cipher_params cipher;
|
|
|
|
/** Crypto authentication operation parameters. */
|
|
struct rte_swx_ipsec_sa_authentication_params auth;
|
|
} cipher_auth;
|
|
|
|
/** Crypto AEAD operation parameters. */
|
|
struct rte_swx_ipsec_sa_aead_params aead;
|
|
};
|
|
|
|
/** Non-zero for AEAD, zero for cipher & authentication. */
|
|
int is_aead;
|
|
} crypto;
|
|
|
|
/** Packet encasulation parameters. */
|
|
struct rte_swx_ipsec_sa_encap_params encap;
|
|
};
|
|
|
|
/**
|
|
* IPsec SA add
|
|
*
|
|
* @param[in] ipsec
|
|
* IPsec instance handle.
|
|
* @param[in] sa_params
|
|
* SA parameters.
|
|
* @param[out] sa_id
|
|
* On success, the SA ID.
|
|
* @return
|
|
* 0 on success or error code otherwise.
|
|
*/
|
|
__rte_experimental
|
|
int
|
|
rte_swx_ipsec_sa_add(struct rte_swx_ipsec *ipsec,
|
|
struct rte_swx_ipsec_sa_params *sa_params,
|
|
uint32_t *sa_id);
|
|
|
|
/**
|
|
* IPsec SA delete
|
|
*
|
|
* It is the responibility of the Control Plane to make sure the SA to be deleted is no longer used
|
|
* by the Data Plane.
|
|
*
|
|
* @param[in] ipsec
|
|
* IPsec instance handle.
|
|
* @param[in] sa_id
|
|
* The SA ID.
|
|
*/
|
|
__rte_experimental
|
|
void
|
|
rte_swx_ipsec_sa_delete(struct rte_swx_ipsec *ipsec,
|
|
uint32_t sa_id);
|
|
|
|
/**
|
|
* IPsec SA read from string
|
|
*
|
|
* IPsec SA syntax:
|
|
*
|
|
* \<sa>
|
|
* : encrypt \<crypto_params> \<encap_params>
|
|
* | decrypt \<crypto_params> \<encap_params>
|
|
* ;
|
|
*
|
|
* \<crypto_params>
|
|
* : \<cipher> \<auth>
|
|
* | \<aead>
|
|
* ;
|
|
*
|
|
* \<cipher>
|
|
* : cipher \<ciher_alg> key \<cipher_key>
|
|
* | cipher \<cipher_alg>
|
|
* ;
|
|
*
|
|
* \<auth>
|
|
* : auth \<authentication_alg> key \<authentication_key>
|
|
* | auth \<authentication_alg>
|
|
* ;
|
|
*
|
|
* \<aead>
|
|
* : aead \<aead_alg> key \<aead_key>
|
|
* ;
|
|
*
|
|
* \<encap_params>
|
|
* : esp spi \<spi> tunnel ipv4 srcaddr \<ipv4_src_addr> dstaddr \<ipv4_dst_addr>
|
|
* | esp spi \<spi> tunnel ipv6 srcaddr \<ipv6_src_addr> dstaddr \<ipv6_dst_addr>
|
|
* | esp spi \<spi> transport
|
|
* ;
|
|
*
|
|
* @param[in] ipsec
|
|
* IPsec instance handle.
|
|
* @param[in] string
|
|
* String containing the SA.
|
|
* @param[in,out] is_blank_or_comment
|
|
* On error, when its input value is not NULL, this argument is set to a non-zero value when
|
|
* *string* contains a blank or comment line and to zero otherwise.
|
|
* @param[in,out] errmsg
|
|
* On error, when its input value is not NULL, this argument points to a string with details on
|
|
* the detected error.
|
|
* @return
|
|
* Pointer to valid IPsec SA parameters data structure on success or NULL on error.
|
|
*/
|
|
__rte_experimental
|
|
struct rte_swx_ipsec_sa_params *
|
|
rte_swx_ipsec_sa_read(struct rte_swx_ipsec *ipsec,
|
|
const char *string,
|
|
int *is_blank_or_comment,
|
|
const char **errmsg);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|