incremental checksums: net helpers - #1849
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (21)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: 3 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour. 📝 WalkthroughWalkthroughThe changes add incremental transport checksum updates for address and 16-bit field changes. NAT paths use these updates and request full checksum refresh when required. The changes also define computed-zero UDP encoding, add IPv6 UDP zero-checksum detection, and allow IPv6 packets to proceed through VXLAN encapsulation. ChangesTransport checksum updates
Suggested reviewers: Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to The checksum and encapsulation changes have no established merge-blocking issue in the supplied evidence; proceed with normal checks. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 71.11% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 90 functions across 16 files. (6 skipped: 6 unsupported.)
Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
RFC 1624 computes 0x0000 when the new one's-complement sum is zero. A full recompute agrees unless every covered word is zero: all-zero data sums to +0, whose checksum is 0xFFFF, and a stored 0x0000 fails validation. An echo reply with identifier 1, sequence 0 and no payload reaches it when the identifier is translated to 0. Only ICMPv4 can get there. Every other transport has a pseudo-header with a non-zero protocol number and length in it, and UDP already writes a computed 0 as 0xFFFF. Which of the two cases applies depends on the payload, which `Transport` cannot see, so the update refuses and leaves it to a full recompute. `increment_checksum_for_u16` now returns whether it updated the checksum, as `increment_checksum_for_address` already does. Reported in review of #1849. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`increment_checksum_for_address` returned early for ICMPv4, which has no pseudo-header, before checking the address families. An ICMPv4 transport given a v4-to-v6 change therefore reported the update as done, contradicting the documented contract that a version change is refused and left to a full recompute. Check the families first. Reported in review of #1849. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RFC 1624 computes 0x0000 when the new one's-complement sum is zero. A full recompute agrees unless every covered word is zero: all-zero data sums to +0, whose checksum is 0xFFFF, and a stored 0x0000 fails validation. An echo reply with identifier 1, sequence 0 and no payload reaches it when the identifier is translated to 0. Only ICMPv4 can get there. Every other transport has a pseudo-header with a non-zero protocol number and length in it, and UDP already writes a computed 0 as 0xFFFF. Which of the two cases applies depends on the payload, which `Transport` cannot see, so the update refuses and leaves it to a full recompute. `increment_checksum_for_u16` now returns whether it updated the checksum, as `increment_checksum_for_address` already does. Reported in review of #1849. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`increment_checksum_for_address` returned early for ICMPv4, which has no pseudo-header, before checking the address families. An ICMPv4 transport given a v4-to-v6 change therefore reported the update as done, contradicting the documented contract that a version change is refused and left to a full recompute. Check the families first. Reported in review of #1849. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2b4d644 to
b9365c0
Compare
3afbdc4 to
36fabb5
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Two moderate logic issues remain in checksum handling and test packet construction.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Adds incremental checksum helpers for transport fields and IP addresses, with UDP zero-checksum normalization and expanded ICMP fixtures/tests.
Changes:
- Adds UDP checksum conversion.
- Adds incremental checksum updates for transport fields and IP addresses.
- Extends embedded checksum handling and test coverage.
| File | Summary |
|---|---|
net/src/udp/checksum.rs |
Adds UDP checksum wire-value conversion. |
net/src/packet/test_utils.rs |
Adds ICMP fixtures; cross-family protocol combinations need handling. |
net/src/headers/mod.rs |
Adds incremental helpers and tests; IPv6 UDP zero checksums need correct handling. |
net/src/headers/embedded.rs |
Reuses UDP conversion and exposes address-word helpers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
36fabb5 to
aecbd87
Compare
aecbd87 to
227566f
Compare
Move UDP zero normalization to `UdpChecksum::from_computed` for reuse by `Transport`. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add RFC 1624 helpers for port, address, and ICMP identifier changes. Preserve disabled IPv4 UDP checksums and store computed zeros as 0xFFFF. `Headers::has_zero_ipv6_udp_checksum` flags the IPv6 zero, which only a full recompute can repair. Request full recomputation for ambiguous ICMPv4 zero results. The address helper is generic over `IpAddress`, so an IP version change cannot be expressed and the update cannot fail. It folds the whole address in one step. `Net::try_set_source_updating_checksum` and `try_set_destination_updating_checksum` set an address and fold it into the transport checksum under the version match `Net` already does. Compare updates with full recomputation in Bolero properties. A further property covers what a checksum-correct packet never reaches: unchanged values, a missing transport, and disabled UDP checksums. Test the zero-checksum and version-mismatch boundaries. NAT integration follows in #1809. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
227566f to
7d57087
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Address the four unresolved moderate checksum-handling issues before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
Resolved since last review (2)
| if let Some(transport) = transport { | ||
| transport.increment_checksum_for_address(old, addr); | ||
| } |
mvachhar
left a comment
There was a problem hiding this comment.
@daniel-noland I'll leave it to you to decide if we should have duvet enforcement for these two changes.
|
|
||
| /// Convert a computed checksum to its wire value. | ||
| /// | ||
| /// Send a computed zero as `0xFFFF`, since a stored zero disables the checksum (RFC 768). |
There was a problem hiding this comment.
Do we want a duvet assertion here?
| /// | ||
| /// Returns [`NetError::InvalidIpVersion`], changing nothing, if the IP version of `addr` does | ||
| /// not match the IP version of the network header. | ||
| pub fn try_set_source_updating_checksum( |
There was a problem hiding this comment.
Duvet for the checksum RFC?
Vendor RFC 6935 and RFC 8200. Cite RFC 6935 section 5, which requires a computed UDP checksum of zero to be sent as 0xFFFF, at `UdpChecksum::from_computed` and at the test that drives an update to zero. RFC 8200 section 8.1 carries the same rule in lowercase, so duvet extracts no requirements from it. It is vendored so the report shows it was considered, and so later citations of it need no new specification. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Build ICMPv4 and ICMPv6 echo requests so NAT tests can exercise identifier and checksum updates. Each builder rejects the other family's ICMP. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Skip header checksum updates for IPv6, which has no header checksum. Add a regression test for VXLAN encapsulation without a refresh request. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Use `Transport` for ICMPv4 and ICMPv6 identifier updates so checksum helpers can dispatch by version. Identifier errors now use `TransportError::UnsupportedIdentifier`. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Apply address, port, and ICMP identifier deltas with the new `Transport` helpers, requesting full recomputation when needed, including for an IPv6 UDP checksum of zero, which cannot take a delta. Compare SNAT and DNAT results with full recomputation for TCP and ICMP. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Let `snat` and `dnat` decide when a refresh is needed. Check through the network function that translations produce correct checksums without requesting full recomputation. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Apply address and port checksum deltas in both translation directions. Keep ICMPv4 checksums unchanged for address-only updates and adjust ICMPv6 pseudo-header checksums. Request full recomputation for an IPv6 UDP checksum of zero, which cannot take a delta. Compare translated checksums with full recomputation in tests. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fold address changes as they are set, borrowing the network and transport headers together through `Headers::net_and_transport_mut`. Capture port deltas before translation and apply them after the `TcpUdpMut` borrow ends. Keep full recomputation for ICMP errors, whose checksums cover the quote, and for an IPv6 UDP checksum of zero, which cannot take a delta. Check checksum validity in the marking properties and add a test through `StaticNat::process`. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Only set `checksum_refresh` when recomputation is needed; leave existing requests intact when an update succeeds incrementally. `Packet::update_checksums` clears the flag after recomputation. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Request full recomputation in masquerade and port-forwarding ICMP error handlers because the outer checksum covers the modified quote. A truncated TCP checksum or disabled UDP checksum can prevent inner checksum updates from preserving the outer sum. Add a shared assertion for current checksums or pending refresh requests and apply it to ICMP error tests, including a port-forwarding test through the ICMP error handler. Signed-off-by: Daniel Noland <daniel@githedgehog.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

No description provided.