support ipv6 localhost relay in Consomme networking mode#40900
Draft
wangxin12 wants to merge 2 commits into
Draft
support ipv6 localhost relay in Consomme networking mode#40900wangxin12 wants to merge 2 commits into
wangxin12 wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends Consomme/mirrored networking to support IPv6 localhost relay end-to-end by provisioning an IPv6 address on the host-created loopback device, adding IPv6 loopback routing/rules in the guest, and introducing a tc/eBPF-based workaround to allow inbound ::1 delivery despite the kernel’s IPv6 “martian” loopback checks on non-loopback devices.
Changes:
- Provision
client_ip_ipv6=::1for the Consomme loopback device so the host relay can inject::1flows onto the GELNIC. - Enable the guest IPv6 loopback policy routing +
::1/128route via the IPv6 loopback gateway, and add an inbound tc/BPF relay path (with a sentinel address + route) to deliver relay-injected::1packets. - Add an in-tree minimal BPF loader and tooling (BPF program, skeleton generator, and a Makefile to rebuild the embedded header).
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/windows/common/ConsommeNetworking.cpp | Adds client_ip_ipv6=::1 to loopback device options when IPv6 + loopback-client mode are enabled. |
| src/linux/netlinkutil/RoutingTable.cpp | Omits RTA_PREFSRC for IPv6 loopback routes to avoid kernel EINVAL with ::1 preferred source. |
| src/linux/init/NetworkManager.h | Extends mirrored loopback rule helper to take address family; adds IPv6 relay configuration helper. |
| src/linux/init/NetworkManager.cpp | Enables IPv6 loopback routing configuration and wires in tc/BPF-based inbound ::1 relay handling. |
| src/linux/init/Loopback6Bpf.h | Declares best-effort loader API returning ingress/egress program fds. |
| src/linux/init/Loopback6Bpf.cpp | Implements minimal loader for embedded tc/BPF bytecode without libbpf. |
| src/linux/init/GnsEngine.cpp | Updates call sites for the updated loopback-rule helper signature. |
| src/linux/init/CMakeLists.txt | Adds new init sources/headers and include path for embedded BPF skeleton header. |
| src/linux/bpf/Makefile | Adds a developer build path to compile the BPF object and regenerate the embedded skeleton header. |
| src/linux/bpf/loopback6_relay.skel.h | Adds generated embedded BPF bytecode + relocation metadata consumed by the in-tree loader. |
| src/linux/bpf/loopback6_relay.bpf.c | Adds tc ingress/egress BPF program implementing the IPv6 localhost relay rewrite/redirect logic. |
| src/linux/bpf/gen_bpf_skel.py | Adds generator producing the embedded skeleton header from a compiled BPF object. |
Comment on lines
+476
to
+495
| // Attach the programs to a clsact qdisc on loopback0. Ingress rewrites a relay-injected ::1 source to | ||
| // the sentinel, restores ::1 as the destination, and redirects onto lo (whose IFF_LOOPBACK bypasses | ||
| // the martian check) so the packet is delivered. Egress restores the relay's addresses on the reply. | ||
| gelnic.ModifyTcClassifier(true); | ||
| gelnic.BpfAttachTcClassifier(programs->ingressFd, true); | ||
| gelnic.BpfAttachTcClassifier(programs->egressFd, false); | ||
| close(programs->ingressFd); | ||
| close(programs->egressFd); | ||
|
|
||
| // The ingress hook redirects packets onto lo, so add the priority-0 "iif lo ... lookup local" rule; | ||
| // otherwise the redirected packets would match the priority-1 "lookup 127" rule and be forwarded | ||
| // back out instead of delivered locally. | ||
| UpdateMirroredLoopbackRulesForInterface("lo", AF_INET6, Operation::Create); | ||
|
|
||
| // The egress hook leaves the reply destined to the sentinel; route the sentinel back out loopback0 | ||
| // (table 127) so it egresses where the hook can rewrite it back to ::1 for the relay. | ||
| Route sentinelRoute = Route(AF_INET6, c_ipv6LoopbackGateway, gelnic.Index(), false, c_sentinelV6AddressRange, 0); | ||
| sentinelRoute.isLoopbackRoute = true; | ||
| loopbackRoutingTable.ModifyRoute(sentinelRoute, Operation::Create); | ||
|
|
Comment on lines
+191
to
+194
| if constexpr (std::is_same_v<TAddr, in6_addr>) | ||
| { | ||
| // The IPv6 loopback destination (::1) cannot be used as a route preferred source on the GELNIC: unlike IPv4 | ||
| // (where EnableLoopbackRouting turns on route_localnet/accept_local so 127.0.0.1 is a valid source), IPv6 has |
Comment on lines
+39
to
+53
| int LoadProgram(const unsigned char* insnBytes, unsigned int insnByteLen, const unsigned int* relocs, unsigned int relocCount, int mapFd) | ||
| { | ||
| std::vector<uint8_t> insns(insnBytes, insnBytes + insnByteLen); | ||
|
|
||
| // Patch the map fd into each ld_imm64 instruction that references the map. | ||
| for (unsigned int i = 0; i < relocCount; i++) | ||
| { | ||
| if (relocs[i] + sizeof(struct bpf_insn) > insns.size()) | ||
| { | ||
| continue; | ||
| } | ||
| auto* insn = reinterpret_cast<struct bpf_insn*>(insns.data() + relocs[i]); | ||
| insn->src_reg = BPF_PSEUDO_MAP_FD; | ||
| insn->imm = mapFd; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of the Pull Request
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed