In new model, the packet was already copied, only need
to wrap it in pcapng format.

Signed-off-by: Stephen Hemminger <step...@networkplumber.org>
---
 lib/pcapng/rte_pcapng.c | 178 +++++++++++++++++++++-------------------
 lib/pcapng/rte_pcapng.h |  27 +++++-
 2 files changed, 120 insertions(+), 85 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index cacbefdc50..5b40a20b19 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -1,3 +1,4 @@
+
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2019 Microsoft Corporation
  */
@@ -432,8 +433,24 @@ pcapng_vlan_insert(struct rte_mbuf *m, uint16_t 
ether_type, uint16_t tci)
        return 0;
 }
 
+/* pad the packet to 32 bit boundary */
+static inline int
+pcapng_mbuf_pad32(struct rte_mbuf *m)
+{
+       uint32_t pkt_len = rte_pktmbuf_pkt_len(m);
+       uint32_t padding = RTE_ALIGN(pkt_len, sizeof(uint32_t)) - pkt_len;
+
+       if (padding > 0) {
+               void *tail = rte_pktmbuf_append(m, padding);
+               if (tail == NULL)
+                       return -1;
+               memset(tail, 0, padding);
+       }
+       return 0;
+}
+
 /*
- *   The mbufs created use the Pcapng standard enhanced packet  block.
+ *  The mbufs created use the Pcapng standard enhanced packet block.
  *
  *                         1                   2                   3
  *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -468,71 +485,28 @@ pcapng_vlan_insert(struct rte_mbuf *m, uint16_t 
ether_type, uint16_t tci)
  *    |                      Block Total Length                       |
  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  */
-
-/* Make a copy of original mbuf with pcapng header and options */
-RTE_EXPORT_SYMBOL(rte_pcapng_copy)
-struct rte_mbuf *
-rte_pcapng_copy(uint16_t port_id, uint32_t queue,
-               const struct rte_mbuf *md,
-               struct rte_mempool *mp,
-               uint32_t length,
-               enum rte_pcapng_direction direction,
-               const char *comment)
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pcapng_insert, 25.07)
+int
+rte_pcapng_insert(struct rte_mbuf *m, uint32_t queue,
+                 enum rte_pcapng_direction direction, uint32_t orig_len,
+                 uint64_t timestamp, const char *comment)
 {
        struct pcapng_enhance_packet_block *epb;
-       uint32_t orig_len, pkt_len, padding, flags;
-       struct pcapng_option *opt;
-       uint64_t timestamp;
-       uint16_t optlen;
-       struct rte_mbuf *mc;
-       bool rss_hash;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
-#endif
-       orig_len = rte_pktmbuf_pkt_len(md);
+       uint32_t pkt_len = rte_pktmbuf_pkt_len(m);
+       uint32_t flags;
 
-       /* Take snapshot of the data */
-       mc = rte_pktmbuf_copy(md, mp, 0, length);
-       if (unlikely(mc == NULL))
-               return NULL;
-
-       /* Expand any offloaded VLAN information */
-       if ((direction == RTE_PCAPNG_DIRECTION_IN &&
-            (md->ol_flags & RTE_MBUF_F_RX_VLAN_STRIPPED)) ||
-           (direction == RTE_PCAPNG_DIRECTION_OUT &&
-            (md->ol_flags & RTE_MBUF_F_TX_VLAN))) {
-               if (pcapng_vlan_insert(mc, RTE_ETHER_TYPE_VLAN,
-                                      md->vlan_tci) != 0)
-                       goto fail;
-       }
+       if (unlikely(pcapng_mbuf_pad32(m) < 0))
+               return -1;
 
-       if ((direction == RTE_PCAPNG_DIRECTION_IN &&
-            (md->ol_flags & RTE_MBUF_F_RX_QINQ_STRIPPED)) ||
-           (direction == RTE_PCAPNG_DIRECTION_OUT &&
-            (md->ol_flags & RTE_MBUF_F_TX_QINQ))) {
-               if (pcapng_vlan_insert(mc, RTE_ETHER_TYPE_QINQ,
-                                      md->vlan_tci_outer) != 0)
-                       goto fail;
-       }
+       uint16_t optlen = pcapng_optlen(sizeof(flags));
 
-       /* record HASH on incoming packets */
-       rss_hash = (direction == RTE_PCAPNG_DIRECTION_IN &&
-                   (md->ol_flags & RTE_MBUF_F_RX_RSS_HASH));
+       /* make queue optional? */
+       optlen += pcapng_optlen(sizeof(queue));
 
-       /* pad the packet to 32 bit boundary */
-       pkt_len = rte_pktmbuf_pkt_len(mc);
-       padding = RTE_ALIGN(pkt_len, sizeof(uint32_t)) - pkt_len;
-       if (padding > 0) {
-               void *tail = rte_pktmbuf_append(mc, padding);
+       /* does packet have valid RSS hash to include */
+       bool rss_hash = (direction == RTE_PCAPNG_DIRECTION_IN &&
+                        (m->ol_flags & RTE_MBUF_F_RX_RSS_HASH));
 
-               if (tail == NULL)
-                       goto fail;
-               memset(tail, 0, padding);
-       }
-
-       optlen = pcapng_optlen(sizeof(flags));
-       optlen += pcapng_optlen(sizeof(queue));
        if (rss_hash)
                optlen += pcapng_optlen(sizeof(uint8_t) + sizeof(uint32_t));
 
@@ -540,10 +514,10 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
                optlen += pcapng_optlen(strlen(comment));
 
        /* reserve trailing options and block length */
-       opt = (struct pcapng_option *)
-               rte_pktmbuf_append(mc, optlen + sizeof(uint32_t));
+       struct pcapng_option *opt = (struct pcapng_option *)
+               rte_pktmbuf_append(m, optlen + sizeof(uint32_t));
        if (unlikely(opt == NULL))
-               goto fail;
+               return -1;
 
        switch (direction) {
        case RTE_PCAPNG_DIRECTION_IN:
@@ -556,24 +530,20 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
                flags = 0;
        }
 
-       opt = pcapng_add_option(opt, PCAPNG_EPB_FLAGS,
-                               &flags, sizeof(flags));
-
-       opt = pcapng_add_option(opt, PCAPNG_EPB_QUEUE,
-                               &queue, sizeof(queue));
+       opt = pcapng_add_option(opt, PCAPNG_EPB_FLAGS, &flags, sizeof(flags));
+       opt = pcapng_add_option(opt, PCAPNG_EPB_QUEUE, &queue, sizeof(queue));
 
        if (rss_hash) {
                uint8_t hash_opt[5];
 
-               /* The algorithm could be something else if
-                * using rte_flow_action_rss; but the current API does not
-                * have a way for ethdev to report  this on a per-packet basis.
+               /* The algorithm could be something else but the current API 
does not
+                * have a way for to record this on a per-packet basis
+                * and the PCAPNG hash types don't match the DPDK types.
                 */
                hash_opt[0] = PCAPNG_HASH_TOEPLITZ;
 
-               memcpy(&hash_opt[1], &md->hash.rss, sizeof(uint32_t));
-               opt = pcapng_add_option(opt, PCAPNG_EPB_HASH,
-                                       &hash_opt, sizeof(hash_opt));
+               memcpy(&hash_opt[1], &m->hash.rss, sizeof(uint32_t));
+               opt = pcapng_add_option(opt, PCAPNG_EPB_HASH, &hash_opt, 
sizeof(hash_opt));
        }
 
        if (comment)
@@ -583,19 +553,14 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
        /* Note: END_OPT necessary here. Wireshark doesn't do it. */
 
        /* Add PCAPNG packet header */
-       epb = (struct pcapng_enhance_packet_block *)
-               rte_pktmbuf_prepend(mc, sizeof(*epb));
+       epb = (struct pcapng_enhance_packet_block *) rte_pktmbuf_prepend(m, 
sizeof(*epb));
        if (unlikely(epb == NULL))
-               goto fail;
+               return -1;
 
        epb->block_type = PCAPNG_ENHANCED_PACKET_BLOCK;
-       epb->block_length = rte_pktmbuf_pkt_len(mc);
-
-       /* Interface index is filled in later during write */
-       mc->port = port_id;
+       epb->block_length = rte_pktmbuf_pkt_len(m);
 
-       /* Put timestamp in cycles here - adjust in packet write */
-       timestamp = rte_get_tsc_cycles();
+       /* Put timestamp in cycles here - adjusted in packet write */
        epb->timestamp_hi = timestamp >> 32;
        epb->timestamp_lo = (uint32_t)timestamp;
        epb->capture_length = pkt_len;
@@ -603,9 +568,56 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
 
        /* set trailer of block length */
        *(uint32_t *)opt = epb->block_length;
+       return 0;
+}
+
+/* Make a copy of original mbuf with pcapng header and options */
+RTE_EXPORT_SYMBOL(rte_pcapng_copy)
+struct rte_mbuf *
+rte_pcapng_copy(uint16_t port_id, uint32_t queue,
+               const struct rte_mbuf *md,
+               struct rte_mempool *mp,
+               uint32_t length,
+               enum rte_pcapng_direction direction,
+               const char *comment)
+{
+       uint32_t orig_len = rte_pktmbuf_pkt_len(md);
+       struct rte_mbuf *mc;
 
-       return mc;
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
+#endif
+
+       /* Take snapshot of the data */
+       mc = rte_pktmbuf_copy(md, mp, 0, length);
+       if (unlikely(mc == NULL))
+               return NULL;
+
+       /* Expand any offloaded VLAN information */
+       if ((direction == RTE_PCAPNG_DIRECTION_IN &&
+            (md->ol_flags & RTE_MBUF_F_RX_VLAN_STRIPPED)) ||
+           (direction == RTE_PCAPNG_DIRECTION_OUT &&
+            (md->ol_flags & RTE_MBUF_F_TX_VLAN))) {
+               if (pcapng_vlan_insert(mc, RTE_ETHER_TYPE_VLAN,
+                                      md->vlan_tci) != 0)
+                       goto fail;
+       }
+
+       if ((direction == RTE_PCAPNG_DIRECTION_IN &&
+            (md->ol_flags & RTE_MBUF_F_RX_QINQ_STRIPPED)) ||
+           (direction == RTE_PCAPNG_DIRECTION_OUT &&
+            (md->ol_flags & RTE_MBUF_F_TX_QINQ))) {
+               if (pcapng_vlan_insert(mc, RTE_ETHER_TYPE_QINQ,
+                                      md->vlan_tci_outer) != 0)
+                       goto fail;
+       }
+
+       /* Interface index is filled in later during write */
+       mc->port = port_id;
 
+       if (likely(rte_pcapng_insert(mc, queue, direction, orig_len,
+                                    rte_get_tsc_cycles(), comment) == 0))
+               return mc;
 fail:
        rte_pktmbuf_free(mc);
        return NULL;
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index 48f2b57564..4914ac9622 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -99,7 +99,7 @@ enum rte_pcapng_direction {
 };
 
 /**
- * Format an mbuf for writing to file.
+ * Make a copy of mbuf for writing to file.
  *
  * @param port_id
  *   The Ethernet port on which packet was received
@@ -117,7 +117,7 @@ enum rte_pcapng_direction {
  * @param direction
  *   The direction of the packer: receive, transmit or unknown.
  * @param comment
- *   Packet comment.
+ *   Packet comment (optional).
  *
  * @return
  *   - The pointer to the new mbuf formatted for pcapng_write
@@ -129,6 +129,29 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
                uint32_t length,
                enum rte_pcapng_direction direction, const char *comment);
 
+/**
+ * Format an mbuf for writing to file.
+ *
+ * @param m
+ *   The mbuf to modify.
+ * @param queue
+ *   The queue on the Ethernet port where packet was received
+ *   or is going to be transmitted.
+ * @param direction
+ *   The direction of the packer: receive, transmit or unknown.
+ * @param orig_len
+ *   The length of the original packet which maybe less than actual
+ *   packet if only a snapshot was captured.
+ * @param timestamp
+ *   The timestamp for packet in TSC cycles.
+ * @param comment
+ *   Packet comment (optional).
+ */
+__rte_experimental
+int
+rte_pcapng_insert(struct rte_mbuf *m, uint32_t queue,
+                 enum rte_pcapng_direction direction, uint32_t orig_len,
+                 uint64_t timestamp, const char *comment);
 
 /**
  * Determine optimum mbuf data size.
-- 
2.47.2

Reply via email to