Reviewed-by: Nikhil Agarwal<nikhil.agar...@linaro.org>


On 12/1/2016 2:47 PM, Petri Savolainen wrote:
Added definitions for a look-a-side IPSEC offload API. In addition to
IPSEC packet transformations, it also supports:
* inbound SA look up
* outbound IP fragmentation

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---

Changes in v3:
* Reword packet ordering specification

Changes in v2:
* Specify that synchronous calls cannot process all packets
   if output.num_pkt < input.num_pkt
* Specify that resulting event must be freed before calling using packets
* Added soft/hard sec limit capability
* Improved packet order specification

Changes in v1:
* renamed odp_ipsec_proto_t to renamed odp_ipsec_protocol_t
* specify that lifetime sec limit is from the SA creation
* added odp_ipsec_sa_context()
* pool for output packets is the same as packet input pool
* added antireplay check and protocol error codes
* specified which input / output packet offsets and flags are set
* moved sync/async mode selection to global config (odp_ipsec_config())
* added IPSEC capability to aid mode selection
* specify that also packet user area is copied from input to output packet


  include/odp/api/spec/event.h                       |   2 +-
  include/odp/api/spec/ipsec.h                       | 883 +++++++++++++++++++++
  include/odp_api.h                                  |   1 +
  platform/Makefile.inc                              |   1 +
  platform/linux-generic/Makefile.am                 |   2 +
  platform/linux-generic/include/odp/api/ipsec.h     |  36 +
  .../include/odp/api/plat/event_types.h             |   1 +
  .../include/odp/api/plat/ipsec_types.h             |  39 +
  8 files changed, 964 insertions(+), 1 deletion(-)
  create mode 100644 include/odp/api/spec/ipsec.h
  create mode 100644 platform/linux-generic/include/odp/api/ipsec.h
  create mode 100644 platform/linux-generic/include/odp/api/plat/ipsec_types.h

diff --git a/include/odp/api/spec/event.h b/include/odp/api/spec/event.h
index fdfa52d..75c0bbc 100644
--- a/include/odp/api/spec/event.h
+++ b/include/odp/api/spec/event.h
@@ -39,7 +39,7 @@ extern "C" {
   * @typedef odp_event_type_t
   * ODP event types:
   * ODP_EVENT_BUFFER, ODP_EVENT_PACKET, ODP_EVENT_TIMEOUT,
- * ODP_EVENT_CRYPTO_COMPL
+ * ODP_EVENT_CRYPTO_COMPL, ODP_EVENT_IPSEC_RESULT
   */
/**
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h
new file mode 100644
index 0000000..86f66e6
--- /dev/null
+++ b/include/odp/api/spec/ipsec.h
@@ -0,0 +1,883 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP IPSEC API
+ */
+
+#ifndef ODP_API_IPSEC_H_
+#define ODP_API_IPSEC_H_
+#include <odp/visibility_begin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/crypto.h>
+
+/** @defgroup odp_ipsec ODP IPSEC
+ *  Operations of IPSEC API.
+ *  @{
+ */
+
+/**
+ * @typedef odp_ipsec_sa_t
+ * IPSEC Security Association (SA)
+ */
+
+ /**
+ * @def ODP_IPSEC_SA_INVALID
+ * Invalid IPSEC SA
+ */
+
+/**
+ * IPSEC operation mode
+ */
+typedef enum odp_ipsec_op_mode_t {
+       /** Synchronous IPSEC operation
+         *
+         * Application uses synchronous IPSEC operations,
+         * which output all results on function return.
+         */
+       ODP_IPSEC_OP_MODE_SYNC = 0,
+
+       /** Asynchronous IPSEC operation
+         *
+         * Application uses asynchronous IPSEC operations,
+         * which return results via events.
+         */
+       ODP_IPSEC_OP_MODE_ASYNC
+
+} odp_ipsec_op_mode_t;
+
+/**
+ * IPSEC capability
+ */
+typedef struct odp_ipsec_capability_t {
+       /** Maximum number of IPSEC SAs */
+       uint32_t max_num_sa;
+
+       /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support
+        *
+        *  0: Synchronous mode is not supported
+        *  1: Synchronous mode is supported
+        *  2: Synchronous mode is supported and preferred
+        */
+       uint8_t op_mode_sync;
+
+       /** Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support
+        *
+        *  0: Asynchronous mode is not supported
+        *  1: Asynchronous mode is supported
+        *  2: Asynchronous mode is supported and preferred
+        */
+       uint8_t op_mode_async;
+
+       /** Soft expiry limit in seconds support
+        *
+        *  0: Limit is not supported
+        *  1: Limit is supported
+        */
+       uint8_t soft_limit_sec;
+
+       /** Hard expiry limit in seconds support
+        *
+        *  0: Limit is not supported
+        *  1: Limit is supported
+        */
+       uint8_t hard_limit_sec;
+
+       /** Supported cipher algorithms */
+       odp_crypto_cipher_algos_t ciphers;
+
+       /** Supported authentication algorithms */
+       odp_crypto_auth_algos_t   auths;
+
+} odp_ipsec_capability_t;
+
+/**
+ * IPSEC configuration options
+ */
+typedef struct odp_ipsec_config_t {
+       /** IPSEC operation mode. Application selects which mode (sync or async)
+        *  will be used for IPSEC operations.
+        *
+        *  @see odp_ipsec_in(), odp_ipsec_in_enq()
+        */
+       odp_ipsec_op_mode_t op_mode;
+
+} odp_ipsec_config_t;
+
+/**
+ * IPSEC SA direction
+ */
+typedef enum odp_ipsec_dir_t {
+       /** Inbound IPSEC SA */
+       ODP_IPSEC_DIR_INBOUND = 0,
+
+       /** Outbound IPSEC SA */
+       ODP_IPSEC_DIR_OUTBOUND
+
+} odp_ipsec_dir_t;
+
+/**
+ * IPSEC protocol mode
+ */
+typedef enum odp_ipsec_mode_t {
+       /** IPSEC tunnel mode */
+       ODP_IPSEC_MODE_TUNNEL = 0,
+
+       /** IPSEC transport mode */
+       ODP_IPSEC_MODE_TRANSPORT
+
+} odp_ipsec_mode_t;
+
+/**
+ * IPSEC protocol
+ */
+typedef enum odp_ipsec_protocol_t {
+       /** ESP protocol */
+       ODP_IPSEC_ESP = 0,
+
+       /** AH protocol */
+       ODP_IPSEC_AH
+
+} odp_ipsec_protocol_t;
+
+/**
+ * IPSEC tunnel type
+ */
+typedef enum odp_ipsec_tunnel_type_t {
+       /** Outer header is IPv4 */
+       ODP_IPSEC_TUNNEL_IPV4 = 0,
+
+       /** Outer header is IPv6 */
+       ODP_IPSEC_TUNNEL_IPV6
+
+} odp_ipsec_tunnel_type_t;
+
+/**
+ * IPSEC crypto parameters
+ */
+typedef struct odp_ipsec_crypto_param_t {
+       /** Cipher algorithm */
+       odp_cipher_alg_t cipher_alg;
+
+       /** Cipher key */
+       odp_crypto_key_t cipher_key;
+
+       /** Authentication algorithm */
+       odp_auth_alg_t auth_alg;
+
+       /** Authentication key */
+       odp_crypto_key_t auth_key;
+
+} odp_ipsec_crypto_param_t;
+
+/**
+ * IPSEC tunnel parameters
+ *
+ * These parameters are used to build outbound tunnel headers. All values are
+ * passed in CPU native byte / bit order if not specified otherwise.
+ * IP addresses must be in NETWORK byte order as those are passed in with
+ * pointers and copied byte-by-byte from memory to the packet.
+ */
+typedef struct odp_ipsec_tunnel_param_t {
+       /** Tunnel type: IPv4 or IPv6 */
+       odp_ipsec_tunnel_type_t type;
+
+       union {
+               /** IPv4 header parameters */
+               struct {
+                       /** IPv4 source address (NETWORK ENDIAN) */
+                       void *src_addr;
+
+                       /** IPv4 destination address (NETWORK ENDIAN) */
+                       void *dst_addr;
+
+                       /** IPv4 Differentiated Services Code Point */
+                       uint8_t dscp;
+
+                       /** IPv4 Don't Fragment bit */
+                       uint8_t df;
+
+                       /** IPv4 Time To Live */
+                       uint8_t ttl;
+               } ipv4;
+
+               /** IPv6 header parameters */
+               struct {
+                       /** IPv6 source address (NETWORK ENDIAN) */
+                       void *src_addr;
+
+                       /** IPv6 destination address (NETWORK ENDIAN) */
+                       void *dst_addr;
+
+                       /** IPv6 Differentiated Services Code Point */
+                       uint8_t dscp;
+
+                       /** IPv6 flow label */
+                       uint32_t flabel;
+
+                       /** IPv6 hop limit */
+                       uint8_t hlimit;
+               } ipv6;
+       };
+} odp_ipsec_tunnel_param_t;
+
+/**
+ * IPSEC SA option flags
+ */
+typedef struct odp_ipsec_sa_opt_t {
+       /** Extended Sequence Numbers (ESN)
+         *
+         * * 1: Use extended (64 bit) sequence numbers
+         * * 0: Use normal sequence numbers
+         */
+       uint32_t esn : 1;
+
+       /** UDP encapsulation
+         *
+         * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
+         *      traverse through NAT boxes.
+         * * 0: No UDP encapsulation
+         */
+       uint32_t udp_encap : 1;
+
+       /** Copy DSCP bits
+         *
+         * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
+         *      the outer IP header in encapsulation, and vice versa in
+         *      decapsulation.
+         * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
+         *      do not change DSCP field in decapsulation.
+         */
+       uint32_t copy_dscp : 1;
+
+       /** Copy IPv6 Flow Label
+         *
+         * * 1: Copy IPv6 flow label from inner IPv6 header to the
+         *      outer IPv6 header.
+         * * 0: Use value from odp_ipsec_tunnel_param_t
+         */
+       uint32_t copy_flabel : 1;
+
+       /** Copy IPv4 Don't Fragment bit
+         *
+         * * 1: Copy the DF bit from the inner IPv4 header to the outer
+         *      IPv4 header.
+         * * 0: Use value from odp_ipsec_tunnel_param_t
+         */
+       uint32_t copy_df : 1;
+
+       /** Decrement inner packet Time To Live (TTL) field
+         *
+         * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
+         *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
+         *      encapsulation.
+         * * 0: Inner packet is not modified.
+         */
+       uint32_t dec_ttl : 1;
+
+} odp_ipsec_sa_opt_t;
+
+/**
+ * IPSEC SA lifetime limits
+ *
+ * These limits are used for setting up SA lifetime. IPSEC operations check
+ * against the limits and output a status code (e.g. soft_exp_bytes) when
+ * a limit is crossed. Any number of limits may be used simultaneously.
+ * Use zero when there is no limit.
+ */
+typedef struct odp_ipsec_lifetime_t {
+       /** Soft expiry limits for the session */
+       struct {
+               /** Limit in seconds from the SA creation */
+               uint64_t sec;
+
+               /** Limit in bytes */
+               uint64_t bytes;
+
+               /** Limit in packet */
+               uint64_t packets;
+       } soft_limit;
+
+       /** Hard expiry limits for the session */
+       struct {
+               /** Limit in seconds from the SA creation */
+               uint64_t sec;
+
+               /** Limit in bytes */
+               uint64_t bytes;
+
+               /** Limit in packet */
+               uint64_t packets;
+       } hard_limit;
+} odp_ipsec_lifetime_t;
+
+/**
+ * Fragmentation mode
+ *
+ * These options control outbound IP packet fragmentation offload. When offload
+ * is enabled, IPSEC operation will determine if fragmentation is needed and
+ * does it according to the mode.
+ */
+typedef enum odp_ipsec_frag_mode_t {
+       /** Do not fragment IP packets */
+       ODP_IPSEC_FRAG_DISABLED = 0,
+
+       /** Fragment IP packet before IPSEC operation */
+       ODP_IPSEC_FRAG_BEFORE,
+
+       /** Fragment IP packet after IPSEC operation */
+       ODP_IPSEC_FRAG_AFTER,
+
+       /** Only check if IP fragmentation is needed,
+         * do not fragment packets. */
+       ODP_IPSEC_FRAG_CHECK
+} odp_ipsec_frag_mode_t;
+
+/**
+ * Packet lookup mode
+ */
+typedef enum odp_ipsec_lookup_mode_t {
+       /** Inbound SA lookup is disabled. */
+       ODP_IPSEC_LOOKUP_DISABLED = 0,
+
+       /** Inbound SA lookup is enabled. Used SPI values must be unique. */
+       ODP_IPSEC_LOOKUP_IN_UNIQUE_SA
+
+} odp_ipsec_lookup_mode_t;
+
+/**
+ * IPSEC Security Association (SA) parameters
+ */
+typedef struct odp_ipsec_sa_param_t {
+       /** IPSEC SA direction: inbound or outbound */
+       odp_ipsec_dir_t dir;
+
+       /** IPSEC protocol: ESP or AH */
+       odp_ipsec_protocol_t proto;
+
+       /** IPSEC protocol mode: transport or tunnel */
+       odp_ipsec_mode_t mode;
+
+       /** Parameters for crypto and authentication algorithms */
+       odp_ipsec_crypto_param_t crypto;
+
+       /** Parameters for tunnel mode */
+       odp_ipsec_tunnel_param_t tunnel;
+
+       /** Fragmentation mode */
+       odp_ipsec_frag_mode_t frag_mode;
+
+       /** Various SA option flags */
+       odp_ipsec_sa_opt_t opt;
+
+       /** SA lifetime parameters */
+       odp_ipsec_lifetime_t lifetime;
+
+       /** SA lookup mode */
+       odp_ipsec_lookup_mode_t lookup_mode;
+
+       /** Minimum anti-replay window size. Use 0 to disable anti-replay
+         * service. */
+       uint32_t antireplay_ws;
+
+       /** Initial sequence number */
+       uint64_t seq;
+
+       /** SPI value */
+       uint32_t spi;
+
+       /** MTU for outbound IP fragmentation offload
+        *
+        *  This is the maximum length of IP packets that outbound IPSEC
+        *  operations may produce. The value may be updated later with
+        *  odp_ipsec_mtu_update().
+        */
+       uint32_t mtu;
+
+       /** Destination queue for IPSEC events
+        *
+        *  Operations in asynchronous mode enqueue resulting events into
+        *  this queue.
+        */
+       odp_queue_t dest_queue;
+
+       /** User defined SA context pointer
+        *
+        *  User defined context pointer associated with the SA.
+        *  The implementation may prefetch the context data. Default value
+        *  of the pointer is NULL.
+        */
+       void *context;
+
+       /** Context data length
+        *
+        *  User defined context data length in bytes for prefetching.
+        *  The implementation may use this value as a hint for the number of
+        *  context data bytes to prefetch. Default value is zero (no hint).
+        */
+       uint32_t context_len;
+
+} odp_ipsec_sa_param_t;
+
+/**
+ * Query IPSEC capabilities
+ *
+ * Outputs IPSEC capabilities on success.
+ *
+ * @param[out] capa   Pointer to capability structure for output
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_ipsec_capability(odp_ipsec_capability_t *capa);
+
+/**
+ * Initialize IPSEC configuration options
+ *
+ * Initialize an odp_ipsec_config_t to its default values.
+ *
+ * @param[out] config  Pointer to IPSEC configuration structure
+ */
+void odp_ipsec_config_init(odp_ipsec_config_t *config);
+
+/**
+ * Global IPSEC configuration
+ *
+ * Initialize and configure IPSEC offload with global configuration options.
+ * This must be called before any SAs are created. Use odp_ipsec_capability()
+ * to examine which features and modes are supported.
+ *
+ * @param config   Pointer to IPSEC configuration structure
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_ipsec_capability(), odp_ipsec_config_init()
+ */
+int odp_ipsec_config(const odp_ipsec_config_t *config);
+
+/**
+ * Initialize IPSEC SA parameters
+ *
+ * Initialize an odp_ipsec_sa_param_t to its default values for all fields.
+ *
+ * @param param   Pointer to the parameter structure
+ */
+void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param);
+
+/**
+ * Create IPSEC SA
+ *
+ * Create a new IPSEC SA according to the parameters.
+ *
+ * @param param   IPSEC SA parameters
+ *
+ * @return IPSEC SA handle
+ * @retval ODP_IPSEC_SA_INVALID on failure
+ *
+ * @see odp_ipsec_sa_param_init()
+ */
+odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param);
+
+/**
+ * Destroy IPSEC SA
+ *
+ * Destroy an unused IPSEC SA. Result is undefined if the SA is being used
+ * (i.e. asynchronous operation is in progress).
+ *
+ * @param sa      IPSEC SA to be destroyed
+ *
+ * @retval 0      On success
+ * @retval <0     On failure
+ *
+ * @see odp_ipsec_sa_create()
+ */
+int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa);
+
+/**
+ * Printable format of odp_ipsec_sa_t
+ *
+ * @param sa      IPSEC SA handle
+ *
+ * @return uint64_t value that can be used to print/display this handle
+ */
+uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa);
+
+/**
+ * IPSEC operation level options
+ *
+ * These may be used to override some SA level options
+ */
+typedef struct odp_ipsec_op_opt_t {
+       /** Fragmentation mode */
+       odp_ipsec_frag_mode_t mode;
+
+} odp_ipsec_op_opt_t;
+
+/** IPSEC operation status has no errors */
+#define ODP_IPSEC_OK 0
+
+/** IPSEC operation status */
+typedef union odp_ipsec_status_t {
+       /** Error flags */
+       struct {
+               /** Protocol error. Not a valid ESP or AH packet. */
+               uint32_t proto            : 1;
+
+               /** SA lookup failed */
+               uint32_t sa_lookup        : 1;
+
+               /** Authentication failed */
+               uint32_t auth             : 1;
+
+               /** Anti-replay check failed */
+               uint32_t antireplay       : 1;
+
+               /** Other algorithm error */
+               uint32_t alg              : 1;
+
+               /** Packet does not fit into the given MTU size */
+               uint32_t mtu              : 1;
+
+               /** Soft lifetime expired: seconds */
+               uint32_t soft_exp_sec     : 1;
+
+               /** Soft lifetime expired: bytes */
+               uint32_t soft_exp_bytes   : 1;
+
+               /** Soft lifetime expired: packets */
+               uint32_t soft_exp_packets : 1;
+
+               /** Hard lifetime expired: seconds */
+               uint32_t hard_exp_sec     : 1;
+
+               /** Hard lifetime expired: bytes */
+               uint32_t hard_exp_bytes   : 1;
+
+               /** Hard lifetime expired: packets */
+               uint32_t hard_exp_packets : 1;
+       } error;
+
+       /** All bits of the bit field structure
+         *
+         * This field can be used to set, clear or compare multiple flags.
+         * For example, 'status.all != ODP_IPSEC_OK' checks if there are any
+         * errors.
+         */
+       uint32_t all;
+
+} odp_ipsec_status_t;
+
+/**
+ * IPSEC operation input parameters
+ */
+typedef struct odp_ipsec_op_param_t {
+       /** Number of packets to be processed */
+       int num_pkt;
+
+       /** Number of SAs
+        *
+        *  Valid values are:
+        *  * 0:       No SAs (default)
+        *  * 1:       Single SA for all packets
+        *  * num_pkt: SA per packet
+        */
+       int num_sa;
+
+       /** Number of operation options
+        *
+        *  Valid values are:
+        *  * 0:       No options (default)
+        *  * 1:       Single option for all packets
+        *  * num_pkt: An option per packet
+        */
+       int num_opt;
+
+       /** Pointer to an array of packets
+        *
+        *  Each packet must have a valid value for these meta-data:
+        *  * L3 offset: Offset to the first byte of the (outmost) IP header
+        *  * L4 offset: For inbound direction, when udp_encap is enabled -
+        *               offset to the first byte of the encapsulating UDP
+        *               header
+        *
+        *  @see odp_packet_l3_offset(), odp_packet_l4_offset()
+        */
+       odp_packet_t *pkt;
+
+       /** Pointer to an array of IPSEC SAs
+        *
+        *  May be NULL when num_sa is zero.
+        */
+       odp_ipsec_sa_t *sa;
+
+       /** Pointer to an array of operation options
+        *
+        *  May be NULL when num_opt is zero.
+        */
+       odp_ipsec_op_opt_t *opt;
+
+} odp_ipsec_op_param_t;
+
+/**
+ * IPSEC operation result for a packet
+ */
+typedef struct odp_ipsec_packet_result_t {
+       /** IPSEC operation status */
+       odp_ipsec_status_t status;
+
+       /** Number of output packets created from the corresponding input packet
+        *
+        *  Without fragmentation offload this is always one. However, if the
+        *  input packet was fragmented during the operation this is larger than
+        *  one for the first fragment and zero for the rest of the fragments
+        *  (following the first one in the 'pkt' array).
+        */
+       int num_out;
+
+       /** IPSEC SA that was used to create the packet
+        *
+        *  Operation updates this SA handle value, when SA look up is performed
+        *  as part of the operation and the look up is successful. Operation
+        *  status code indicates if the look up failed. Otherwise, the SA
+        *  provided by the application is copied here.
+        */
+       odp_ipsec_sa_t sa;
+
+} odp_ipsec_packet_result_t;
+
+/**
+ * IPSEC operation results
+ */
+typedef struct odp_ipsec_op_result_t {
+       /** Number of packets
+        *
+        *  Application sets this to the maximum number of packets the operation
+        *  may output (number of elements in 'pkt' and 'res' arrays).
+        *  The operation updates it with the actual number of packets
+        *  outputted.
+        */
+       int num_pkt;
+
+       /** Pointer to an array of packets
+        *
+        *  Operation outputs packets into this array. The array must have
+        *  at least 'num_pkt' elements.
+        *
+        *  Each successfully transformed packet has a valid value for these
+        *  meta-data:
+        *  * L3 offset: Offset to the first byte of the (outmost) IP header
+        *  * L4 offset: Offset to the first byte of the valid and known L4
+        *               header (immediately following the IP header).
+        *  * Various flags about L3 and L4 layers:
+        *               has_l3, has_l4, has_ipv4, has_ipv6, has_ipfrag,
+        *               has_ipsec, has_udp, has_tcp, etc depending on
+        *               the resulted packet format
+        *
+        * @see odp_packet_l3_offset(), odp_packet_l4_offset(),
+        *      odp_packet_has_ipv4(), odp_packet_has_ipv6(),
+        *      odp_packet_has_ipfrag(), odp_packet_has_ipsec()
+        *
+        * @note The amount and content of packet data before the IP header is
+        *       implementation specific.
+        */
+       odp_packet_t *pkt;
+
+       /** Pointer to an array of per packet operation results
+        *
+        *  Operation outputs results for each outputted packet into this array.
+        *  The array must have at least 'num_pkt' elements. The results include
+        *  operation status and packet form information for each outputted
+        *  packet.
+        *
+        *  For example, some packets may not have been transformed due to
+        *  an error, but the original packet is returned with appropriate
+        *  packet result information instead.
+        */
+       odp_ipsec_packet_result_t *res;
+
+} odp_ipsec_op_result_t;
+
+/**
+ * Inbound synchronous IPSEC operation
+ *
+ * This operation does inbound IPSEC processing in synchronous mode
+ * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of
+ * packets consumed and outputs a new packet handle as well as an operation
+ * result for each outputted packet. The operation does not modify packets that
+ * it does not consume. It cannot consume all input packets if 'output.num_pkt'
+ * is smaller than 'input.num_pkt'.
+ *
+ * Packet context pointer and user area content are copied from input to output
+ * packets. Output packets are allocated from the same pool(s) as input 
packets.
+ *
+ * When 'input.num_sa' is zero, this operation performs SA look up for each
+ * packet. Otherwise, application must provide the SA(s) as part of operation
+ * input parameters (odp_ipsec_op_param_t). The operation outputs used SA(s) as
+ * part of per packet operation results (odp_ipsec_packet_result_t), or an 
error
+ * status if a SA was not found.
+ *
+ * Packets are processed in the input order. Packet order is maintained from
+ * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed
+ * between calling threads.
+ *
+ * @param         input   Operation input parameters
+ * @param[out]    output  Operation results
+ *
+ * @return Number of input packets consumed (0 ... input.num_pkt)
+ * @retval <0     On failure
+ *
+ * @see odp_packet_user_ptr(), odp_packet_user_area()
+ */
+int odp_ipsec_in(const odp_ipsec_op_param_t *input,
+                odp_ipsec_op_result_t *output);
+
+/**
+ * Outbound synchronous IPSEC operation
+ *
+ * This operation does outbound IPSEC processing in synchronous mode
+ * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of
+ * packets consumed and outputs a new packet handle as well as an operation
+ * result for each outputted packet. The operation does not modify packets that
+ * it does not consume. It cannot consume all input packets if 'output.num_pkt'
+ * is smaller than 'input.num_pkt'.
+ *
+ * Packet context pointer and user area content are copied from input to output
+ * packets. Output packets are allocated from the same pool(s) as input 
packets.
+ *
+ * When outbound IP fragmentation offload is enabled, the number of outputted
+ * packets (and corresponding per packet results) may be greater than
+ * the number of input packets. In that case, application may examine 'num_out'
+ * of each packet result (odp_ipsec_packet_result_t) to find out which
+ * fragments are originated from which input packet.
+ *
+ * Packets are processed in the input order. Packet order is maintained from
+ * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed
+ * between calling threads.
+ *
+ * @param         input   Operation input parameters
+ * @param[out]    output  Operation results
+ *
+ * @return Number of input packets consumed (0 ... input.num_pkt)
+ * @retval <0     On failure
+ *
+ * @see odp_packet_user_ptr(), odp_packet_user_area()
+ */
+int odp_ipsec_out(const odp_ipsec_op_param_t *input,
+                 odp_ipsec_op_result_t *output);
+
+/**
+ * Inbound asynchronous IPSEC operation
+ *
+ * This operation does inbound IPSEC processing in asynchronous mode
+ * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to
+ * odp_ipsec_in(), but outputs all results through one or more
+ * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations.
+ *
+ * Asynchronous mode maintains (operation input) packet order per SA when
+ * application calls the operation within an ordered or atomic scheduler 
context
+ * of the same queue. Packet order is also maintained when application
+ * otherwise guarantees (e.g. using locks) that the operation is not called
+ * simultaneously from multiple threads for the same SA(s). Resulting
+ * events for the same SA are enqueued in order, and packet handles (for the
+ * same SA) are stored in order within an event.
+ *
+ * @param         input   Operation input parameters
+ *
+ * @return Number of input packets consumed (0 ... input.num_pkt)
+ * @retval <0     On failure
+ *
+ * @see odp_ipsec_in(), odp_ipsec_result()
+ */
+int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input);
+
+/**
+ * Outbound asynchronous IPSEC operation
+ *
+ * This operation does outbound IPSEC processing in asynchronous mode
+ * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to
+ * odp_ipsec_out(), but outputs all results through one or more
+ * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations.
+ *
+ * Asynchronous mode maintains (operation input) packet order per SA when
+ * application calls the operation within an ordered or atomic scheduler 
context
+ * of the same queue. Packet order is also maintained when application
+ * otherwise guarantees (e.g. using locks) that the operation is not called
+ * simultaneously from multiple threads for the same SA(s). Resulting
+ * events for the same SA are enqueued in order, and packet handles (for the
+ * same SA) are stored in order within an event.
+ *
+ * @param         input   Operation input parameters
+ *
+ * @return Number of input packets consumed (0 ... input.num_pkt)
+ * @retval <0     On failure
+ *
+ * @see odp_ipsec_out(), odp_ipsec_result()
+ */
+int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input);
+
+/**
+ * Get IPSEC results from an ODP_EVENT_IPSEC_RESULT event
+ *
+ * Copies IPSEC operation results from an event. The event must be of
+ * type ODP_EVENT_IPSEC_RESULT. It must be freed before the application passes
+ * any resulting packet handles to other ODP calls.
+ *
+ * @param[out]    result  Pointer to operation result for output. Maybe NULL, 
if
+ *                        application is interested only on the number of
+ *                        packets.
+ * @param         event   An ODP_EVENT_IPSEC_RESULT event
+ *
+ * @return Number of packets in the event. If this is larger than
+ *         'result.num_pkt', all packets did not fit into result struct and
+ *         application must call the function again with a larger result 
struct.
+ * @retval <0     On failure
+ *
+ * @see odp_ipsec_in_enq(), odp_ipsec_out_enq()
+ */
+int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event);
+
+/**
+ * Update MTU for outbound IP fragmentation
+ *
+ * When IP fragmentation offload is enabled, the SA is created with an MTU.
+ * This call may be used to update MTU at any time. MTU updates are not
+ * expected to happen very frequently.
+ *
+ * @param sa      IPSEC SA to be updated
+ * @param mtu     The new MTU value
+ *
+ * @retval 0      On success
+ * @retval <0     On failure
+ */
+int odp_ipsec_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu);
+
+/**
+ * Get user defined SA context pointer
+ *
+ * @param sa      IPSEC SA handle
+ *
+ * @return User defined SA context pointer value
+ * @retval NULL   On failure
+ */
+void *odp_ipsec_sa_context(odp_ipsec_sa_t sa);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <odp/visibility_end.h>
+#endif
diff --git a/include/odp_api.h b/include/odp_api.h
index ec7fcd2..73e5309 100644
--- a/include/odp_api.h
+++ b/include/odp_api.h
@@ -57,6 +57,7 @@ extern "C" {
  #include <odp/api/spinlock_recursive.h>
  #include <odp/api/rwlock_recursive.h>
  #include <odp/api/std_clib.h>
+#include <odp/api/ipsec.h>
#ifdef __cplusplus
  }
diff --git a/platform/Makefile.inc b/platform/Makefile.inc
index b31b95b..aefbf9a 100644
--- a/platform/Makefile.inc
+++ b/platform/Makefile.inc
@@ -34,6 +34,7 @@ odpapispecinclude_HEADERS = \
                  $(top_srcdir)/include/odp/api/spec/hash.h \
                  $(top_srcdir)/include/odp/api/spec/hints.h \
                  $(top_srcdir)/include/odp/api/spec/init.h \
+                 $(top_srcdir)/include/odp/api/spec/ipsec.h \
                  $(top_srcdir)/include/odp/api/spec/packet.h \
                  $(top_srcdir)/include/odp/api/spec/packet_flags.h \
                  $(top_srcdir)/include/odp/api/spec/packet_io.h \
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index b60eacb..9c4758d 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -37,6 +37,7 @@ odpapiinclude_HEADERS = \
                  $(srcdir)/include/odp/api/hash.h \
                  $(srcdir)/include/odp/api/hints.h \
                  $(srcdir)/include/odp/api/init.h \
+                 $(srcdir)/include/odp/api/ipsec.h \
                  $(srcdir)/include/odp/api/packet_flags.h \
                  $(srcdir)/include/odp/api/packet.h \
                  $(srcdir)/include/odp/api/packet_io.h \
@@ -78,6 +79,7 @@ odpapiplatinclude_HEADERS = \
                  $(srcdir)/include/odp/api/plat/crypto_types.h \
                  $(srcdir)/include/odp/api/plat/event_types.h \
                  $(srcdir)/include/odp/api/plat/init_types.h \
+                 $(srcdir)/include/odp/api/plat/ipsec_types.h \
                  $(srcdir)/include/odp/api/plat/packet_types.h \
                  $(srcdir)/include/odp/api/plat/packet_io_types.h \
                  $(srcdir)/include/odp/api/plat/pool_types.h \
diff --git a/platform/linux-generic/include/odp/api/ipsec.h 
b/platform/linux-generic/include/odp/api/ipsec.h
new file mode 100644
index 0000000..44c5d02
--- /dev/null
+++ b/platform/linux-generic/include/odp/api/ipsec.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP IPSEC API - platform specific header
+ */
+
+#ifndef ODP_PLAT_IPSEC_H_
+#define ODP_PLAT_IPSEC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/plat/ipsec_types.h>
+
+/** @ingroup odp_ipsec
+ *  @{
+ */
+
+/**
+ * @}
+ */
+
+#include <odp/api/spec/ipsec.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h 
b/platform/linux-generic/include/odp/api/plat/event_types.h
index 9ca0fb8..abaa770 100644
--- a/platform/linux-generic/include/odp/api/plat/event_types.h
+++ b/platform/linux-generic/include/odp/api/plat/event_types.h
@@ -38,6 +38,7 @@ typedef enum odp_event_type_t {
        ODP_EVENT_PACKET       = 2,
        ODP_EVENT_TIMEOUT      = 3,
        ODP_EVENT_CRYPTO_COMPL = 4,
+       ODP_EVENT_IPSEC_RESULT = 5
  } odp_event_type_t;
/** Get printable format of odp_event_t */
diff --git a/platform/linux-generic/include/odp/api/plat/ipsec_types.h 
b/platform/linux-generic/include/odp/api/plat/ipsec_types.h
new file mode 100644
index 0000000..a36cdad
--- /dev/null
+++ b/platform/linux-generic/include/odp/api/plat/ipsec_types.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP IPSEC API - platform specific types
+ */
+
+#ifndef ODP_PLAT_IPSEC_TYPES_H_
+#define ODP_PLAT_IPSEC_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/std_types.h>
+#include <odp/api/plat/strong_types.h>
+
+/** @ingroup odp_ipsec
+ *  @{
+ */
+
+typedef ODP_HANDLE_T(odp_ipsec_sa_t);
+
+#define ODP_IPSEC_SA_INVALID _odp_cast_scalar(odp_ipsec_sa_t, 0xffffffff)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Reply via email to