blob: 3a9de93396640b28ad00f65c5a7244ac22ac97f3 [file] [log] [blame]
/*
**************************************************************************
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/**
* @file nss_ipsec.h
* NSS IPSec interface definitions.
*/
#ifndef __NSS_IPSEC_H
#define __NSS_IPSEC_H
/*
* For some reason Linux doesn't define this in if_arp.h,
* refer http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
* for the full list
*/
/**
* @addtogroup nss_ipsec_subsystem
* @{
*/
#define NSS_IPSEC_ARPHRD_IPSEC 31
/**< ARP (iana.org) hardware type for an IPsec tunnel. */
#define NSS_IPSEC_MAX_RULES 256
/**< Maximum number of rules supported. */
#define NSS_IPSEC_MAX_SA NSS_CRYPTO_MAX_IDXS
/**< Maximum number of SAs supported. */
#if (~(NSS_IPSEC_MAX_RULES - 1) & (NSS_IPSEC_MAX_RULES >> 1))
#error "NSS Max SA should be a power of 2"
#endif
/**
* Size of an IPsec message.
*/
#define NSS_IPSEC_MSG_LEN (sizeof(struct nss_ipsec_msg) - sizeof(struct nss_cmn_msg))
/**
* nss_ipsec_msg_type
* Rules for the IPsec interface.
*/
enum nss_ipsec_msg_type {
NSS_IPSEC_MSG_TYPE_NONE = 0,
NSS_IPSEC_MSG_TYPE_ADD_RULE = 1,
NSS_IPSEC_MSG_TYPE_DEL_RULE = 2,
NSS_IPSEC_MSG_TYPE_FLUSH_TUN = 3,
NSS_IPSEC_MSG_TYPE_SYNC_SA_STATS = 4,
NSS_IPSEC_MSG_TYPE_SYNC_FLOW_STATS = 5,
NSS_IPSEC_MSG_TYPE_SYNC_NODE_STATS = 6,
NSS_IPSEC_MSG_TYPE_CONFIGURE_NODE = 7,
NSS_IPSEC_MSG_TYPE_MAX
};
/**
* nss_ipsec_status
* Status types for the IPsec interface.
*/
typedef enum nss_ipsec_status {
NSS_IPSEC_STATUS_OK = 0,
NSS_IPSEC_STATUS_ENOMEM = 1,
NSS_IPSEC_STATUS_ENOENT = 2,
NSS_IPSEC_STATUS_MAX
} nss_ipsec_status_t;
/**
* nss_ipsec_error_type
* Error types for the IPsec interface.
*/
enum nss_ipsec_error_type {
NSS_IPSEC_ERROR_TYPE_NONE = 0,
NSS_IPSEC_ERROR_TYPE_HASH_DUPLICATE = 1,
NSS_IPSEC_ERROR_TYPE_HASH_COLLISION = 2,
NSS_IPSEC_ERROR_TYPE_UNHANDLED_MSG = 3,
NSS_IPSEC_ERROR_TYPE_INVALID_RULE = 4,
NSS_IPSEC_ERROR_TYPE_MAX_SA = 5,
NSS_IPSEC_ERROR_TYPE_MAX_FLOW = 6,
NSS_IPSEC_ERROR_TYPE_INVALID_CINDEX = 7,
NSS_IPSEC_ERROR_TYPE_INVALID_IPVER = 8,
NSS_IPSEC_ERROR_TYPE_MAX
};
/**
* nss_ipsec_type
* Operation types for the IPsec interface.
*/
enum nss_ipsec_type {
NSS_IPSEC_TYPE_NONE = 0,
NSS_IPSEC_TYPE_ENCAP = 1,
NSS_IPSEC_TYPE_DECAP = 2,
NSS_IPSEC_TYPE_MAX
};
/**
* nss_ipsec_tuple
* Common IPsec rule selector tuple for encapsulation and decapsulation.
*
* This selector is used for preparing a lookup tuple for incoming packets.
* The tuple is used to derive the index into the rule table.
*
* Choosing the selector fields depends on the IPsec encapsulation or decapsulation
* package. The host has no understanding of the index derived from the selector fields,
* and thus it provides information for all entries in the structure.
*
* The encapsulation and decapsulation packages return the index in their respective
* tables to the host. The host stores the rule for future reference purposes.
*/
struct nss_ipsec_tuple {
uint32_t dst_addr[4]; /**< Destination IP address. */
uint32_t src_addr[4]; /**< Source IP address. */
uint32_t esp_spi; /**< SPI index. */
uint16_t dst_port; /**< Destination port (UDP or TCP). */
uint16_t src_port; /**< Source port (UDP or TCP). */
uint8_t proto_next_hdr; /**< IP header type. */
uint8_t ip_ver; /**< IP version. */
uint8_t res[2]; /**< Reserved for 4-byte alignment. */
};
/**
* nss_ipsec_rule_oip
* Common information about the IPsec rule outer IP header.
*/
struct nss_ipsec_rule_oip {
uint32_t dst_addr[4]; /**< IPv4 destination address to apply. */
uint32_t src_addr[4]; /**< IPv4 source address to apply. */
uint32_t esp_spi; /**< ESP SPI index to apply. */
uint16_t dst_port; /**< Destination port (UDP or TCP). */
uint16_t src_port; /**< Source port (UDP or TCP). */
uint8_t ttl_hop_limit; /**< IPv4 time-to-live value to apply. */
uint8_t ip_ver; /**< IP version. */
uint8_t proto_next_hdr; /**< IP header type. */
uint8_t res; /**< Reserved for 4-byte alignment. */
};
/**
* nss_ipsec_rule_data
* IPsec rule data used for per-packet transformation.
*/
struct nss_ipsec_rule_data {
uint16_t crypto_index; /**< Crypto index for the security association. */
uint16_t window_size; /**< ESP sequence number window. */
uint8_t cipher_blk_len; /**< Size of the cipher block. */
uint8_t iv_len; /**< Size of the initialization vector. */
uint8_t nat_t_req; /**< NAT-T required. */
uint8_t esp_icv_len; /**< Size of the ICV to be produced as a result of authentication. */
uint8_t esp_seq_skip; /**< Skip an ESP sequence number. */
uint8_t esp_tail_skip; /**< Skip an ESP trailer. */
uint8_t use_pattern; /**< Use random pattern in a hash calculation. */
uint8_t enable_esn; /**< Enable extended sequence number. */
uint8_t dscp; /**< Default DSCP value of the SA. */
uint8_t df; /**< Default dont fragment value of the SA. */
uint8_t copy_dscp; /**< The flag tells whether to copy DSCP from inner header. */
uint8_t copy_df; /**< The flag tells Whether to copy DF from inner header. */
uint32_t res2[4]; /**< Reserved 16 bytes for future use. */
};
/**
* nss_ipsec_rule
* Push message for IPsec rules.
*
* This message is sent from the host to the NSS for performing an operation
* on NSS rule tables.
*/
struct nss_ipsec_rule {
struct nss_ipsec_rule_oip oip; /**< Per rule outer IP information. */
struct nss_ipsec_rule_data data;/**< Per rule data. */
uint32_t index; /**< Index provided by the NSS. */
uint32_t sa_idx; /**< Rule index for the security association table. */
};
/**
* nss_ipsec_configure_node
* Push message for setting IPsec inline mode and initializing DMA rings.
*/
struct nss_ipsec_configure_node {
bool dma_redirect; /**< Program redirect DMA ring. */
bool dma_lookaside; /**< Program lookaside DMA ring. */
};
/**
* nss_ipsec_sa_stats
* Packet statistics per security association.
*/
struct nss_ipsec_sa_stats {
uint32_t count; /**< Packets processed. */
uint32_t bytes; /**< Bytes processed. */
uint32_t no_headroom; /**< Insufficient headroom. */
uint32_t no_tailroom; /**< Insufficient tailroom. */
uint32_t no_resource; /**< No crypto buffer. */
uint32_t fail_queue; /**< Failed to enqueue. */
uint32_t fail_hash; /**< Hash mismatch. */
uint32_t fail_replay; /**< Replay check failure. */
uint64_t seq_num; /**< Current sequence number. */
uint64_t window_max; /**< Maximum size of the window. */
uint32_t window_size; /**< Current window size. */
uint32_t fail_hash_cont; /**< Consecutive hash fail count. */
uint8_t esn_enabled; /**< Indicates whether ESN is enabled. */
uint8_t res[3]; /**< Reserved for future use. */
} /** @cond */ __attribute__((packed))/** @endcond */;
/**
* nss_ipsec_flow_stats
* Per-flow statistics.
*/
struct nss_ipsec_flow_stats {
uint32_t processed; /**< Packets processed for this flow. */
uint8_t use_pattern; /**< Use random pattern. */
uint8_t res[3]; /**< Reserved for 4-byte alignment padding. */
};
/**
* nss_ipsec_node_stats
* Per-node statistics.
*/
struct nss_ipsec_node_stats {
uint32_t enqueued; /**< Packets enqueued to the node. */
uint32_t completed; /**< Packets processed by the node. */
uint32_t linearized; /**< Packet is linear. */
uint32_t exceptioned; /**< Packets exception from the NSS. */
uint32_t fail_enqueue; /**< Packets failed to enqueue. */
uint32_t redir_rx; /**< Packets received in redirect ring. */
uint32_t fail_redir; /**< Packets dropped in redirect ring. */
};
/**
* nss_ipsec_stats
* Common statistics structure.
*/
union nss_ipsec_stats {
struct nss_ipsec_sa_stats sa; /**< Security association statistics. */
struct nss_ipsec_flow_stats flow; /**< Flow statistics. */
struct nss_ipsec_node_stats node; /**< Node statistics. */
};
/**
* nss_ipsec_msg
* Data for sending and receiving IPsec messages.
*/
struct nss_ipsec_msg {
struct nss_cmn_msg cm; /**< Common message header. */
uint32_t tunnel_id; /**< ID of the tunnel associated with the message. */
struct nss_ipsec_tuple tuple;
/**< Tuple to look up the SA table for encapsulation or decapsulation. */
enum nss_ipsec_type type; /**< Encapsulation or decapsulation operation. */
/**
* Payload of an IPsec message.
*/
union {
struct nss_ipsec_rule rule;
/**< IPsec rule message. */
struct nss_ipsec_configure_node node;
/**< IPsec node message. */
union nss_ipsec_stats stats;
/**< Retrieve statistics for the tunnel. */
} msg; /**< Message payload. */
};
/**
* Callback function for receiving message notifications.
*
* @datatypes
* nss_ipsec_msg
*
* @param[in] app_data Pointer to the application context of the message.
* @param[in] msg Pointer to the message data.
*/
typedef void (*nss_ipsec_msg_callback_t)(void *app_data, struct nss_ipsec_msg *msg);
/**
* Callback function for receiving data.
*
* @datatypes
* net_device \n
* sk_buff \n
* napi_struct
*
* @param[in] netdev Pointer to the associated network device.
* @param[in] skb Pointer to the message data.
* @param[in] napi Pointer to the NAPI structure.
*/
typedef void (*nss_ipsec_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi);
/**
* nss_ipsec_tx_msg
* Sends an IPsec message to the NSS HLOS driver.
*
* @datatypes
* nss_ctx_instance \n
* nss_ipsec_msg
*
* @param[in] nss_ctx Pointer to the NSS HLOS driver context.
* @param[in] msg Pointer to the message data.
*
* @return
* Status of the Tx operation.
*/
extern nss_tx_status_t nss_ipsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_msg *msg);
/**
* nss_ipsec_tx_msg_sync
* Sends IPsec messages synchronously.
*
* @datatypes
* nss_ctx_instance \n
* nss_ipsec_msg_type \n
* nss_ipsec_msg \n
* nss_ipsec_error_type
*
* @param[in] nss_ctx Pointer to the NSS context.
* @param[in] if_num Configuration interface number.
* @param[in] type Type of the message.
* @param[in] len Size of the payload.
* @param[in] nim Pointer to the message data.
* @param[in,out] resp Response for the configuration.
*
* @return
* Status of the Tx operation.
*/
extern nss_tx_status_t nss_ipsec_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num,
enum nss_ipsec_msg_type type, uint16_t len,
struct nss_ipsec_msg *nim, enum nss_ipsec_error_type *resp);
/**
* nss_ipsec_tx_buf
* Sends a plain text packet to NSS for IPsec encapsulation or decapsulation.
*
* @datatypes
* sk_buff
*
* @param[in] skb Pointer to the message data.
* @param[in] if_num Pointer to the NSS interface number.
*
* @return
* Status of the Tx operation.
*/
extern nss_tx_status_t nss_ipsec_tx_buf(struct sk_buff *skb, uint32_t if_num);
/**
* nss_ipsec_notify_register
* Registers an event callback handler with the HLOS driver.
*
* When registered, the message callback is called when the NSS
* sends a response to the message sent by the host.
*
* @datatypes
* nss_ipsec_msg_callback_t
*
* @param[in] if_num NSS interface number.
* @param[in] cb Callback function for the message.
* @param[in] app_data Pointer to the context of the message.
*
* @return
* Pointer to the NSS core context.
*/
extern struct nss_ctx_instance *nss_ipsec_notify_register(uint32_t if_num, nss_ipsec_msg_callback_t cb, void *app_data);
/**
* nss_ipsec_data_register
* Registers a data callback handler with the HLOS driver.
*
* The HLOS driver calls the registered data callback to return
* the packet to the OS.
*
* @datatypes
* nss_ipsec_buf_callback_t \n
* net_device
*
* @param[in] if_num NSS interface number.
* @param[in] cb Callback function for the data.
* @param[in] netdev Pointer to the associated network device.
* @param[in] features Data socket buffer types supported by this interface.
*
* @return
* Pointer to the NSS core context.
*/
extern struct nss_ctx_instance *nss_ipsec_data_register(uint32_t if_num, nss_ipsec_buf_callback_t cb, struct net_device *netdev, uint32_t features);
/**
* nss_ipsec_notify_unregister
* Deregisters the message notifier from the HLOS driver.
*
* @datatypes
* nss_ctx_instance
*
* @param[in,out] ctx Pointer to the context of the HLOS driver.
* @param[in] if_num NSS interface number.
*
* @return
* None.
*
* @dependencies
* The message notifier must have been previously registered.
*/
extern void nss_ipsec_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num);
/**
* nss_ipsec_data_unregister
* Deregisters the data notifier from the HLOS driver.
*
* @datatypes
* nss_ctx_instance
*
* @param[in,out] ctx Pointer to the context of the HLOS driver.
* @param[in] if_num NSS interface number.
*
* @return
* None.
*
* @dependencies
* The data notifier must have been previously registered.
*/
extern void nss_ipsec_data_unregister(struct nss_ctx_instance *ctx, uint32_t if_num);
/**
* nss_ipsec_get_context
* Gets the NSS context for the IPsec handle.
*
* @return
* Pointer to the NSS core context.
*/
extern struct nss_ctx_instance *nss_ipsec_get_context(void);
/**
* nss_ipsec_get_ifnum
* Gets the IPsec interface number with a core ID.
*
* @param[in] if_num NSS interface number.
*
* @return
* Interface number with the core ID.
*/
extern int32_t nss_ipsec_get_ifnum(int32_t if_num);
/**
* nss_ipsec_msg_init
* Initializes an IPsec message.
*
* @datatypes
* nss_ipsec_msg \n
* nss_ipsec_msg_callback_t
*
* @param[in,out] nim Pointer to the NSS interface message.
* @param[in] if_num NSS interface number.
* @param[in] type Type of message.
* @param[in] len Size of the payload.
* @param[in] cb Callback function for the message.
* @param[in] app_data Pointer to the application context of the message.
*
* @return
* None.
*/
extern void nss_ipsec_msg_init(struct nss_ipsec_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
nss_ipsec_msg_callback_t cb, void *app_data);
/**
* nss_ipsec_get_encap_interface
* Gets the NSS interface number to be used for IPsec encapsulation message.
*
* @return
* Encapsulation interface number.
*/
extern int32_t nss_ipsec_get_encap_interface(void);
/**
* nss_ipsec_get_decap_interface
* Gets the NSS interface number to be used for an IPsec decapsulation message.
*
* @return
* Decapsulation interface number.
*/
extern int32_t nss_ipsec_get_decap_interface(void);
/**
* nss_ipsec_get_data_interface
* Gets the NSS interface number to be used for an IPsec data transfer.
*
* @return
* NSS interface number.
*/
extern int32_t nss_ipsec_get_data_interface(void);
/**
* nss_ipsec_ppe_port_config
* Configure Packet Processing Engine IPsec port.
*
* @datatypes
* nss_ctx_instance \n
* net_device
*
* @param[in] ctx Pointer to the context of the HLOS driver.
* @param[in] netdev Pointer to the associated network device.
* @param[in] if_num Data interface number.
* @param[in] vsi_num Virtual switch instance number.
*
* @return
* True if successful, else false.
*/
extern bool nss_ipsec_ppe_port_config(struct nss_ctx_instance *ctx, struct net_device *netdev,
uint32_t if_num, uint32_t vsi_num);
/**
* nss_ipsec_ppe_mtu_update()
* Configure Packet Processing Engine MTU for IPsec in-line.
*
* @datatypes
* nss_ctx_instance \n
*
* @param[in] ctx Pointer to the context of the HLOS driver.
* @param[in] if_num Data interface number.
* @param[in] mtu Maximum transmission unit of Interface number.
* @param[in] mru Maximum Receive unit of Interface number.
*
* @return
* True if successful, else false.
*/
bool nss_ipsec_ppe_mtu_update(struct nss_ctx_instance *ctx, uint32_t if_num, uint16_t mtu, uint16_t mru);
/**
* @}
*/
#endif /* __NSS_IPSEC_H */