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 const struct rte_security_session *ss; 48 const struct rte_cryptodev_sym_session *cs; 49 50 if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) { 51 ss = cop->sym[0].sec_session; 52 return (void *)(uintptr_t)ss->opaque_data; 53 } else if (cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 54 cs = cop->sym[0].session; 55 return (void *)(uintptr_t)cs->opaque_data; 56 } 57 return NULL; 58 } 59 60 /** 61 * Take as input completed crypto ops, extract related mbufs 62 * and group them by rte_ipsec_session they belong to. 63 * For mbuf which crypto-op wasn't completed successfully 64 * RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED will be raised in ol_flags. 65 * Note that mbufs with undetermined SA (session-less) are not freed 66 * by the function, but are placed beyond mbufs for the last valid group. 67 * It is a user responsibility to handle them further. 68 * @param cop 69 * The address of an array of *num* pointers to the input *rte_crypto_op* 70 * structures. 71 * @param mb 72 * The address of an array of *num* pointers to output *rte_mbuf* structures. 73 * @param grp 74 * The address of an array of *num* to output *rte_ipsec_group* structures. 75 * @param num 76 * The maximum number of crypto-ops to process. 77 * @return 78 * Number of filled elements in *grp* array. 79 */ 80 static inline uint16_t 81 rte_ipsec_pkt_crypto_group(const struct rte_crypto_op *cop[], 82 struct rte_mbuf *mb[], struct rte_ipsec_group grp[], uint16_t num) 83 { 84 uint32_t i, j, k, n; 85 void *ns, *ps; 86 struct rte_mbuf *m, *dr[num]; 87 88 j = 0; 89 k = 0; 90 n = 0; 91 ps = NULL; 92 93 for (i = 0; i != num; i++) { 94 95 m = cop[i]->sym[0].m_src; 96 ns = cop[i]->sym[0].session; 97 98 m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD; 99 if (cop[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS) 100 m->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED; 101 102 /* no valid session found */ 103 if (ns == NULL) { 104 dr[k++] = m; 105 continue; 106 } 107 108 /* different SA */ 109 if (ps != ns) { 110 111 /* 112 * we already have an open group - finalize it, 113 * then open a new one. 114 */ 115 if (ps != NULL) { 116 grp[n].id.ptr = 117 rte_ipsec_ses_from_crypto(cop[i - 1]); 118 grp[n].cnt = mb + j - grp[n].m; 119 n++; 120 } 121 122 /* start new group */ 123 grp[n].m = mb + j; 124 ps = ns; 125 } 126 127 mb[j++] = m; 128 } 129 130 /* finalise last group */ 131 if (ps != NULL) { 132 grp[n].id.ptr = rte_ipsec_ses_from_crypto(cop[i - 1]); 133 grp[n].cnt = mb + j - grp[n].m; 134 n++; 135 } 136 137 /* copy mbufs with unknown session beyond recognised ones */ 138 if (k != 0 && k != num) { 139 for (i = 0; i != k; i++) 140 mb[j + i] = dr[i]; 141 } 142 143 return n; 144 } 145 146 #ifdef __cplusplus 147 } 148 #endif 149 150 #endif /* _RTE_IPSEC_GROUP_H_ */ 151