When the source port has VLAN strip enabled, captured packets have the VLAN tag in mbuf metadata (vlan_tci) but not in the packet data. Similarly, TX captures with pending VLAN insert have the tag only in metadata. The resulting pcap files contain untagged packets.
Convert RX_VLAN_STRIPPED metadata to TX_VLAN offload requests on dequeued mbufs and call rte_eth_tx_prepare() before rte_eth_tx_burst() so the pcap vdev inserts the tag into the packet data. Signed-off-by: Stephen Hemminger <[email protected]> --- lib/pdump/rte_pdump.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/pdump/rte_pdump.c b/lib/pdump/rte_pdump.c index ac94efe7ff..6ffe72e284 100644 --- a/lib/pdump/rte_pdump.c +++ b/lib/pdump/rte_pdump.c @@ -9,6 +9,7 @@ #include <rte_mbuf.h> #include <rte_ethdev.h> #include <rte_lcore.h> +#include <rte_ether.h> #include <rte_log.h> #include <rte_memzone.h> #include <rte_errno.h> @@ -135,6 +136,29 @@ pdump_cb_release(struct pdump_rxtx_cbs *cbs) rte_atomic_store_explicit(&cbs->use_count, count, rte_memory_order_release); } +/* + * Reconstruct VLAN tag in packet data if it was offloaded to metadata. + * + * When VLAN strip is active on RX, or VLAN insert is pending on TX, + * the VLAN tag exists only in mbuf metadata (vlan_tci / ol_flags) + * and not in the packet data. For packet capture we need the + * complete wire-format packet, so insert the tag back into the + * cloned mbuf. + */ +static inline void +pdump_vlan_restore(struct rte_mbuf *m) +{ + if (m->ol_flags & (RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_TX_VLAN)) { + if (rte_vlan_insert(&m) != 0) + return; + /* + * Clear offload flags so the pcap writer sees the packet + * as a plain tagged frame rather than acting on these again. + */ + m->ol_flags &= ~(RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_TX_VLAN); + } +} + /* Create a clone of mbuf to be placed into ring. */ static void pdump_copy_burst(uint16_t port_id, uint16_t queue_id, @@ -182,8 +206,14 @@ pdump_copy_burst(uint16_t port_id, uint16_t queue_id, if (unlikely(p == NULL)) rte_atomic_fetch_add_explicit(&stats->nombuf, 1, rte_memory_order_relaxed); - else + else { + /* + * Restore any VLAN tag that was offloaded to metadata + * so the captured packet has the complete wire format. + */ + pdump_vlan_restore(p); dup_bufs[d_pkts++] = p; + } } if (d_pkts == 0) -- 2.51.0

