Skip to content

fix(net): route native IPv6 output across interfaces - #2321

Merged
fslongjin merged 2 commits into
DragonOS-Community:masterfrom
fslongjin:codex/ipv6-routed-output
Sep 22, 2026
Merged

fslongjin merged 2 commits into
DragonOS-Community:masterfrom
fslongjin:codex/ipv6-routed-output

Conversation

@fslongjin

@fslongjin fslongjin commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

Fix native IPv6 local traffic when the source address / TCP SocketSet owner and the namespace-selected output interface differ.

  • Route IPv6 through the existing namespace output pipeline, preserving full 128-bit next hops in queue contexts and neighbor retry keys.
  • Transfer local inbound IPv6 traffic to its address owner without losing physical ingress metadata. Keep NDP on the receiving link.
  • Honor egress MTU for TCP segmentation and validate fixed-source routes before consuming socket state.
  • Reuse existing FIB, neighbor cache and bounded queues; no separate IPv6 routing table or polling worker.
  • Add seven mandatory dunitest cases covering the complete bidirectional path, cold NDP, smaller egress MTU and error recovery.

Dependency

DragonOS-Community/smoltcp#32 has merged into dragonos/v0.12.0. The manifest and lockfile now pin merged commit afde7359455a5b9feacd2b8684994232acbf8903. Its Git tree is identical to the previously validated 4cfe0ddadd6c0f5a82a72245bf18c4df6f4bb8fd, so this follow-up changes dependency identity only.

make kernel passed again using the merged revision. The guest results below were obtained from the identical source tree before the revision-only update, not rerun for that update.

Root cause

The FIB already supported IPv6, but output classification forced native-owner transmission; queued next hops and the explicit-next-hop transmit API were IPv4-only. Cross-interface local IPv6 replies were also not handed to the owner. Using the owner's MTU prevented reliable large transfers through a smaller actual egress.

NDP needs special link semantics: a unicast advertisement may target a global address, so multicast checks alone are insufficient. The dependency fixes both the external override and the internal second route lookup for typed NDP.

Validation

Check Result
Pre-fix guest / Linux same SYN egress probe Guest 0 expected inbound SYNs; Linux 3
Post-fix same guest probe 4 expected inbound SYNs, 0 owner outgoing SYNs
make fmt, make kernel with public dependency revision Passed
Seven focused tests, Linux three rounds 21/21
Seven focused tests, fresh DragonOS guest ten rounds 70/70
Thirteen existing TCP/UDP regression suites 161/161
Real nginx fixed-source IPv6 cross-interface upstream HTTP 200 and exact 37-byte body
nginx IPv4/IPv6 HTTP and graceful master exit Passed
smoltcp tests and feature builds 653 tests, six configurations passed

Independent logic, security/concurrency and system/performance reviews completed; their actionable NDP finding was corrected and covered by library and guest regression tests.

Boundaries

This is host output/local delivery, not IPv6 router forwarding or NAT. Full scope-id and source-selection semantics are not added. Native IPv6 source fragmentation and IPV6_MTU_DISCOVER remain unsupported: oversized non-local UDP is rejected synchronously with EMSGSIZE, verified separately, rather than claimed to match Linux's default fragmentation behavior. The shared UDP regression tests the common MTU-sized behavior.

The nginx check uses a controlled single-worker configuration and a synthetic wire-level TCP/HTTP upstream. It is not an all-module nginx certification. Full repository CI remains to run.

Use the namespace FIB and socket device constraint for native IPv6 output instead of implicitly transmitting on the SocketSet owner. Keep the owner stable and hand incoming local IPv6 packets to it while preserving the physical ingress interface.

Generalize the existing bounded output and neighbor retry queues to complete IP addresses, including a full-width Patricia key and opaque route context. Activate configured-neighbor routing for both families and preserve existing IPv4 behavior.

Use the selected egress MTU for TCP segmentation through smoltcp 4cfe0dd, keep NDP on the receiving link, and reject unsupported oversized native IPv6 UDP output before enqueueing. Validate fixed-source routes before changing TCP state.

Add seven dunitest cases covering bidirectional cross-interface traffic, device constraints, 8192-byte TCP over MTU 1280, cold NDP, MTU-sized UDP, retry after ENETUNREACH, and global-source neighbor advertisements. Register them in whitelist and no_skip.

Validation: make fmt and make kernel passed using the public dependency revision; Linux reference 21/21, DragonOS repeated focused tests 70/70 and existing networking regressions 161/161 passed. Real nginx IPv6 upstream proxy, dual-stack HTTP and graceful exit passed. IPv6 source fragmentation, PMTU socket options and full scope-id support remain outside this change.
Signed-off-by: longjin <longjin@dragonos.org>
@github-actions github-actions Bot added the Bug fix A bug is fixed in this pull request label Sep 22, 2026
@fslongjin

Copy link
Copy Markdown
Member Author

@codex review

Update the manifest and lockfile to afde7359455a5b9feacd2b8684994232acbf8903 after smoltcp PR DragonOS-Community#32 merged into dragonos/v0.12.0.

Verified that the merged commit has the same Git tree as the previously validated 4cfe0dd revision. No protocol implementation changes are introduced. make kernel passed with the merged dependency.

Signed-off-by: longjin <longjin@dragonos.org>
@fslongjin
fslongjin merged commit 16d7938 into DragonOS-Community:master Sep 22, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug fix A bug is fixed in this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant