Skip to content

fix: pass ICMP echo replies to kernel for interface-NAT addresses#439

Merged
psaab merged 2 commits intomasterfrom
fix/438-icmp-echo-reply-local-delivery
Apr 4, 2026
Merged

fix: pass ICMP echo replies to kernel for interface-NAT addresses#439
psaab merged 2 commits intomasterfrom
fix/438-icmp-echo-reply-local-delivery

Conversation

@psaab
Copy link
Copy Markdown
Owner

@psaab psaab commented Apr 4, 2026

Summary

  • XDP shim's is_icmp_to_interface_nat_local() only matched echo request (type 8), dropping locally-originated ping replies
  • Extended to also match echo reply (type 0) and ICMPv6 echo reply (type 129)
  • Added local firewall connectivity check to failover testing preflight

Test plan

  • ping -c 5 1.1.1.1 from primary fw: 0% loss (was 100%)
  • ping6 -c 3 2001:4860:4860::8888 from primary fw: 0% loss
  • Transit traffic (ping 172.16.80.200 from LAN host): still works
  • Cluster status healthy after deploy

Fixes #438

🤖 Generated with Claude Code

The XDP shim's is_icmp_to_interface_nat_local() only matched ICMP echo
request (type 8), causing locally-originated ping replies to be
redirected to XSK instead of the kernel. Extend the check to include
echo reply (type 0) and ICMPv6 echo reply (type 129).

Also add local firewall connectivity to failover testing preflight.

Fixes #438

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 06:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes locally-originated ping/ping6 from the firewall by ensuring the userspace XDP shim treats ICMP echo replies to interface-NAT addresses as kernel-delivery traffic, and documents a preflight check to catch regressions during failover testing.

Changes:

  • Extend is_icmp_to_interface_nat_local() to match ICMPv4 echo reply (type 0) and ICMPv6 echo reply (type 129) in addition to echo request.
  • Add a “Local firewall connectivity” preflight step to failover testing docs.
  • Add/update the embedded Rust userspace XDP compiled object (userspace_xdp_bpfel.o) used by the Go loader.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
userspace-xdp/src/lib.rs Pass ICMP echo replies to kernel for interface-NAT destinations so locally-originated pings succeed.
testing-docs/failover-testing.md Add a preflight checklist item to validate local firewall-originated connectivity before failover tests.
pkg/dataplane/userspace_xdp_bpfel.o Embed the rebuilt Rust XDP program artifact matching the shim logic change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1160 to +1162
// Echo request (8) and echo reply (0): both need kernel delivery
// for locally-originated pings. The kernel's own conntrack matches
// echo replies to the ping process.
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

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

The new comment implies both echo request and echo reply are seen for locally-originated pings, but locally-originated echo requests typically bypass XDP (kernel transmit path) and the shim mainly needs to pass echo replies (and inbound echo requests from remote peers) to the kernel. Consider rewording this comment to avoid misleading future readers about why type 8 is included here.

Suggested change
// Echo request (8) and echo reply (0): both need kernel delivery
// for locally-originated pings. The kernel's own conntrack matches
// echo replies to the ping process.
// Echo reply (0) must reach the kernel for locally-originated
// pings, since the kernel matches replies to the ping process.
// Echo request (8) is also allowed here so inbound requests to
// interface-local/NAT destinations are delivered to the kernel.

Copilot uses AI. Check for mistakes.
Comment on lines +119 to +123
```bash
# On the primary node (whichever owns reth0)
ping -c 3 1.1.1.1
ping6 -c 3 2001:4860:4860::8888
```
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

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

This preflight step hardcodes public Internet targets (1.1.1.1 / 2001:4860:4860::8888). In test environments without direct Internet egress (or with outbound ICMP filtered), this will fail even if the dataplane is healthy. Consider wording this as “ping a known reachable external IP/v6” (or provide an environment-specific target) to keep the checklist usable in isolated labs.

Copilot uses AI. Check for mistakes.
- Reword ICMP comment to clarify echo replies (locally-originated) vs
  echo requests (inbound from peers) per Copilot suggestion
- Note that preflight ping targets are examples; substitute in isolated labs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@psaab psaab merged commit b9b828d into master Apr 4, 2026
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.

XDP shim drops ICMP echo replies for interface-NAT addresses

2 participants