@@ -325,6 +325,22 @@ dp_packet_put_uninit(struct dp_packet *b, size_t size)
void *p;
dp_packet_prealloc_tailroom(b, size);
p = dp_packet_tail(b);
+#ifdef DPDK_NETDEV
+ if (b->source == DPBUF_DPDK) {
+ struct rte_mbuf *buf = &(b->mbuf);
+ /* In the case of multi-segment mbufs, the data length of the last mbuf
+ * should be adjusted by 'size' bytes. A call to dp_packet_size() would
+ * adjust the data length of the first mbuf in the segment, so we avoid
+ * invoking same; as a result, the packet length of the entire mbuf
+ * chain (stored in the first mbuf of said chain) must be adjusted here
+ * instead.
+ */
+ while (buf->next)
+ buf = buf->next;
+ buf->data_len += size;
+ b->mbuf.pkt_len += size;
+ } else
+#endif
dp_packet_set_size(b, dp_packet_size(b) + size);
return p;
}
dp_packet_put_uninit(dp_packet, size) appends 'size' bytes to the tail of a dp_packet. In the case of multi-segment mbufs, it is the data length of the last mbuf in the mbuf chain that should be adjusted by 'size' bytes. In its current implementation, dp_packet_put_uninit() adjusts the dp_packet's size via a call to dp_packet_set_size(); however, this adjusts the data length of the first mbuf in the chain, which is incorrect in the case of multi-segment mbufs. Instead, traverse the mbuf chain to locate the final mbuf of said chain, and update its data_len [1]. To finish, increase the packet length of the entire mbuf [2] by 'size'. [1] In the case of a single-segment mbuf, this is the mbuf itself. [2] This is stored in the first mbuf of an mbuf chain. Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com> --- lib/dp-packet.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)