1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #ifndef _RTE_IPSEC_GROUP_H_ 6 #define _RTE_IPSEC_GROUP_H_ 7 8 /** 9 * @file rte_ipsec_group.h 10 * 11 * RTE IPsec support. 12 * It is not recommended to include this file directly, 13 * include <rte_ipsec.h> instead. 14 * Contains helper functions to process completed crypto-ops 15 * and group related packets by sessions they belong to. 16 */ 17 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /** 24 * Used to group mbufs by some id. 25 * See below for particular usage. 26 */ 27 struct rte_ipsec_group { 28 union { 29 uint64_t val; 30 void *ptr; 31 } id; /**< grouped by value */ 32 struct rte_mbuf **m; /**< start of the group */ 33 uint32_t cnt; /**< number of entries in the group */ 34 int32_t rc; /**< status code associated with the group */ 35 }; 36 37 /** 38 * Take crypto-op as an input and extract pointer to related ipsec session. 39 * @param cop 40 * The address of an input *rte_crypto_op* structure. 41 * @return 42 * The pointer to the related *rte_ipsec_session* structure. 43 */ 44 static inline struct rte_ipsec_session * 45 rte_ipsec_ses_from_crypto(const struct rte_crypto_op *cop) 46 { 47 void *ses; 48 49 if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) { 50 ses = cop->sym[0].session; 51 return (struct rte_ipsec_session *)(uintptr_t) 52 rte_security_session_opaque_data_get(ses); 53 } else if (cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 54 ses = cop->sym[0].session; 55 return (struct rte_ipsec_session *)(uintptr_t) 56 rte_cryptodev_sym_session_opaque_data_get(ses); 57 } 58 return NULL; 59 } 60 61 /** 62 * Take as input completed crypto ops, extract related mbufs 63 * and group them by rte_ipsec_session they belong to. 64 * For mbuf which crypto-op wasn't completed successfully 65 * RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED will be raised in ol_flags. 66 * Note that mbufs with undetermined SA (session-less) are not freed 67 * by the function, but are placed beyond mbufs for the last valid group. 68 * It is a user responsibility to handle them further. 69 * @param cop 70 * The address of an array of *num* pointers to the input *rte_crypto_op* 71 * structures. 72 * @param mb 73 * The address of an array of *num* pointers to output *rte_mbuf* structures. 74 * @param grp 75 * The address of an array of *num* to output *rte_ipsec_group* structures. 76 * @param num 77 * The maximum number of crypto-ops to process. 78 * @return 79 * Number of filled elements in *grp* array. 80 */ 81 static inline uint16_t 82 rte_ipsec_pkt_crypto_group(const struct rte_crypto_op *cop[], 83 struct rte_mbuf *mb[], struct rte_ipsec_group grp[], uint16_t num) 84 { 85 uint32_t i, j, k, n; 86 void *ns, *ps; 87 struct rte_mbuf *m, *dr[num]; 88 89 j = 0; 90 k = 0; 91 n = 0; 92 ps = NULL; 93 94 for (i = 0; i != num; i++) { 95 96 m = cop[i]->sym[0].m_src; 97 ns = cop[i]->sym[0].session; 98 99 m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD; 100 if (cop[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS) 101 m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED; 102 103 /* no valid session found */ 104 if (ns == NULL) { 105 dr[k++] = m; 106 continue; 107 } 108 109 /* different SA */ 110 if (ps != ns) { 111 112 /* 113 * we already have an open group - finalize it, 114 * then open a new one. 115 */ 116 if (ps != NULL) { 117 grp[n].id.ptr = 118 rte_ipsec_ses_from_crypto(cop[i - 1]); 119 grp[n].cnt = mb + j - grp[n].m; 120 n++; 121 } 122 123 /* start new group */ 124 grp[n].m = mb + j; 125 ps = ns; 126 } 127 128 mb[j++] = m; 129 } 130 131 /* finalise last group */ 132 if (ps != NULL) { 133 grp[n].id.ptr = rte_ipsec_ses_from_crypto(cop[i - 1]); 134 grp[n].cnt = mb + j - grp[n].m; 135 n++; 136 } 137 138 /* copy mbufs with unknown session beyond recognised ones */ 139 if (k != 0 && k != num) { 140 for (i = 0; i != k; i++) 141 mb[j + i] = dr[i]; 142 } 143 144 return n; 145 } 146 147 #ifdef __cplusplus 148 } 149 #endif 150 151 #endif /* _RTE_IPSEC_GROUP_H_ */ 152