On Wed, Mar 22, 2017 at 6:37 AM, Peltonen, Janne (Nokia - FI/Espoo) < janne.pelto...@nokia.com> wrote:
> Hi, > > > > + > > > + /** Outer headers for inline output operation > > > + * > > > + * Outbound inline IPSEC operation uses this information to > > > prepend > > > + * outer headers to the IPSEC packet before sending it out. > > > + */ > > > + struct { > > > + /** Points to first byte of outer headers to be copied > in > > > + * front of the outgoing IPSEC packet. Implementation > > > copies > > > + * the headers during odp_ipsec_out_inline() call. */ > > > + uint8_t *ptr; > > > > > > > Should this be an odp_packet_t rather than a raw set of bytes? The > > rationale for making this an odp_packet_t is that this could then be a > > packet reference which can be used for (re)transmit tracking. For input > > If it were odp_packet_t, the IPsec implementation would have to be > prepared for the data to be segmented in arbitrary ways, which probably > would not improve performance. And to me it is not really a packet anyway. > It's as much of a packet as the hdr passed to odp_packet_ref_pkt() to be prefixed to the created reference. An odp_packet_t is how we represent packets (complete and partial) in ODP, so it makes sense to be consistent here. We already have minimum segment sizes in the packet definition so I don't see this being a concern here any more than in any other ODP packet APIs. > > I did not quite understand the point about retransmit tracking in this > context. > One of the main use cases for references is to permit easy retransmit processing via constructs like: odp_pktout_send(outq, odp_packet_ref_static(pkt)); That allows the caller to hold onto a reference to the packet being transmitted both for retransmit purposes as well as to be able to determine that that transmit has been successful, indicated by odp_packet_has_ref(pkt) returning from 1 to 0. You can't really pass a reference to the IPsec routines since references have read-only payloads and IPsec is transforming the payload, however if you have a separate header that can be a reference since all you're asking is that this be prefixed to the result prior to transmission, so it would seem the same capabilities would result. > > One thing we already discussed with Petri is that to enable IP and UDP > based tunneling protocols (e.g. IPIP, GRE, VxLAN) outside the IPsec > packet in the inline output case, the right packet length would have > to be inserted in the right place of the added header. There is the > same issue with L2 protocols that would contain the total packet > length (e.g. some proprietary fabric encapsulation). In this case > the outer header is rather like a template. This is something to be > considered in some future versions of the API but one possible > way to accommodate some of these cases is to have an offset that > specifies which word of the complete packet shall be incremented > by the resulting packet size after IPsec encapsulation. > I agree this is a direction we want to go, but I'd want to see this done via a generalized tunnel acceleration set of APIs the permit general encapsulation/decapsulation services. Given the flexibility inherent in this sort of processing, I see this as one area where synergy with the P4 project is most promising. P4 excels at offering highly efficient descriptions of bit-level packet structures and manipulations that can be implemented in soft logic like FPGAs. The idea would be that the application would either select from a library of predefined P4 templates or be able to specify its own unique formats without requiring a new ODP API for every such variant. Something worth exploring. > > > having this be raw bytes makes sense since the ODP implementation is > > controlling their allocation and placement, however for output how is the > > application going to allocate these? Presumably it would create a header > > via odp_packet_alloc() and then use odp_packet_data() to get this > address, > > but that seems cumbersome compared to simply passing the odp_packet_t > > directly. The alternative would seem to require that the application use > > some sort of odp_shm_reserve() call, but that gets awkward and is far > less > > efficient than packet allocation, which is a fastpath operation. > > > > I do not think applications would dynamically allocate the storage for the > header (through packet alloc or shm alloc or whatever) for every packet > sent > but would just have the pointer point to a cached header somewhere (e.g. > ready-made L2 header cached in the next hop structure found by L3 route > search). If the header or part of it does have to be constructed on the > fly, the application can use the stack or other thread specific storage > that does not have to be allocated separately for every output operation. > Or maybe even some existing per-packet memory like the user area. > The user area would be safe, however the stack would not unless you're using purely synchronous calls, which is a limit I'd think we wouldn't want to impose on this feature. The user area, however, would still need per-packet initialization. The reason for leveraging the packet structure would be to permit references to these headers to be used as a cheap cloning mechanism that would leverage whatever HW packet manager structures are in place to support other packets. > > Btw, the API should make it clear if the header data can be in the headroom > or the user area of the packet being enqueued (I suppose the latter should > be fine). > It's dangerous to try to use headroom since that's essentially trying to make use of unallocated space. As far as the application is concerned, this space is unusable (or even non-existent) until after a successful odp_packet_push_head() call is made. > > Janne > > > > -----Original Message----- > > From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of > Bill Fischofer > > Sent: Wednesday, March 22, 2017 12:17 AM > > To: Petri Savolainen <petri.savolai...@linaro.org> > > Cc: lng-odp-forward <lng-odp@lists.linaro.org> > > Subject: Re: [lng-odp] [API-NEXT PATCH v2 2/3] api: ipsec: add inline > IPSEC support > > > > On Tue, Mar 21, 2017 at 9:17 AM, Petri Savolainen < > > petri.savolai...@linaro.org> wrote: > > > > > Added support for inline IPSEC processing on packet input and > > > output. Inline mode IPSEC and traffic manager cannot be enabled > > > (currently) on the same pktio interface. > > > > > > Signed-off-by: Petri Savolainen <petri.savolai...@linaro.org> > > > --- > > > include/odp/api/spec/ipsec.h | 348 ++++++++++++++++++++++++++++++ > > > ++++++--- > > > include/odp/api/spec/packet_io.h | 32 ++++ > > > 2 files changed, 355 insertions(+), 25 deletions(-) > > > > > > diff --git a/include/odp/api/spec/ipsec.h > b/include/odp/api/spec/ipsec.h > > > index e951e49..23d02cf 100644 > > > --- a/include/odp/api/spec/ipsec.h > > > +++ b/include/odp/api/spec/ipsec.h > > > @@ -19,6 +19,8 @@ extern "C" { > > > #endif > > > > > > #include <odp/api/crypto.h> > > > +#include <odp/api/packet_io.h> > > > +#include <odp/api/classification.h> > > > > > > /** @defgroup odp_ipsec ODP IPSEC > > > * Operations of IPSEC API. > > > @@ -51,11 +53,43 @@ typedef enum odp_ipsec_op_mode_t { > > > * Application uses asynchronous IPSEC operations, > > > * which return results via events. > > > */ > > > - ODP_IPSEC_OP_MODE_ASYNC > > > + ODP_IPSEC_OP_MODE_ASYNC, > > > + > > > + /** Inline IPSEC operation > > > + * > > > + * Packet input/output is connected directly to IPSEC > > > inbound/outbound > > > + * processing. Application uses asynchronous or inline IPSEC > > > + * operations. > > > + */ > > > + ODP_IPSEC_OP_MODE_INLINE, > > > + > > > + /** IPSEC is disabled in inbound / outbound direction */ > > > + ODP_IPSEC_OP_MODE_DISABLED > > > > > > } odp_ipsec_op_mode_t; > > > > > > /** > > > + * Protocol layers in IPSEC configuration > > > + */ > > > +typedef enum odp_ipsec_proto_layer_t { > > > + /** No layers */ > > > + ODP_IPSEC_LAYER_NONE = 0, > > > + > > > + /** Layer L2 protocols (Ethernet, VLAN, etc) */ > > > + ODP_IPSEC_LAYER_L2, > > > + > > > + /** Layer L3 protocols (IPv4, IPv6, ICMP, IPSec, etc) */ > > > > > > > Nit: Correct spelling is IPsec, not IPSec, per RFC 4301. > > > > > > > + ODP_IPSEC_LAYER_L3, > > > + > > > + /** Layer L4 protocols (UDP, TCP, SCTP) */ > > > + ODP_IPSEC_LAYER_L4, > > > + > > > + /** All layers */ > > > + ODP_IPSEC_LAYER_ALL > > > + > > > +} odp_ipsec_proto_layer_t; > > > + > > > +/** > > > * Configuration options for IPSEC inbound processing > > > */ > > > typedef struct odp_ipsec_inbound_config_t { > > > @@ -77,9 +111,113 @@ typedef struct odp_ipsec_inbound_config_t { > > > uint32_t max; > > > } spi; > > > > > > + /** Retain outer headers > > > + * > > > + * Select up to which protocol layer (at least) outer headers > are > > > + * retained in inbound inline processing. Default value is > > > + * ODP_IPSEC_LAYER_NONE. > > > + * > > > + * ODP_IPSEC_LAYER_NONE: Application does not require any > outer > > > + * headers to be retained. > > > + * > > > + * ODP_IPSEC_LAYER_L2: Retain headers up to layer 2. > > > + * > > > + * ODP_IPSEC_LAYER_L3: Retain headers up to layer 3, > otherwise > > > the > > > + * same as ODP_IPSEC_LAYER_ALL. > > > + * > > > + * ODP_IPSEC_LAYER_L4: Retain headers up to layer 4, > otherwise > > > the > > > + * same as ODP_IPSEC_LAYER_ALL. > > > + * > > > + * ODP_IPSEC_LAYER_ALL: In tunnel mode, all headers before > IPSEC > > > are > > > + * retained. In transport mode, all > headers > > > + * before IP (carrying IPSEC) are > retained. > > > + * > > > + */ > > > + odp_ipsec_proto_layer_t retain_outer; > > > + > > > + /** Parse packet headers in IPSEC payload > > > + * > > > + * Select header parsing level after inbound processing. > Packet > > > headers > > > + * in IPSEC payload must be parsed (at least) up to this > level. > > > + * Default value is ODP_IPSEC_LAYER_NONE. > > > + * > > > + * Note that IPSec payload is never a L2 packet > > > (ODP_IPSEC_LAYER_L2 > > > > > > > IPsec > > > > > > > + * equals ODP_IPSEC_LAYER_NONE). In transport mode, IPSEC > payload > > > + * starts after IP header (ODP_IPSEC_LAYER_L3 equals > > > + * ODP_IPSEC_LAYER_NONE). > > > + */ > > > + odp_ipsec_proto_layer_t parse; > > > + > > > + /** Flags to control IPSEC payload data checks up to the > selected > > > parse > > > + * level. */ > > > + union { > > > + struct { > > > + /** Check IPv4 header checksum in IPSEC > payload. > > > + * Default value is 0. */ > > > + uint32_t ipv4_chksum : 1; > > > + > > > + /** Check UDP checksum in IPSEC payload. > > > + * Default value is 0. */ > > > + uint32_t udp_chksum : 1; > > > + > > > + /** Check TCP checksum in IPSEC payload. > > > + * Default value is 0. */ > > > + uint32_t tcp_chksum : 1; > > > + > > > + /** Check SCTP checksum in IPSEC payload. > > > + * Default value is 0. */ > > > + uint32_t sctp_chksum : 1; > > > + } check; > > > + > > > + /** All bits of the bit field structure > > > + * > > > + * This field can be used to set/clear all flags, or > > > bitwise > > > + * operations over the entire structure. */ > > > + uint32_t all_check; > > > + }; > > > + > > > } odp_ipsec_inbound_config_t; > > > > > > /** > > > + * Configuration options for IPSEC outbound processing > > > + */ > > > +typedef struct odp_ipsec_outbound_config_t { > > > + /** Flags to control L3/L4 checksum insertion as part of > outbound > > > + * packet processing. Packet must have set with valid L3/L4 > > > offsets. > > > + * Checksum configuration is ignored for packets that checksum > > > cannot > > > + * be computed for (e.g. IPv4 fragments). Application may use > a > > > packet > > > + * metadata flag to disable checksum insertion per packet > bases. > > > + */ > > > + union { > > > + struct { > > > + /** Insert IPv4 header checksum on the payload > > > packet > > > + * before IPSEC transformation. Default value > is > > > 0. */ > > > + uint32_t inner_ipv4 : 1; > > > + > > > + /** Insert UDP header checksum on the payload > > > packet > > > + * before IPSEC transformation. Default value > is > > > 0. */ > > > + uint32_t inner_udp : 1; > > > + > > > + /** Insert TCP header checksum on the payload > > > packet > > > + * before IPSEC transformation. Default value > is > > > 0. */ > > > + uint32_t inner_tcp : 1; > > > + > > > + /** Insert SCTP header checksum on the payload > > > packet > > > + * before IPSEC transformation. Default value > is > > > 0. */ > > > + uint32_t inner_sctp : 1; > > > + > > > + } chksum; > > > + > > > + /** All bits of the bit field structure > > > + * > > > + * This field can be used to set/clear all flags, or > > > bitwise > > > + * operations over the entire structure. */ > > > + uint32_t all_chksum; > > > + }; > > > + > > > +} odp_ipsec_outbound_config_t; > > > + > > > +/** > > > * IPSEC capability > > > */ > > > typedef struct odp_ipsec_capability_t { > > > @@ -102,6 +240,24 @@ typedef struct odp_ipsec_capability_t { > > > */ > > > uint8_t op_mode_async; > > > > > > + /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) > support > > > + * > > > + * 0: Inline IPSEC operation is not supported > > > + * 1: Inline IPSEC operation is supported > > > + * 2: Inline IPSEC operation is supported and preferred > > > + */ > > > + uint8_t op_mode_inline; > > > + > > > + /** Support of inline classification (ODP_IPSEC_DEST_CLS) for > > > resulting > > > + * inbound packets. > > > + * > > > + * 0: Inline classification of resulting packets is not > supported > > > + * 1: Inline classification of resulting packets is supported > > > + * 2: Inline classification of resulting packets is supported > and > > > + * preferred > > > + */ > > > + uint8_t cls_inline; > > > + > > > /** Soft expiry limit in seconds support > > > * > > > * 0: Limit is not supported > > > @@ -128,12 +284,19 @@ typedef struct 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. > > > + /** Inbound IPSEC operation mode. Application selects which > mode > > > + * will be used for inbound IPSEC operations. > > > * > > > * @see odp_ipsec_in(), odp_ipsec_in_enq() > > > */ > > > - odp_ipsec_op_mode_t op_mode; > > > + odp_ipsec_op_mode_t inbound_mode; > > > + > > > + /** Outbound IPSEC operation mode. Application selects which > mode > > > + * will be used for outbound IPSEC operations. > > > + * > > > + * @see odp_ipsec_out(), odp_ipsec_out_enq(), > > > odp_ipsec_out_inline() > > > + */ > > > + odp_ipsec_op_mode_t outbound_mode; > > > > > > /** Maximum number of IPSEC SAs that application will use > > > * simultaneously */ > > > @@ -142,6 +305,9 @@ typedef struct odp_ipsec_config_t { > > > /** IPSEC inbound processing configuration */ > > > odp_ipsec_inbound_config_t inbound; > > > > > > + /** IPSEC outbound processing configuration */ > > > + odp_ipsec_outbound_config_t outbound; > > > + > > > } odp_ipsec_config_t; > > > > > > /** > > > @@ -381,11 +547,29 @@ typedef enum odp_ipsec_lookup_mode_t { > > > 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_IN_UNIQUE_SPI, > > > + > > > + /** Inbound SA lookup is enabled. Lookup matches both SPI and > > > + * destination IP address. Used SPI values must be unique. */ > > > + ODP_IPSEC_LOOKUP_IN_DSTADDR_UNIQUE_SPI > > > > > > } odp_ipsec_lookup_mode_t; > > > > > > /** > > > + * Result event destination > > > + */ > > > +typedef enum odp_ipsec_dest_mode_t { > > > + /** Destination for IPSEC result events is a queue. */ > > > + ODP_IPSEC_DEST_QUEUE = 0, > > > + > > > + /** Destination for IPSEC result events is the classifier. > > > + * IPSEC capability 'cls_inline' determines if inline > > > classification > > > + * is supported. */ > > > + ODP_IPSEC_DEST_CLS > > > + > > > +} odp_ipsec_dest_mode_t; > > > + > > > +/** > > > * IPSEC Security Association (SA) parameters > > > */ > > > typedef struct odp_ipsec_sa_param_t { > > > @@ -426,6 +610,17 @@ typedef struct odp_ipsec_sa_param_t { > > > /** SPI value */ > > > uint32_t spi; > > > > > > + /** Additional inbound SA lookup parameters. Values are > considered > > > + * only in ODP_IPSEC_LOOKUP_IN_DSTADDR_UNIQUE_SPI lookup > mode. */ > > > + struct { > > > + /* v4 or v6 */ > > > + uint8_t ip_version; > > > > > > > Is this an enum? If not perhaps doc this as 4 = IPv4, 6 = IPv6. > > > > > > > + > > > + /* IP destination address (NETWORK ENDIAN) */ > > > + void *dst_addr; > > > + > > > + } lookup_param; > > > + > > > /** MTU for outbound IP fragmentation offload > > > * > > > * This is the maximum length of IP packets that outbound > IPSEC > > > @@ -434,13 +629,32 @@ typedef struct odp_ipsec_sa_param_t { > > > */ > > > uint32_t mtu; > > > > > > + /** Select where IPSEC result events are sent > > > + * > > > + * Asynchronous and inline modes generate result events. > Select > > > where > > > + * those events are sent. Inbound SAs may choose between a > queue > > > or > > > + * the classifier. Outbound SAs must define a queue always. > > > + * The default value is ODP_IPSEC_DEST_QUEUE. > > > + */ > > > + odp_ipsec_dest_mode_t dest_mode; > > > + > > > /** Destination queue for IPSEC events > > > * > > > - * Operations in asynchronous mode enqueue resulting events > into > > > - * this queue. > > > + * Operations in asynchronous or inline mode enqueue resulting > > > events > > > + * into this queue. > > > */ > > > odp_queue_t dest_queue; > > > > > > + /** Classifier destination CoS for IPSEC result events > > > + * > > > + * Result events for successfully decapsulated packets are > sent to > > > + * classification through this CoS. Other result events are > sent > > > to > > > + * 'dest_queue'. This field is considered only when > 'dest_mode' is > > > + * ODP_IPSEC_DEST_CLS. The CoS must not be shared between any > > > pktio > > > + * interface default CoS. > > > + */ > > > + odp_cos_t dest_cos; > > > + > > > /** User defined SA context pointer > > > * > > > * User defined context pointer associated with the SA. > > > @@ -673,6 +887,18 @@ typedef struct odp_ipsec_op_status_t { > > > uint32_t all_error; > > > }; > > > > > > + union { > > > + /** Status flags */ > > > + struct { > > > + /** Packet was processed in inline mode */ > > > + uint32_t inline_mode : 1; > > > + > > > + } flag; > > > + > > > + /** All flag bits */ > > > + uint32_t all_flag; > > > + }; > > > + > > > } odp_ipsec_op_status_t; > > > > > > /** > > > @@ -727,6 +953,35 @@ typedef struct odp_ipsec_op_param_t { > > > } odp_ipsec_op_param_t; > > > > > > /** > > > + * Outbound inline IPSEC operation parameters > > > + */ > > > +typedef struct odp_ipsec_inline_op_param_t { > > > + /** Packet output interface for inline output operation > > > + * > > > + * Outbound inline IPSEC operation uses this packet IO > interface > > > to > > > + * output the packet after a successful IPSEC transformation. > The > > > pktio > > > + * must have been configured to operate in inline IPSEC mode. > > > + */ > > > + odp_pktio_t pktio; > > > > > > > Shouldn't we have an option for this to be output to an odp_tm_queue_t > > instead of a pktio? > > Also, for output are there any controls over which odp_pktout_queue_t is > > used, or is this undefined? > > > > > > > + > > > + /** Outer headers for inline output operation > > > + * > > > + * Outbound inline IPSEC operation uses this information to > > > prepend > > > + * outer headers to the IPSEC packet before sending it out. > > > + */ > > > + struct { > > > + /** Points to first byte of outer headers to be copied > in > > > + * front of the outgoing IPSEC packet. Implementation > > > copies > > > + * the headers during odp_ipsec_out_inline() call. */ > > > + uint8_t *ptr; > > > > > > > Should this be an odp_packet_t rather than a raw set of bytes? The > > rationale for making this an odp_packet_t is that this could then be a > > packet reference which can be used for (re)transmit tracking. For input > > having this be raw bytes makes sense since the ODP implementation is > > controlling their allocation and placement, however for output how is the > > application going to allocate these? Presumably it would create a header > > via odp_packet_alloc() and then use odp_packet_data() to get this > address, > > but that seems cumbersome compared to simply passing the odp_packet_t > > directly. The alternative would seem to require that the application use > > some sort of odp_shm_reserve() call, but that gets awkward and is far > less > > efficient than packet allocation, which is a fastpath operation. > > > > > > > + > > > + /** Outer header length in bytes */ > > > + uint32_t len; > > > + } outer_hdr; > > > + > > > +} odp_ipsec_inline_op_param_t; > > > + > > > +/** > > > * IPSEC operation result for a packet > > > */ > > > typedef struct odp_ipsec_packet_result_t { > > > @@ -752,6 +1007,23 @@ typedef struct odp_ipsec_packet_result_t { > > > */ > > > odp_ipsec_sa_t sa; > > > > > > + /** Packet outer header status before inbound inline > processing. > > > + * This is valid only when status.flag.inline_mode is set. > > > + */ > > > + struct { > > > + /** Points to the first byte of retained outer headers. > > > These > > > + * headers are stored in a contiquous, per packet, > > > + * implementation specific memory space. Since the > memory > > > space > > > + * may overlap with e.g. packet head/tailroom, the > content > > > + * becomes invalid if packet data storage is modified > in > > > + * anyway. The memory space may not be sharable to > other > > > + * threads. */ > > > + uint8_t *ptr; > > > + > > > + /** Outer header length in bytes */ > > > + uint32_t len; > > > + } outer_hdr; > > > + > > > } odp_ipsec_packet_result_t; > > > > > > /** > > > @@ -773,18 +1045,14 @@ typedef struct odp_ipsec_op_result_t { > > > * at least 'num_pkt' elements. > > > * > > > * Each successfully transformed packet has a valid value for > > > these > > > - * meta-data: > > > + * meta-data regardless of the inner packet parse > configuration. > > > > > > > Vestigial typo. It's metadata, not meta-data. Might as well clean up > here. > > > > > > > + * (odp_ipsec_inbound_config_t): > > > * * 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 > > > + * * pktio: For inbound inline IPSEC processed packets, > > > original > > > + * packet input interface > > > * > > > - * @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() > > > + * Other meta-data for parse results and error checks depend > on > > > + * configuration (selected parse and error check levels). > > > */ > > > odp_packet_t *pkt; > > > > > > @@ -915,10 +1183,10 @@ int odp_ipsec_out(const odp_ipsec_op_param_t > *input, > > > /** > > > * 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. > > > + * This operation does inbound IPSEC processing in asynchronous mode. > 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 > > > @@ -928,6 +1196,11 @@ int odp_ipsec_out(const odp_ipsec_op_param_t > *input, > > > * events for the same SA are enqueued in order, and packet handles > (for > > > the > > > * same SA) are stored in order within an event. > > > * > > > + * The function may be used also in inline processing mode, e.g. for > IPSEC > > > + * packets for which inline processing is not possible. Packets for > the > > > same SA > > > + * may be processed simultaneously in both modes (initiated by this > > > function > > > + * and inline operation). > > > + * > > > * @param input Operation input parameters > > > * > > > * @return Number of input packets consumed (0 ... input.num_pkt) > > > @@ -940,10 +1213,10 @@ 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. > > > + * This operation does outbound IPSEC processing in asynchronous > mode. 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 > > > @@ -953,6 +1226,9 @@ int odp_ipsec_in_enq(const odp_ipsec_op_param_t > > > *input); > > > * events for the same SA are enqueued in order, and packet handles > (for > > > the > > > * same SA) are stored in order within an event. > > > * > > > + * The function may be used also in inline processing mode, e.g. for > IPSEC > > > + * packets for which inline processing is not possible. > > > + * > > > * @param input Operation input parameters > > > * > > > * @return Number of input packets consumed (0 ... input.num_pkt) > > > @@ -963,6 +1239,28 @@ int odp_ipsec_in_enq(const odp_ipsec_op_param_t > > > *input); > > > int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input); > > > > > > /** > > > + * Outbound inline IPSEC operation > > > + * > > > + * This operation does outbound inline IPSEC processing for the > packets. > > > It's > > > + * otherwise identical to odp_ipsec_out_enq(), but outputs all > > > successfully > > > + * transformed packets to the specified output interface, instead of > > > generating > > > + * result events for those. > > > + * > > > + * Inline operation parameters are defined per packet. The array of > > > parameters > > > + * must have 'op_param.num_pkt' elements and is pointed to by > > > 'inline_param'. > > > + * > > > + * @param op_param Operation parameters > > > + * @param inline_param Outbound inline operation specific > > > parameters > > > + * > > > + * @return Number of packets consumed (0 ... op_param.num_pkt) > > > + * @retval <0 On failure > > > + * > > > + * @see odp_ipsec_out_enq() > > > + */ > > > +int odp_ipsec_out_inline(const odp_ipsec_op_param_t *op_param, > > > + const odp_ipsec_inline_op_param_t > *inline_param); > > > + > > > +/** > > > * Get IPSEC results from an ODP_EVENT_IPSEC_RESULT event > > > * > > > * Copies IPSEC operation results from an event. The event must be of > > > diff --git a/include/odp/api/spec/packet_io.h > > > b/include/odp/api/spec/packet_io.h > > > index cec1f22..8802089 100644 > > > --- a/include/odp/api/spec/packet_io.h > > > +++ b/include/odp/api/spec/packet_io.h > > > @@ -407,6 +407,38 @@ typedef struct odp_pktio_config_t { > > > * interface capability before enabling the same. */ > > > odp_bool_t enable_loop; > > > > > > + /** Inbound IPSEC inlined with packet input > > > + * > > > + * Enable/disable inline inbound IPSEC operation. When enabled > > > packet > > > + * input directs all IPSEC packets automatically to IPSEC > inbound > > > + * processing. IPSEC configuration is done through the IPSEC > API. > > > + * Packets that are not (recognized as) IPSEC are processed > > > + * according to the packet input configuration. > > > + * > > > + * 0: Disable inbound IPSEC inline operation (default) > > > + * 1: Enable inbound IPSEC inline operation > > > + * > > > + * @see odp_ipsec_config(), odp_ipsec_sa_create() > > > + */ > > > + odp_bool_t inbound_ipsec; > > > + > > > + /** Outbound IPSEC inlined with packet output > > > + * > > > + * Enable/disable inline outbound IPSEC operation. When > enabled > > > IPSEC > > > + * outbound processing can send outgoing IPSEC packets > directly > > > + * to the pktio interface for output. IPSEC configuration is > done > > > + * through the IPSEC API. > > > + * > > > + * Outbound IPSEC inline operation cannot be combined with > traffic > > > + * manager (ODP_PKTOUT_MODE_TM). > > > > > > > We need to fix this since TM is likely to be the preferred TX mode, just > as > > the classifier is the preferred RX mode. There's no reason why IPsec > > traffic shouldn't also be subject to TM policies. > > > > > > > + * > > > + * 0: Disable outbound IPSEC inline operation (default) > > > + * 1: Enable outbound IPSEC inline operation > > > + * > > > + * @see odp_ipsec_config(), odp_ipsec_sa_create() > > > + */ > > > + odp_bool_t outbound_ipsec; > > > + > > > } odp_pktio_config_t; > > > > > > /** > > > -- > > > 2.8.1 > > > > > > >