/* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2018-2020 Intel Corporation */ #ifndef _RTE_IPSEC_H_ #define _RTE_IPSEC_H_ /** * @file rte_ipsec.h * * RTE IPsec support. * * librte_ipsec provides a framework for data-path IPsec protocol * processing (ESP/AH). */ #include #include struct rte_ipsec_session; /** * IPsec state for stateless processing of a batch of IPsec packets. */ struct rte_ipsec_state { /** * 64 bit sequence number to be used for the first packet of the * batch of packets. */ uint64_t sqn; }; /** * IPsec session specific functions that will be used to: * - prepare - for input mbufs and given IPsec session prepare crypto ops * that can be enqueued into the cryptodev associated with given session * (see *rte_ipsec_pkt_crypto_prepare* below for more details). * - prepare_stateless - similar to prepare, but further processing is done * based on IPsec state provided by the 'state' parameter. * - process - finalize processing of packets after crypto-dev finished * with them or process packets that are subjects to inline IPsec offload * (see rte_ipsec_pkt_process for more details). */ struct rte_ipsec_sa_pkt_func { union { uint16_t (*async)(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], struct rte_crypto_op *cop[], uint16_t num); uint16_t (*sync)(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num); } prepare; union { uint16_t (*async)(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], struct rte_crypto_op *cop[], uint16_t num, struct rte_ipsec_state *state); uint16_t (*sync)(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num, struct rte_ipsec_state *state); } prepare_stateless; uint16_t (*process)(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num); }; /** * rte_ipsec_session is an aggregate structure that defines particular * IPsec Security Association IPsec (SA) on given security/crypto device: * - pointer to the SA object * - security session action type * - pointer to security/crypto session, plus other related data * - session/device specific functions to prepare/process IPsec packets. */ struct __rte_cache_aligned rte_ipsec_session { /** * SA that session belongs to. * Note that multiple sessions can belong to the same SA. */ struct rte_ipsec_sa *sa; /** session action type */ enum rte_security_session_action_type type; /** session and related data */ union { struct { struct rte_cryptodev_sym_session *ses; uint8_t dev_id; } crypto; struct { struct rte_security_session *ses; struct rte_security_ctx *ctx; uint32_t ol_flags; } security; }; /** functions to prepare/process IPsec packets */ struct rte_ipsec_sa_pkt_func pkt_func; }; /** * Checks that inside given rte_ipsec_session crypto/security fields * are filled correctly and setups function pointers based on these values. * Expects that all fields except IPsec processing function pointers * (*pkt_func*) will be filled correctly by caller. * @param ss * Pointer to the *rte_ipsec_session* object * @return * - Zero if operation completed successfully. * - -EINVAL if the parameters are invalid. */ int rte_ipsec_session_prepare(struct rte_ipsec_session *ss); /** * For input mbufs and given IPsec session prepare crypto ops that can be * enqueued into the cryptodev associated with given session. * expects that for each input packet: * - l2_len, l3_len are setup correctly * Note that erroneous mbufs are not freed by the function, * but are placed beyond last valid mbuf in the *mb* array. * It is a user responsibility to handle them further. * @param ss * Pointer to the *rte_ipsec_session* object the packets belong to. * @param mb * The address of an array of *num* pointers to *rte_mbuf* structures * which contain the input packets. * @param cop * The address of an array of *num* pointers to the output *rte_crypto_op* * structures. * @param num * The maximum number of packets to process. * @return * Number of successfully processed packets, with error code set in rte_errno. */ static inline uint16_t rte_ipsec_pkt_crypto_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], struct rte_crypto_op *cop[], uint16_t num) { return ss->pkt_func.prepare.async(ss, mb, cop, num); } static inline uint16_t rte_ipsec_pkt_cpu_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num) { return ss->pkt_func.prepare.sync(ss, mb, num); } /** * Same as *rte_ipsec_pkt_crypto_prepare*, but processing is done based on * IPsec state provided by the 'state' parameter. Internal IPsec state won't * be updated when this API is called. * * For input mbufs and given IPsec session prepare crypto ops that can be * enqueued into the cryptodev associated with given session. * expects that for each input packet: * - l2_len, l3_len are setup correctly * Note that erroneous mbufs are not freed by the function, * but are placed beyond last valid mbuf in the *mb* array. * It is a user responsibility to handle them further. * @param ss * Pointer to the *rte_ipsec_session* object the packets belong to. * @param mb * The address of an array of *num* pointers to *rte_mbuf* structures * which contain the input packets. * @param cop * The address of an array of *num* pointers to the output *rte_crypto_op* * structures. * @param num * The maximum number of packets to process. * @param state * The IPsec state to be used for processing current batch of packets. * @return * Number of successfully processed packets, with error code set in rte_errno. */ __rte_experimental static inline uint16_t rte_ipsec_pkt_crypto_prepare_stateless(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], struct rte_crypto_op *cop[], uint16_t num, struct rte_ipsec_state *state) { return ss->pkt_func.prepare_stateless.async(ss, mb, cop, num, state); } /** * Same as *rte_ipsec_pkt_crypto_prepare_stateless*, but processing is done * in synchronous mode. * * @param ss * Pointer to the *rte_ipsec_session* object the packets belong to. * @param mb * The address of an array of *num* pointers to *rte_mbuf* structures * which contain the input packets. * @param num * The maximum number of packets to process. * @param state * The IPsec state to be used for processing current batch of packets. * @return * Number of successfully processed packets, with error code set in rte_errno. */ __rte_experimental static inline uint16_t rte_ipsec_pkt_cpu_prepare_stateless(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num, struct rte_ipsec_state *state) { return ss->pkt_func.prepare_stateless.sync(ss, mb, num, state); } /** * Finalise processing of packets after crypto-dev finished with them or * process packets that are subjects to inline IPsec offload. * Expects that for each input packet: * - l2_len, l3_len are setup correctly * Output mbufs will be: * inbound - decrypted & authenticated, ESP(AH) related headers removed, * *l2_len* and *l3_len* fields are updated. * outbound - appropriate mbuf fields (ol_flags, tx_offloads, etc.) * properly setup, if necessary - IP headers updated, ESP(AH) fields added, * Note that erroneous mbufs are not freed by the function, * but are placed beyond last valid mbuf in the *mb* array. * It is a user responsibility to handle them further. * @param ss * Pointer to the *rte_ipsec_session* object the packets belong to. * @param mb * The address of an array of *num* pointers to *rte_mbuf* structures * which contain the input packets. * @param num * The maximum number of packets to process. * @return * Number of successfully processed packets, with error code set in rte_errno. */ static inline uint16_t rte_ipsec_pkt_process(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], uint16_t num) { return ss->pkt_func.process(ss, mb, num); } /** * Enable per SA telemetry for a specific SA. * Note that this function is not thread safe * @param sa * Pointer to the *rte_ipsec_sa* object that will have telemetry enabled. * @return * 0 on success, negative value otherwise. */ int rte_ipsec_telemetry_sa_add(const struct rte_ipsec_sa *sa); /** * Disable per SA telemetry for a specific SA. * Note that this function is not thread safe * @param sa * Pointer to the *rte_ipsec_sa* object that will have telemetry disabled. */ void rte_ipsec_telemetry_sa_del(const struct rte_ipsec_sa *sa); #include #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* _RTE_IPSEC_H_ */