+/**
+ * Converts portion of mbuf data into a vector representation.
+ * Each segment will be represented as a separate entry in *vec* array.
+ * Expects that provided *ofs* + *len* not to exceed mbuf's *pkt_len*.
+ * @param mb
+ * Pointer to the *rte_mbuf* object.
+ * @param ofs
+ * Offset within mbuf data to start with.
+ * @param len
+ * Length of data to represent.
+ * @param vec
+ * Pointer to an output array of IO vectors.
+ * @param num
+ * Size of an output array.
+ * @return
+ * - number of successfully filled entries in *vec* array.
+ * - negative number of elements in *vec* array required.
+ */
+__rte_experimental
+static inline int
+rte_crypto_mbuf_to_vec(const struct rte_mbuf *mb, uint32_t ofs, uint32_t len,
+ struct rte_crypto_vec vec[], uint32_t num)
+{
+ uint32_t i;
+ struct rte_mbuf *nseg;
+ uint32_t left;
+ uint32_t seglen;
+
+ /* assuming that requested data starts in the first segment */
+ RTE_ASSERT(mb->data_len > ofs);
+
+ if (mb->nb_segs > num)
+ return -mb->nb_segs;
+
+ vec[0].base = rte_pktmbuf_mtod_offset(mb, void *, ofs);
+ vec[0].iova = rte_pktmbuf_iova_offset(mb, ofs);
+
+ /* whole data lies in the first segment */
+ seglen = mb->data_len - ofs;
+ if (len <= seglen) {
+ vec[0].len = len;
+ return 1;
+ }
+
+ /* data spread across segments */
+ vec[0].len = seglen;
+ left = len - seglen;
+ for (i = 1, nseg = mb->next; nseg != NULL; nseg = nseg->next, i++) {
+
+ vec[i].base = rte_pktmbuf_mtod(nseg, void *);
+ vec[i].iova = rte_pktmbuf_iova(nseg);
+
+ seglen = nseg->data_len;
+ if (left <= seglen) {
+ /* whole requested data is completed */
+ vec[i].len = left;
+ left = 0;
+ break;
+ }
+
+ /* use whole segment */
+ vec[i].len = seglen;
+ left -= seglen;
+ }
+
+ RTE_ASSERT(left == 0);
+ return i + 1;
+}
+