X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ceph%2Fsrc%2Fspdk%2Fdpdk%2Flib%2Flibrte_ipsec%2Fmisc.h;fp=ceph%2Fsrc%2Fspdk%2Fdpdk%2Flib%2Flibrte_ipsec%2Fmisc.h;h=1b543ed8753bde6bfa8657913987ea824653bceb;hb=f67539c23b11f3b8a2ecaeeddf7a403ae1c442a8;hp=693a4afddbf3bd131f7fad9074c00f872fb35e4f;hpb=64a4c04e6850c6d9086e4c37f57c4eada541b05e;p=ceph.git diff --git a/ceph/src/spdk/dpdk/lib/librte_ipsec/misc.h b/ceph/src/spdk/dpdk/lib/librte_ipsec/misc.h index 693a4afdd..1b543ed87 100644 --- a/ceph/src/spdk/dpdk/lib/librte_ipsec/misc.h +++ b/ceph/src/spdk/dpdk/lib/librte_ipsec/misc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018-2020 Intel Corporation */ #ifndef _MISC_H_ @@ -38,4 +38,143 @@ move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb, mb[k + i] = drb[i]; } +/* + * Find packet's segment for the specified offset. + * ofs - at input should contain required offset, at output would contain + * offset value within the segment. + */ +static inline struct rte_mbuf * +mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs) +{ + uint32_t k, n, plen; + struct rte_mbuf *ms; + + plen = mb->pkt_len; + n = *ofs; + + if (n == plen) { + ms = rte_pktmbuf_lastseg(mb); + n = n + rte_pktmbuf_data_len(ms) - plen; + } else { + ms = mb; + for (k = rte_pktmbuf_data_len(ms); n >= k; + k = rte_pktmbuf_data_len(ms)) { + ms = ms->next; + n -= k; + } + } + + *ofs = n; + return ms; +} + +/* + * Trim multi-segment packet at the specified offset, and free + * all unused segments. + * mb - input packet + * ms - segment where to cut + * ofs - offset within the *ms* + * len - length to cut (from given offset to the end of the packet) + * Can be used in conjunction with mbuf_get_seg_ofs(): + * ofs = new_len; + * ms = mbuf_get_seg_ofs(mb, &ofs); + * mbuf_cut_seg_ofs(mb, ms, ofs, mb->pkt_len - new_len); + */ +static inline void +mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs, + uint32_t len) +{ + uint32_t n, slen; + struct rte_mbuf *mn; + + slen = ms->data_len; + ms->data_len = ofs; + + /* tail spawns through multiple segments */ + if (slen < ofs + len) { + mn = ms->next; + ms->next = NULL; + for (n = 0; mn != NULL; n++) { + ms = mn->next; + rte_pktmbuf_free_seg(mn); + mn = ms; + } + mb->nb_segs -= n; + } + + mb->pkt_len -= len; +} + +/* + * process packets using sync crypto engine. + * expects *num* to be greater than zero. + */ +static inline void +cpu_crypto_bulk(const struct rte_ipsec_session *ss, + union rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[], + void *iv[], void *aad[], void *dgst[], uint32_t l4ofs[], + uint32_t clen[], uint32_t num) +{ + uint32_t i, j, n; + int32_t vcnt, vofs; + int32_t st[num]; + struct rte_crypto_sgl vecpkt[num]; + struct rte_crypto_vec vec[UINT8_MAX]; + struct rte_crypto_sym_vec symvec; + + const uint32_t vnum = RTE_DIM(vec); + + j = 0, n = 0; + vofs = 0; + for (i = 0; i != num; i++) { + + vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], + &vec[vofs], vnum - vofs); + + /* not enough space in vec[] to hold all segments */ + if (vcnt < 0) { + /* fill the request structure */ + symvec.sgl = &vecpkt[j]; + symvec.iv = &iv[j]; + symvec.aad = &aad[j]; + symvec.digest = &dgst[j]; + symvec.status = &st[j]; + symvec.num = i - j; + + /* flush vec array and try again */ + n += rte_cryptodev_sym_cpu_crypto_process( + ss->crypto.dev_id, ss->crypto.ses, ofs, + &symvec); + vofs = 0; + vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i], + vec, vnum); + RTE_ASSERT(vcnt > 0); + j = i; + } + + vecpkt[i].vec = &vec[vofs]; + vecpkt[i].num = vcnt; + vofs += vcnt; + } + + /* fill the request structure */ + symvec.sgl = &vecpkt[j]; + symvec.iv = &iv[j]; + symvec.aad = &aad[j]; + symvec.digest = &dgst[j]; + symvec.status = &st[j]; + symvec.num = i - j; + + n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id, + ss->crypto.ses, ofs, &symvec); + + j = num - n; + for (i = 0; j != 0 && i != num; i++) { + if (st[i] != 0) { + mb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED; + j--; + } + } +} + #endif /* _MISC_H_ */