[ovs-dev,RFC,v3,6/8] lib/dp-packet: copy data from multi-seg. DPDK mbuf

Message ID 1511288957-68599-7-git-send-email-mark.b.kavanagh@intel.com
State Superseded
Delegated to: Ian Stokes
Headers show
Series
  • netdev-dpdk: support multi-segment mbufs
Related show

Commit Message

Kavanagh, Mark B Nov. 21, 2017, 6:29 p.m.
From: Michael Qiu <qiudayu@chinac.com>

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 <qiudayu@chinac.com>
Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
---
 lib/dp-packet.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

Patch

diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 5c590e5..26fff02 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -166,10 +166,30 @@  struct dp_packet *
 dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
 {
     struct dp_packet *new_buffer;
+    uint32_t pkt_len = dp_packet_size(buffer);
 
+#ifdef DPDK_NETDEV
+    /* copy multi-seg data */
+    if (buffer->source == DPBUF_DPDK && buffer->mbuf.nb_segs > 1) {
+        uint32_t offset = 0;
+        void *dst = NULL;
+        struct rte_mbuf *tmbuf = CONST_CAST(struct rte_mbuf *, &(buffer->mbuf));
+
+        new_buffer = dp_packet_new_with_headroom(pkt_len, headroom);
+        dp_packet_set_size(new_buffer, pkt_len + headroom);
+        dst = dp_packet_tail(new_buffer);
+
+        while (tmbuf) {
+            rte_memcpy((char *)dst + offset,
+                       rte_pktmbuf_mtod(tmbuf, void *), tmbuf->data_len);
+            offset += tmbuf->data_len;
+            tmbuf = tmbuf->next;
+        }
+    }
+    else
+#endif
     new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
-                                                 dp_packet_size(buffer),
-                                                 headroom);
+                                                 pkt_len, headroom);
     /* Copy the following fields into the returned buffer: l2_pad_size,
      * l2_5_ofs, l3_ofs, l4_ofs, cutlen, packet_type and md. */
     memcpy(&new_buffer->l2_pad_size, &buffer->l2_pad_size,