Skip to content

Conversation

@christophefontaine
Copy link
Collaborator

@christophefontaine christophefontaine commented Nov 25, 2025

For packet duplication or fragmentation, traces must be duplicated as the packet may go through different paths.

Summary by CodeRabbit

  • New Features

    • Deep-copy of packets now preserves private metadata and full per-packet trace history (timestamps, node IDs, trace payloads) when cloning.
  • Bug Fixes

    • IP fragmentation now uses the trace-preserving copy so fragments retain the original packet's trace records and continuity.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Added gr_mbuf_trace_copy(dst, src) (implementation in modules/infra/datapath/trace.c, declaration in modules/infra/datapath/gr_mbuf.h) to clone all trace items from a source rte_mbuf into a destination. Added static inline struct rte_mbuf *gr_mbuf_copy(struct rte_mbuf *m, size_t data_len, size_t priv_len) in modules/infra/datapath/gr_mbuf.h to deep-copy an mbuf, copy its private data, and invoke trace copying when present. Replaced rte_pktmbuf_copy(...) with gr_mbuf_copy(...) for IP fragment creation in modules/ip/datapath/ip_fragment.c and removed explicit propagation of ip_output_mbuf_data to fragment mbufs.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately describes the main change: adding trace deepcopy functionality for packet duplication and fragmentation.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1bc286d and adbab34.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d52a09 and 22aaf73.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{c,h}

⚙️ CodeRabbit configuration file

**/*.{c,h}: - gr_vec_*() functions cannot fail. No need to check their return value.

  • gr_vec_free(x) always sets x = NULL. There is no risk of double free.
  • ec_node_*() functions consume their ec_node arguments. No leaks on error.
  • rte_node->ctx is an uint8_t array of size 16, not a pointer.
  • Don't suggest to replace assert() with graceful error checking.
  • We compile with -std=gnu2x. Unnamed parameters in function definitions are valid.

Files:

  • modules/infra/datapath/gr_mbuf.h
  • modules/infra/datapath/trace.c
  • modules/ip/datapath/ip_fragment.c
🧬 Code graph analysis (3)
modules/infra/datapath/gr_mbuf.h (1)
modules/infra/datapath/trace.c (2)
  • gr_mbuf_trace_copy (621-653)
  • gr_mbuf_trace_finish (655-671)
modules/infra/datapath/trace.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_traces (47-49)
modules/ip/datapath/ip_fragment.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_copy (79-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build-and-tests (gcc-13, none, debugoptimized, ubuntu-24.04, -Dfrr=enabled, false)
  • GitHub Check: build-and-tests (gcc-14, address, debug, ubuntu-24.04, -Dfrr=enabled, true)
  • GitHub Check: rpm
🔇 Additional comments (3)
modules/ip/datapath/ip_fragment.c (1)

99-99: LGTM! Trace-aware fragment copy.

The switch to gr_mbuf_copy correctly preserves trace data when creating fragment copies, which is essential for fragments that take different paths through the network stack.

modules/infra/datapath/gr_mbuf.h (1)

78-87: LGTM! Clean deep-copy helper.

The implementation correctly performs a full mbuf copy including private data and traces. The sequence of operations (mbuf copy → priv data copy → trace copy) is sound.

modules/infra/datapath/trace.c (1)

621-653: LGTM with a note on intended usage.

The implementation correctly performs a deep copy of all trace items. The allocation loop with eviction ensures robustness.

Note: Line 628's STAILQ_INIT would leak any pre-existing independent traces in dst. This is fine for the intended usage (via gr_mbuf_copy on a freshly copied mbuf), but calling this function standalone on an mbuf that already has traces would leak them. Consider adding a comment clarifying the expected usage pattern.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
modules/infra/datapath/gr_mbuf.h (1)

67-73: Return value doc mismatch already flagged.

The implementation in trace.c always returns 0 (never fails). See past review.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22aaf73 and 44ee664.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{c,h}

⚙️ CodeRabbit configuration file

**/*.{c,h}: - gr_vec_*() functions cannot fail. No need to check their return value.

  • gr_vec_free(x) always sets x = NULL. There is no risk of double free.
  • ec_node_*() functions consume their ec_node arguments. No leaks on error.
  • rte_node->ctx is an uint8_t array of size 16, not a pointer.
  • Don't suggest to replace assert() with graceful error checking.
  • We compile with -std=gnu2x. Unnamed parameters in function definitions are valid.

Files:

  • modules/infra/datapath/trace.c
  • modules/infra/datapath/gr_mbuf.h
  • modules/ip/datapath/ip_fragment.c
🧬 Code graph analysis (3)
modules/infra/datapath/trace.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_traces (47-49)
modules/infra/datapath/gr_mbuf.h (1)
modules/infra/datapath/trace.c (2)
  • gr_mbuf_trace_copy (621-653)
  • gr_mbuf_trace_finish (655-671)
modules/ip/datapath/ip_fragment.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_copy (79-87)
🔇 Additional comments (2)
modules/infra/datapath/trace.c (1)

621-653: LGTM.

The deep copy logic is correct: resets destination, allocates new trace items (evicting oldest if necessary), copies all fields including payload. Pattern matches existing gr_mbuf_trace_add.

modules/ip/datapath/ip_fragment.c (1)

99-102: Good use of gr_mbuf_copy, but note the upstream fix needed.

The switch to gr_mbuf_copy correctly preserves traces for fragmented packets. Once the buffer overflow in gr_mbuf_copy is fixed (see gr_mbuf.h review), consider whether line 125's explicit *ip_output_mbuf_data(frag_mbuf) = *ip_output_mbuf_data(mbuf) is still needed—it may become redundant.

@christophefontaine christophefontaine marked this pull request as draft November 25, 2025 16:48
@christophefontaine christophefontaine marked this pull request as ready for review November 25, 2025 21:00
@christophefontaine
Copy link
Collaborator Author

@rjarry I updated the size of the copy, you'll want to double check before merging :)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 44ee664 and 47d1a30.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • modules/ip/datapath/ip_fragment.c
  • modules/infra/datapath/gr_mbuf.h
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{c,h}

⚙️ CodeRabbit configuration file

**/*.{c,h}: - gr_vec_*() functions cannot fail. No need to check their return value.

  • gr_vec_free(x) always sets x = NULL. There is no risk of double free.
  • ec_node_*() functions consume their ec_node arguments. No leaks on error.
  • rte_node->ctx is an uint8_t array of size 16, not a pointer.
  • Don't suggest to replace assert() with graceful error checking.
  • We compile with -std=gnu2x. Unnamed parameters in function definitions are valid.

Files:

  • modules/infra/datapath/trace.c
🧬 Code graph analysis (1)
modules/infra/datapath/trace.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_traces (47-49)

@christophefontaine christophefontaine force-pushed the gr_mbuf_deepcopy branch 2 times, most recently from a4107ab to a3108b5 Compare November 26, 2025 09:22
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
modules/infra/datapath/gr_mbuf.h (2)

67-71: Clarify gr_mbuf_trace_copy preconditions on dst traces

gr_mbuf_trace_copy reinitializes the destination trace head before appending new items, so calling it on an mbuf that already has traces would drop (and effectively leak) the existing chain. If the intended invariant is “dst has no traces” (only used on fresh clones), it’d be good to document that here or enforce it with an assert(!gr_mbuf_is_traced(dst)) to catch accidental misuse.


76-88: Document and verify assumptions between mbuf_data_type and mbuf_data() layout

__gr_mbuf_copy always copies from/to mbuf_data(m)/mbuf_data(copy), while priv_len comes from sizeof(mbuf_data_type) via the macro. This relies on every caller passing a type whose size/layout matches the region pointed to by mbuf_data(), otherwise you risk silent over/under‑copy (and potential overwrite of adjacent private data). I’d explicitly state that contract in the comment (and ideally keep callers using a single typedef/alias for the mbuf private area) so gr_mbuf_copy(m, data_len, ...) can’t be accidentally used with an incompatible struct like a larger per‑feature view.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4107ab and a3108b5.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • modules/ip/datapath/ip_fragment.c
  • modules/infra/datapath/trace.c
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{c,h}

⚙️ CodeRabbit configuration file

**/*.{c,h}: - gr_vec_*() functions cannot fail. No need to check their return value.

  • gr_vec_free(x) always sets x = NULL. There is no risk of double free.
  • ec_node_*() functions consume their ec_node arguments. No leaks on error.
  • rte_node->ctx is an uint8_t array of size 16, not a pointer.
  • Don't suggest to replace assert() with graceful error checking.
  • We compile with -std=gnu2x. Unnamed parameters in function definitions are valid.

Files:

  • modules/infra/datapath/gr_mbuf.h
🧠 Learnings (1)
📚 Learning: 2025-10-03T13:34:31.801Z
Learnt from: rjarry
Repo: DPDK/grout PR: 329
File: modules/ip/cli/route.c:51-66
Timestamp: 2025-10-03T13:34:31.801Z
Learning: The `gr_api_client_stream_foreach` macro in `api/gr_api.h` always sets its `ret` parameter during the first outer loop condition evaluation (via `if (__first == 1) ret = __id;`), even when the stream yields zero items. Therefore, the `ret` variable does not need to be initialized at declaration when used with this macro.

Applied to files:

  • modules/infra/datapath/gr_mbuf.h
🧬 Code graph analysis (1)
modules/infra/datapath/gr_mbuf.h (1)
modules/infra/datapath/trace.c (2)
  • gr_mbuf_trace_copy (621-651)
  • gr_mbuf_trace_finish (653-669)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: build-and-tests (gcc-14, address, debug, ubuntu-24.04, -Dfrr=enabled, true)
  • GitHub Check: build-and-tests (gcc-13, none, debugoptimized, ubuntu-24.04, -Dfrr=enabled, false)
  • GitHub Check: build-and-tests (clang-18, none, debugoptimized, ubuntu-24.04, false)
  • GitHub Check: build-and-tests (clang-16, none, debugoptimized, ubuntu-24.04, false)
  • GitHub Check: build-and-tests (clang-15, none, debugoptimized, ubuntu-22.04, false)
  • GitHub Check: build-cross-aarch64
  • GitHub Check: deb
  • GitHub Check: rpm

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
modules/infra/datapath/trace.c (1)

621-651: Make src const and document/guard the “fresh dst” assumption

The copy loop never mutates src, so the signature can safely be:

-void gr_mbuf_trace_copy(struct rte_mbuf *dst, struct rte_mbuf *src) {
+void gr_mbuf_trace_copy(struct rte_mbuf *dst, const struct rte_mbuf *src) {

Also, STAILQ_INIT(dst_traces) assumes dst has no live traces; if this function is ever used on reused mbufs, existing trace chains would be dropped and leaked. Given current usage via freshly-allocated copies this is fine, but you might want a debug guard to lock in that contract:

 void gr_mbuf_trace_copy(struct rte_mbuf *dst, const struct rte_mbuf *src) {
 	struct gr_trace_head *src_traces = gr_mbuf_traces(src);
 	struct gr_trace_head *dst_traces = gr_mbuf_traces(dst);
@@
-	// Reset trace head
-	STAILQ_INIT(dst_traces);
+	// dst is expected to be a fresh mbuf without traces.
+	assert(STAILQ_EMPTY(dst_traces));
+	STAILQ_INIT(dst_traces);
🧹 Nitpick comments (1)
modules/ip/datapath/ip_fragment.c (1)

83-90: Clarify whether duplicated ip_fragment trace entries on later fragments are intended

With gr_mbuf_copy(mbuf, ...) cloning all existing trace items and the ip_fragment_trace_data for fragment 0 being added to mbuf before the loop, every extra fragment now inherits that “frag=0 offset=0 MF” entry and then gets its own frag=i entry via gr_mbuf_trace_add(frag_mbuf, ...). For i > 0, trace dumps will show two ip_fragment records per packet.

If you only want per-fragment entries (plus the shared pre-fragment history), consider reordering so that:

  • you create the extra fragments with gr_mbuf_copy while mbuf still has no ip_fragment_trace_data, and
  • then add one ip_fragment_trace_data per fragment (including the first) afterwards.

Otherwise, maybe add a short comment that this duplication is deliberate so future readers don’t second‑guess it.

Also applies to: 97-135

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3108b5 and 54e864f.

📒 Files selected for processing (3)
  • modules/infra/datapath/gr_mbuf.h (1 hunks)
  • modules/infra/datapath/trace.c (1 hunks)
  • modules/ip/datapath/ip_fragment.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • modules/infra/datapath/gr_mbuf.h
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{c,h}

⚙️ CodeRabbit configuration file

**/*.{c,h}: - gr_vec_*() functions cannot fail. No need to check their return value.

  • gr_vec_free(x) always sets x = NULL. There is no risk of double free.
  • ec_node_*() functions consume their ec_node arguments. No leaks on error.
  • rte_node->ctx is an uint8_t array of size 16, not a pointer.
  • Don't suggest to replace assert() with graceful error checking.
  • We compile with -std=gnu2x. Unnamed parameters in function definitions are valid.

Files:

  • modules/infra/datapath/trace.c
  • modules/ip/datapath/ip_fragment.c
🧬 Code graph analysis (2)
modules/infra/datapath/trace.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_traces (47-49)
modules/ip/datapath/ip_fragment.c (1)
modules/infra/datapath/gr_mbuf.h (1)
  • gr_mbuf_copy (77-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build-and-tests (clang-16, none, debugoptimized, ubuntu-24.04, false)
  • GitHub Check: build-and-tests (clang-18, none, debugoptimized, ubuntu-24.04, false)
  • GitHub Check: build-and-tests (clang-15, none, debugoptimized, ubuntu-22.04, false)
  • GitHub Check: build-and-tests (gcc-14, address, debug, ubuntu-24.04, -Dfrr=enabled, true)
  • GitHub Check: build-and-tests (gcc-13, none, debugoptimized, ubuntu-24.04, -Dfrr=enabled, false)
  • GitHub Check: deb
  • GitHub Check: rpm

Copy link
Collaborator

@aharivel aharivel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

Suggested-by: David Marchand <[email protected]>
Signed-off-by: Christophe Fontaine <[email protected]>
Reviewed-by: Anthony Harivel <[email protected]>
Reviewed-by: Robin Jarry <[email protected]>
@rjarry rjarry merged commit 93e1c9f into DPDK:main Nov 27, 2025
6 of 7 checks passed
@christophefontaine christophefontaine deleted the gr_mbuf_deepcopy branch December 12, 2025 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants