199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2018 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _RTE_IPSEC_GROUP_H_ 699a2dd95SBruce Richardson #define _RTE_IPSEC_GROUP_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson /** 999a2dd95SBruce Richardson * @file rte_ipsec_group.h 1099a2dd95SBruce Richardson * 1199a2dd95SBruce Richardson * RTE IPsec support. 1299a2dd95SBruce Richardson * It is not recommended to include this file directly, 1399a2dd95SBruce Richardson * include <rte_ipsec.h> instead. 1499a2dd95SBruce Richardson * Contains helper functions to process completed crypto-ops 1599a2dd95SBruce Richardson * and group related packets by sessions they belong to. 1699a2dd95SBruce Richardson */ 1799a2dd95SBruce Richardson 1899a2dd95SBruce Richardson 1999a2dd95SBruce Richardson #ifdef __cplusplus 2099a2dd95SBruce Richardson extern "C" { 2199a2dd95SBruce Richardson #endif 2299a2dd95SBruce Richardson 2399a2dd95SBruce Richardson /** 2499a2dd95SBruce Richardson * Used to group mbufs by some id. 2599a2dd95SBruce Richardson * See below for particular usage. 2699a2dd95SBruce Richardson */ 2799a2dd95SBruce Richardson struct rte_ipsec_group { 2899a2dd95SBruce Richardson union { 2999a2dd95SBruce Richardson uint64_t val; 3099a2dd95SBruce Richardson void *ptr; 3199a2dd95SBruce Richardson } id; /**< grouped by value */ 3299a2dd95SBruce Richardson struct rte_mbuf **m; /**< start of the group */ 3399a2dd95SBruce Richardson uint32_t cnt; /**< number of entries in the group */ 3499a2dd95SBruce Richardson int32_t rc; /**< status code associated with the group */ 3599a2dd95SBruce Richardson }; 3699a2dd95SBruce Richardson 3799a2dd95SBruce Richardson /** 3899a2dd95SBruce Richardson * Take crypto-op as an input and extract pointer to related ipsec session. 3999a2dd95SBruce Richardson * @param cop 4099a2dd95SBruce Richardson * The address of an input *rte_crypto_op* structure. 4199a2dd95SBruce Richardson * @return 4299a2dd95SBruce Richardson * The pointer to the related *rte_ipsec_session* structure. 4399a2dd95SBruce Richardson */ 4499a2dd95SBruce Richardson static inline struct rte_ipsec_session * 4599a2dd95SBruce Richardson rte_ipsec_ses_from_crypto(const struct rte_crypto_op *cop) 4699a2dd95SBruce Richardson { 4799a2dd95SBruce Richardson const struct rte_security_session *ss; 4899a2dd95SBruce Richardson const struct rte_cryptodev_sym_session *cs; 4999a2dd95SBruce Richardson 5099a2dd95SBruce Richardson if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) { 5199a2dd95SBruce Richardson ss = cop->sym[0].sec_session; 5299a2dd95SBruce Richardson return (void *)(uintptr_t)ss->opaque_data; 5399a2dd95SBruce Richardson } else if (cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 5499a2dd95SBruce Richardson cs = cop->sym[0].session; 5599a2dd95SBruce Richardson return (void *)(uintptr_t)cs->opaque_data; 5699a2dd95SBruce Richardson } 5799a2dd95SBruce Richardson return NULL; 5899a2dd95SBruce Richardson } 5999a2dd95SBruce Richardson 6099a2dd95SBruce Richardson /** 6199a2dd95SBruce Richardson * Take as input completed crypto ops, extract related mbufs 6299a2dd95SBruce Richardson * and group them by rte_ipsec_session they belong to. 6399a2dd95SBruce Richardson * For mbuf which crypto-op wasn't completed successfully 64*daa02b5cSOlivier Matz * RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED will be raised in ol_flags. 6599a2dd95SBruce Richardson * Note that mbufs with undetermined SA (session-less) are not freed 6699a2dd95SBruce Richardson * by the function, but are placed beyond mbufs for the last valid group. 6799a2dd95SBruce Richardson * It is a user responsibility to handle them further. 6899a2dd95SBruce Richardson * @param cop 6999a2dd95SBruce Richardson * The address of an array of *num* pointers to the input *rte_crypto_op* 7099a2dd95SBruce Richardson * structures. 7199a2dd95SBruce Richardson * @param mb 7299a2dd95SBruce Richardson * The address of an array of *num* pointers to output *rte_mbuf* structures. 7399a2dd95SBruce Richardson * @param grp 7499a2dd95SBruce Richardson * The address of an array of *num* to output *rte_ipsec_group* structures. 7599a2dd95SBruce Richardson * @param num 7699a2dd95SBruce Richardson * The maximum number of crypto-ops to process. 7799a2dd95SBruce Richardson * @return 7899a2dd95SBruce Richardson * Number of filled elements in *grp* array. 7999a2dd95SBruce Richardson */ 8099a2dd95SBruce Richardson static inline uint16_t 8199a2dd95SBruce Richardson rte_ipsec_pkt_crypto_group(const struct rte_crypto_op *cop[], 8299a2dd95SBruce Richardson struct rte_mbuf *mb[], struct rte_ipsec_group grp[], uint16_t num) 8399a2dd95SBruce Richardson { 8499a2dd95SBruce Richardson uint32_t i, j, k, n; 8599a2dd95SBruce Richardson void *ns, *ps; 8699a2dd95SBruce Richardson struct rte_mbuf *m, *dr[num]; 8799a2dd95SBruce Richardson 8899a2dd95SBruce Richardson j = 0; 8999a2dd95SBruce Richardson k = 0; 9099a2dd95SBruce Richardson n = 0; 9199a2dd95SBruce Richardson ps = NULL; 9299a2dd95SBruce Richardson 9399a2dd95SBruce Richardson for (i = 0; i != num; i++) { 9499a2dd95SBruce Richardson 9599a2dd95SBruce Richardson m = cop[i]->sym[0].m_src; 9699a2dd95SBruce Richardson ns = cop[i]->sym[0].session; 9799a2dd95SBruce Richardson 98*daa02b5cSOlivier Matz m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD; 9999a2dd95SBruce Richardson if (cop[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS) 100*daa02b5cSOlivier Matz m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED; 10199a2dd95SBruce Richardson 10299a2dd95SBruce Richardson /* no valid session found */ 10399a2dd95SBruce Richardson if (ns == NULL) { 10499a2dd95SBruce Richardson dr[k++] = m; 10599a2dd95SBruce Richardson continue; 10699a2dd95SBruce Richardson } 10799a2dd95SBruce Richardson 10899a2dd95SBruce Richardson /* different SA */ 10999a2dd95SBruce Richardson if (ps != ns) { 11099a2dd95SBruce Richardson 11199a2dd95SBruce Richardson /* 11299a2dd95SBruce Richardson * we already have an open group - finalize it, 11399a2dd95SBruce Richardson * then open a new one. 11499a2dd95SBruce Richardson */ 11599a2dd95SBruce Richardson if (ps != NULL) { 11699a2dd95SBruce Richardson grp[n].id.ptr = 11799a2dd95SBruce Richardson rte_ipsec_ses_from_crypto(cop[i - 1]); 11899a2dd95SBruce Richardson grp[n].cnt = mb + j - grp[n].m; 11999a2dd95SBruce Richardson n++; 12099a2dd95SBruce Richardson } 12199a2dd95SBruce Richardson 12299a2dd95SBruce Richardson /* start new group */ 12399a2dd95SBruce Richardson grp[n].m = mb + j; 12499a2dd95SBruce Richardson ps = ns; 12599a2dd95SBruce Richardson } 12699a2dd95SBruce Richardson 12799a2dd95SBruce Richardson mb[j++] = m; 12899a2dd95SBruce Richardson } 12999a2dd95SBruce Richardson 13099a2dd95SBruce Richardson /* finalise last group */ 13199a2dd95SBruce Richardson if (ps != NULL) { 13299a2dd95SBruce Richardson grp[n].id.ptr = rte_ipsec_ses_from_crypto(cop[i - 1]); 13399a2dd95SBruce Richardson grp[n].cnt = mb + j - grp[n].m; 13499a2dd95SBruce Richardson n++; 13599a2dd95SBruce Richardson } 13699a2dd95SBruce Richardson 13799a2dd95SBruce Richardson /* copy mbufs with unknown session beyond recognised ones */ 13899a2dd95SBruce Richardson if (k != 0 && k != num) { 13999a2dd95SBruce Richardson for (i = 0; i != k; i++) 14099a2dd95SBruce Richardson mb[j + i] = dr[i]; 14199a2dd95SBruce Richardson } 14299a2dd95SBruce Richardson 14399a2dd95SBruce Richardson return n; 14499a2dd95SBruce Richardson } 14599a2dd95SBruce Richardson 14699a2dd95SBruce Richardson #ifdef __cplusplus 14799a2dd95SBruce Richardson } 14899a2dd95SBruce Richardson #endif 14999a2dd95SBruce Richardson 15099a2dd95SBruce Richardson #endif /* _RTE_IPSEC_GROUP_H_ */ 151