Skip to content

fix(fc): slot-driven guest IPv6 config; default to IPv4-only to eliminate Happy Eyeballs latency - #3587

Open
AdaAibaby wants to merge 4 commits into
e2b-dev:mainfrom
AdaAibaby:fix/disable-ipv6-kernel-args
Open

fix(fc): slot-driven guest IPv6 config; default to IPv4-only to eliminate Happy Eyeballs latency#3587
AdaAibaby wants to merge 4 commits into
e2b-dev:mainfrom
AdaAibaby:fix/disable-ipv6-kernel-args

Conversation

@AdaAibaby

@AdaAibaby AdaAibaby commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #3585.

Problem

kernel_args.go hardcoded ipv6.disable=0 and ipv6.autoconf=1, enabling IPv6 inside every Firecracker guest. However the host-side network setup only configures IPv4 — no router advertisement is sent on the host tap interface, so SLAAC produces only an unroutable
fe80:: link-local address.

With IPv6 nominally enabled but unroutable, the Linux kernel's address selection (RFC 6724) prefers AAAA records. On every outbound connection to a dual-stack host the kernel tries IPv6 first, hits EHOSTUNREACH or waits for a silent NDP timeout, then falls back to IPv4
under the Happy Eyeballs ~250 ms delay (RFC 8305).

Every sandbox is affected. pip, npm, cargo, apt, and any HTTP API call to a major service (OpenAI, GitHub, PyPI, GCP, AWS) has AAAA records. A package install that opens 20 TCP connections silently loses 5+ seconds.

Fix

Rather than hardcoding ipv6.disable=1, the guest's IPv6 state is now derived from whether the host slot actually has an IPv6 router configured:

  • Slot.HasIPv6Router() bool — single source of truth. Returns false today (no RA on the tap); flip to true (or read from real IPv6 slot state) when the host gains a full IPv6 stack.
  • ProcessOptions.IPv6RouterConfigured bool — carries the slot's answer into buildKernelArgs without coupling the kernel-args layer to the network package. Set from Slot.HasIPv6Router() in Process.Create.
  • buildKernelArgs — selects ipv6.disable=0 or =1 based on the flag. The zero-value default (false) preserves safe behavior: guests without an IPv6 router boot IPv4-only.

This means today's sandboxes get ipv6.disable=1 (fixing the Happy Eyeballs regression), and future dual-stack support requires only flipping HasIPv6Router() — no scattered code changes.

Changes

File What changed
network/slot.go HasIPv6Router() bool — documented extension point, returns false
fc/process.go ProcessOptions.IPv6RouterConfigured; set from slot.HasIPv6Router() before buildKernelArgs
fc/kernel_args.go ipv6.disable derived from options.IPv6RouterConfigured instead of hardcoded
fc/kernel_args_test.go Updated existing cases (expect ipv6.disable=1); added ipv6 router configured case (expect ipv6.disable=0)
docs/ARCHITECTURE.md Documents IPv4-only guest default and the dual-stack upgrade path

…ency

The tap interface is configured IPv4-only: process.go builds the ip=
kernel parameter with NamespaceIP/TapIP/TapMask but no IPv6 router or
prefix is advertised on the host side of the tap. With ipv6.disable=0
and ipv6.autoconf=1 the guest kernel enables SLAAC, which at best
yields an unroutable fe80:: link-local address and at worst waits for
an RA that never arrives.

The practical consequence is a ~250 ms Happy Eyeballs penalty (RFC 8305)
on every outbound connection to a dual-stack host: the kernel prefers the
AAAA address, the attempt fails with EHOSTUNREACH or a silent NDP timeout,
then falls back to IPv4. pip install, npm install, and any HTTP API call
to a major service (OpenAI, GitHub, PyPI, GCP) all have AAAA records, so
every sandbox pays this cost on every first TCP connection per destination.

Fix: set ipv6.disable=1 and drop the now-redundant ipv6.autoconf=1.
This is a one-line kernel cmdline change with no other code impact.
Full IPv6 support can be re-enabled once the host networking layer gains
a complete stack (RA, prefix delegation, ip6tables).

Fixes: e2b-dev#3585
Previously the guest kernel always booted with ipv6.disable=1 (hardcoded in
kernel_args.go). This fix keeps the same safe default while making the flag
slot-driven, so the codebase is ready for a future host-side IPv6 stack without
a scattered search-and-replace.

Changes:
- Slot.HasIPv6Router() bool — the single source of truth for whether the host
  tap has an IPv6 router configured. Returns false today (no RA on the tap);
  flip to true (or derive from real IPv6 state) when the host gains IPv6.

- ProcessOptions.IPv6RouterConfigured bool — carries the slot's answer into
  buildKernelArgs without coupling kernel_args.go to the network package.
  Set from Slot.HasIPv6Router() in Process.Create, one line before the call.

- buildKernelArgs selects ipv6.disable=0 or =1 based on the flag instead of
  a string literal. The default (false) preserves the existing behaviour:
  guests without an IPv6 router on the host tap boot with ipv6.disable=1.

- kernel_args_test.go adds an "ipv6 router configured" case that asserts
  ipv6.disable=0 when IPv6RouterConfigured=true.

Fixes e2b-dev#3585.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 926e6ed210

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/orchestrator/pkg/sandbox/fc/kernel_args.go
Comment thread packages/orchestrator/pkg/sandbox/fc/kernel_args.go
@AdaAibaby AdaAibaby changed the title fix(fc): disable IPv6 in guest kernel to eliminate Happy Eyeballs latency fix(fc): slot-driven guest IPv6 config; default to IPv4-only to eliminate Happy Eyeballs latency Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kernel: ipv6.disable=0 with no IPv6 routing causes Happy Eyeballs latency on all outbound sandbox connections

2 participants