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.kavan...@intel.com> --- lib/dp-packet.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/dp-packet.c b/lib/dp-packet.c index 5078211..5c590e5 100644 --- a/lib/dp-packet.c +++ b/lib/dp-packet.c @@ -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; } -- 1.9.3 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev