static inline int rte_pktmbuf_linearize(struct rte_mbuf *mbuf) { if (rte_pktmbuf_is_contiguous(mbuf)) return 0; return __rte_pktmbuf_linearize(mbuf); }
/** * Test if mbuf data is contiguous. * * @param m * The packet mbuf. * @return * - 1, if all data is contiguous (one segment). * - 0, if there is several segments. */ static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m) { __rte_mbuf_sanity_check(m, 1); return !!(m->nb_segs == 1); }
__rte_pktmbuf_linearize(struct rte_mbuf *mbuf) { size_t seg_len, copy_len; struct rte_mbuf *m; struct rte_mbuf *m_next; char *buffer; /* Extend first segment to the total packet length */ copy_len = rte_pktmbuf_pkt_len(mbuf) - rte_pktmbuf_data_len(mbuf); if (unlikely(copy_len > rte_pktmbuf_tailroom(mbuf))) return -1; buffer = rte_pktmbuf_mtod_offset(mbuf, char *, mbuf->data_len); mbuf->data_len = (uint16_t)(mbuf->pkt_len); /* Append data from next segments to the first one */ m = mbuf->next; while (m != NULL) { m_next = m->next; seg_len = rte_pktmbuf_data_len(m); rte_memcpy(buffer, rte_pktmbuf_mtod(m, char *), seg_len); buffer += seg_len; rte_pktmbuf_free_seg(m); m = m_next; }
mbuf->next = NULL; mbuf->nb_segs = 1; return 0; }
static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m) { __rte_mbuf_sanity_check(m, 0); return m->data_off; } /** * Get the tailroom of a packet mbuf. * * @param m * The packet mbuf. * @return * The length of the tailroom. */ static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m) { __rte_mbuf_sanity_check(m, 0); return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) - m->data_len); }