When doing packet clone, if packet source is from DPDK driver, multi-segment must be considered, and copy the segment's data one by one.
Signed-off-by: Michael Qiu <qiud...@chinac.com> Signed-off-by: Jijiang Liu <liujiji...@chinac.com> --- lib/dp-packet.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/dp-packet.c b/lib/dp-packet.c index 619f651..3ca1fde 100644 --- a/lib/dp-packet.c +++ b/lib/dp-packet.c @@ -164,9 +164,28 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom) { struct dp_packet *new_buffer; - new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer), - dp_packet_size(buffer), - headroom); + uint32_t size = dp_packet_size(buffer); + + /* copy multi-seg data */ + #ifdef DPDK_NETDEV + if (buffer->source == DPBUF_DPDK && buffer->mbuf.nb_segs > 1) { + struct rte_mbuf *tmbuf = &(buffer->mbuf); + new_buffer = dp_packet_new_with_headroom(size, headroom); + void *dst = dp_packet_put_uninit(new_buffer, size); + uint32_t off_set = 0; + + while (tmbuf) { + rte_memcpy((char *)dst + off_set, + rte_pktmbuf_mtod(tmbuf, void *), tmbuf->data_len); + off_set += tmbuf->data_len; + tmbuf = tmbuf->next; + } + } + else + #endif + new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer), + size, headroom); + new_buffer->l2_pad_size = buffer->l2_pad_size; new_buffer->l2_5_ofs = buffer->l2_5_ofs; new_buffer->l3_ofs = buffer->l3_ofs; -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev