Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions modules/infra/datapath/gr_mbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,22 @@ static inline bool gr_mbuf_is_traced(struct rte_mbuf *m) {
// Returns a pointer to a gr_trace_item.data buffer.
void *gr_mbuf_trace_add(struct rte_mbuf *m, struct rte_node *node, size_t data_len);

// Copy all trace items from source mbuf to destination mbuf.
//
// This creates a deep copy of the entire trace chain, preserving timestamps,
// node IDs, and trace data. Used when cloning packets to maintain trace history.
void gr_mbuf_trace_copy(struct rte_mbuf *dst, struct rte_mbuf *src);

// Detach the trace items from an mbuf and store them in the trace buffer.
void gr_mbuf_trace_finish(struct rte_mbuf *m);

// Deep copy of an mbuf: duplicates mbuf, copies mbuf priv data and traces
static inline struct rte_mbuf *gr_mbuf_copy(struct rte_mbuf *m, size_t data_len, size_t priv_len) {
struct rte_mbuf *copy = rte_pktmbuf_copy(m, m->pool, 0, data_len);
if (copy) {
memcpy(mbuf_data(copy), mbuf_data(m), priv_len);
if (gr_mbuf_is_traced(m))
gr_mbuf_trace_copy(copy, m);
}
return copy;
}
32 changes: 32 additions & 0 deletions modules/infra/datapath/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,38 @@ void *gr_mbuf_trace_add(struct rte_mbuf *m, struct rte_node *node, size_t data_l
return trace->data;
}

void gr_mbuf_trace_copy(struct rte_mbuf *dst, struct rte_mbuf *src) {
struct gr_trace_head *src_traces = gr_mbuf_traces(src);
struct gr_trace_head *dst_traces = gr_mbuf_traces(dst);
struct gr_trace_item *src_trace, *dst_trace;
void *data;

// Reset trace head
STAILQ_INIT(dst_traces);

// Copy each trace item from source to destination
STAILQ_FOREACH (src_trace, src_traces, next) {
// Allocate new trace item for destination
while (rte_mempool_get(trace_pool, &data) < 0) {
void *oldest = NULL;
rte_ring_dequeue(traced_packets, &oldest);
free_trace(oldest);
}

dst_trace = data;

// Copy all trace item data
dst_trace->ts = src_trace->ts;
dst_trace->cpu_id = src_trace->cpu_id;
dst_trace->node_id = src_trace->node_id;
dst_trace->len = src_trace->len;
memcpy(dst_trace->data, src_trace->data, src_trace->len);

// Add to destination trace chain
STAILQ_INSERT_TAIL(dst_traces, dst_trace, next);
}
}

void gr_mbuf_trace_finish(struct rte_mbuf *m) {
struct gr_trace_head *traces = gr_mbuf_traces(m);
struct gr_trace_item *trace = STAILQ_FIRST(traces);
Expand Down
5 changes: 3 additions & 2 deletions modules/ip/datapath/ip_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ ip_fragment_process(struct rte_graph *graph, struct rte_node *node, void **objs,
// Create and enqueue remaining fragments
for (i = 1; i < num_frags; i++) {
// Create new fragment, copying the original IPv4 header.
frag_mbuf = rte_pktmbuf_copy(mbuf, mbuf->pool, 0, ip_hdr_len);
frag_mbuf = gr_mbuf_copy(
mbuf, ip_hdr_len, sizeof(struct ip_output_mbuf_data)
);
if (unlikely(frag_mbuf == NULL)) {
break;
}
Expand All @@ -122,7 +124,6 @@ ip_fragment_process(struct rte_graph *graph, struct rte_node *node, void **objs,
frag_ip->hdr_checksum = 0;
frag_ip->hdr_checksum = rte_ipv4_cksum(frag_ip);

*ip_output_mbuf_data(frag_mbuf) = *ip_output_mbuf_data(mbuf);
frag_mbuf->packet_type = mbuf->packet_type;
if (gr_mbuf_is_traced(mbuf)) {
struct ip_fragment_trace_data *t;
Expand Down