1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018-2020 Intel Corporation 3 */ 4 5 #ifndef _MISC_H_ 6 #define _MISC_H_ 7 8 /** 9 * @file misc.h 10 * Contains miscellaneous functions/structures/macros used internally 11 * by ipsec library. 12 */ 13 14 /* 15 * Move bad (unprocessed) mbufs beyond the good (processed) ones. 16 * bad_idx[] contains the indexes of bad mbufs inside the mb[]. 17 */ 18 static inline void 19 move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb, 20 uint32_t nb_bad) 21 { 22 uint32_t i, j, k; 23 struct rte_mbuf *drb[nb_bad]; 24 25 j = 0; 26 k = 0; 27 28 /* copy bad ones into a temp place */ 29 for (i = 0; i != nb_mb; i++) { 30 if (j != nb_bad && i == bad_idx[j]) 31 drb[j++] = mb[i]; 32 else 33 mb[k++] = mb[i]; 34 } 35 36 /* copy bad ones after the good ones */ 37 for (i = 0; i != nb_bad; i++) 38 mb[k + i] = drb[i]; 39 } 40 41 /* 42 * Find packet's segment for the specified offset. 43 * ofs - at input should contain required offset, at output would contain 44 * offset value within the segment. 45 */ 46 static inline struct rte_mbuf * 47 mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs) 48 { 49 uint32_t k, n, plen; 50 struct rte_mbuf *ms; 51 52 plen = mb->pkt_len; 53 n = *ofs; 54 55 if (n == plen) { 56 ms = rte_pktmbuf_lastseg(mb); 57 n = n + rte_pktmbuf_data_len(ms) - plen; 58 } else { 59 ms = mb; 60 for (k = rte_pktmbuf_data_len(ms); n >= k; 61 k = rte_pktmbuf_data_len(ms)) { 62 ms = ms->next; 63 n -= k; 64 } 65 } 66 67 *ofs = n; 68 return ms; 69 } 70 71 /* 72 * Trim multi-segment packet at the specified offset, and free 73 * all unused segments. 74 * mb - input packet 75 * ms - segment where to cut 76 * ofs - offset within the *ms* 77 * len - length to cut (from given offset to the end of the packet) 78 * Can be used in conjunction with mbuf_get_seg_ofs(): 79 * ofs = new_len; 80 * ms = mbuf_get_seg_ofs(mb, &ofs); 81 * mbuf_cut_seg_ofs(mb, ms, ofs, mb->pkt_len - new_len); 82 */ 83 static inline void 84 mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs, 85 uint32_t len) 86 { 87 uint32_t n, slen; 88 struct rte_mbuf *mn; 89 90 slen = ms->data_len; 91 ms->data_len = ofs; 92 93 /* tail spawns through multiple segments */ 94 if (slen < ofs + len) { 95 mn = ms->next; 96 ms->next = NULL; 97 for (n = 0; mn != NULL; n++) { 98 ms = mn->next; 99 rte_pktmbuf_free_seg(mn); 100 mn = ms; 101 } 102 mb->nb_segs -= n; 103 } 104 105 mb->pkt_len -= len; 106 } 107 108 /* 109 * process packets using sync crypto engine. 110 * expects *num* to be greater than zero. 111 */ 112 static inline void 113 cpu_crypto_bulk(const struct rte_ipsec_session *ss, 114 union rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[], 115 struct rte_crypto_va_iova_ptr iv[], 116 struct rte_crypto_va_iova_ptr aad[], 117 struct rte_crypto_va_iova_ptr dgst[], uint32_t l4ofs[], 118 uint32_t clen[], uint32_t num) 119 { 120 uint32_t i, j, n; 121 int32_t vcnt, vofs; 122 int32_t st[num]; 123 struct rte_crypto_sgl vecpkt[num]; 124 struct rte_crypto_vec vec[UINT8_MAX]; 125 struct rte_crypto_sym_vec symvec; 126 127 const uint32_t vnum = RTE_DIM(vec); 128 129 j = 0, n = 0; 130 vofs = 0; 131 for (i = 0; i != num; i++) { 132 133 vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], 134 &vec[vofs], vnum - vofs); 135 136 /* not enough space in vec[] to hold all segments */ 137 if (vcnt < 0) { 138 /* fill the request structure */ 139 symvec.src_sgl = &vecpkt[j]; 140 symvec.iv = &iv[j]; 141 symvec.digest = &dgst[j]; 142 symvec.aad = &aad[j]; 143 symvec.status = &st[j]; 144 symvec.num = i - j; 145 146 /* flush vec array and try again */ 147 n += rte_cryptodev_sym_cpu_crypto_process( 148 ss->crypto.dev_id, ss->crypto.ses, ofs, 149 &symvec); 150 vofs = 0; 151 vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], 152 vec, vnum); 153 RTE_ASSERT(vcnt > 0); 154 j = i; 155 } 156 157 vecpkt[i].vec = &vec[vofs]; 158 vecpkt[i].num = vcnt; 159 vofs += vcnt; 160 } 161 162 /* fill the request structure */ 163 symvec.src_sgl = &vecpkt[j]; 164 symvec.iv = &iv[j]; 165 symvec.aad = &aad[j]; 166 symvec.digest = &dgst[j]; 167 symvec.status = &st[j]; 168 symvec.num = i - j; 169 170 n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id, 171 ss->crypto.ses, ofs, &symvec); 172 173 j = num - n; 174 for (i = 0; j != 0 && i != num; i++) { 175 if (st[i] != 0) { 176 mb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED; 177 j--; 178 } 179 } 180 } 181 182 #endif /* _MISC_H_ */ 183