Skip to content

Commit 54e864f

Browse files
infra: add gr_mbuf deepcopy
For packet duplication or fragmentation, traces must be duplicated as the packet may go through different paths. Add: - a helper to copy traces - a helper to copy the mbuf, its payload, specific mbuf_data and traces. Signed-off-by: Christophe Fontaine <cfontain@redhat.com>
1 parent 2d52a09 commit 54e864f

3 files changed

Lines changed: 52 additions & 2 deletions

File tree

modules/infra/datapath/gr_mbuf.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,22 @@ static inline bool gr_mbuf_is_traced(struct rte_mbuf *m) {
6464
// Returns a pointer to a gr_trace_item.data buffer.
6565
void *gr_mbuf_trace_add(struct rte_mbuf *m, struct rte_node *node, size_t data_len);
6666

67+
// Copy all trace items from source mbuf to destination mbuf.
68+
//
69+
// This creates a deep copy of the entire trace chain, preserving timestamps,
70+
// node IDs, and trace data. Used when cloning packets to maintain trace history.
71+
void gr_mbuf_trace_copy(struct rte_mbuf *dst, struct rte_mbuf *src);
72+
6773
// Detach the trace items from an mbuf and store them in the trace buffer.
6874
void gr_mbuf_trace_finish(struct rte_mbuf *m);
75+
76+
// Deep copy of an mbuf: duplicates mbuf, copies mbuf priv data and traces
77+
static inline struct rte_mbuf *gr_mbuf_copy(struct rte_mbuf *m, size_t data_len, size_t priv_len) {
78+
struct rte_mbuf *copy = rte_pktmbuf_copy(m, m->pool, 0, data_len);
79+
if (copy) {
80+
memcpy(mbuf_data(copy), mbuf_data(m), priv_len);
81+
if (gr_mbuf_is_traced(m))
82+
gr_mbuf_trace_copy(copy, m);
83+
}
84+
return copy;
85+
}

modules/infra/datapath/trace.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,38 @@ void *gr_mbuf_trace_add(struct rte_mbuf *m, struct rte_node *node, size_t data_l
618618
return trace->data;
619619
}
620620

621+
void gr_mbuf_trace_copy(struct rte_mbuf *dst, struct rte_mbuf *src) {
622+
struct gr_trace_head *src_traces = gr_mbuf_traces(src);
623+
struct gr_trace_head *dst_traces = gr_mbuf_traces(dst);
624+
struct gr_trace_item *src_trace, *dst_trace;
625+
void *data;
626+
627+
// Reset trace head
628+
STAILQ_INIT(dst_traces);
629+
630+
// Copy each trace item from source to destination
631+
STAILQ_FOREACH (src_trace, src_traces, next) {
632+
// Allocate new trace item for destination
633+
while (rte_mempool_get(trace_pool, &data) < 0) {
634+
void *oldest = NULL;
635+
rte_ring_dequeue(traced_packets, &oldest);
636+
free_trace(oldest);
637+
}
638+
639+
dst_trace = data;
640+
641+
// Copy all trace item data
642+
dst_trace->ts = src_trace->ts;
643+
dst_trace->cpu_id = src_trace->cpu_id;
644+
dst_trace->node_id = src_trace->node_id;
645+
dst_trace->len = src_trace->len;
646+
memcpy(dst_trace->data, src_trace->data, src_trace->len);
647+
648+
// Add to destination trace chain
649+
STAILQ_INSERT_TAIL(dst_traces, dst_trace, next);
650+
}
651+
}
652+
621653
void gr_mbuf_trace_finish(struct rte_mbuf *m) {
622654
struct gr_trace_head *traces = gr_mbuf_traces(m);
623655
struct gr_trace_item *trace = STAILQ_FIRST(traces);

modules/ip/datapath/ip_fragment.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ ip_fragment_process(struct rte_graph *graph, struct rte_node *node, void **objs,
9696
// Create and enqueue remaining fragments
9797
for (i = 1; i < num_frags; i++) {
9898
// Create new fragment, copying the original IPv4 header.
99-
frag_mbuf = rte_pktmbuf_copy(mbuf, mbuf->pool, 0, ip_hdr_len);
99+
frag_mbuf = gr_mbuf_copy(
100+
mbuf, ip_hdr_len, sizeof(struct ip_output_mbuf_data)
101+
);
100102
if (unlikely(frag_mbuf == NULL)) {
101103
break;
102104
}
@@ -122,7 +124,6 @@ ip_fragment_process(struct rte_graph *graph, struct rte_node *node, void **objs,
122124
frag_ip->hdr_checksum = 0;
123125
frag_ip->hdr_checksum = rte_ipv4_cksum(frag_ip);
124126

125-
*ip_output_mbuf_data(frag_mbuf) = *ip_output_mbuf_data(mbuf);
126127
frag_mbuf->packet_type = mbuf->packet_type;
127128
if (gr_mbuf_is_traced(mbuf)) {
128129
struct ip_fragment_trace_data *t;

0 commit comments

Comments
 (0)