Skip to content

IPv6 Health Endpoint Unreachable from Host Network Namespace

IPv6 Health Endpoint Unreachable from Host Network Namespace

Summary

Cilium health checks fail for IPv6 secondary addresses when probing from the host network namespace. IPv4 health checks work fine, and pod-to-health-endpoint IPv6 connectivity works perfectly. Only host-to-health-endpoint IPv6 fails.

Environment

  • Cilium Version: 1.18.3
  • Kubernetes Version: v1.34.1
  • Kernel: 6.17.7-300.fc43.x86_64
  • Datapath Mode: Both veth and netkit (issue occurs in both)
  • Routing Mode: native
  • Cluster: Single-node, dual-stack

Minimal Configuration to Reproduce

helm install cilium cilium/cilium --version 1.18.3 \
    --namespace kube-system \
    --set ipv4.enabled=true \
    --set ipv6.enabled=true \
    --set routingMode=native \
    --set ipv4NativeRoutingCIDR=10.244.0.0/16 \
    --set ipv6NativeRoutingCIDR=fd00:10:244::/48 \
    --set kubeProxyReplacement=true

Node configuration:

# /var/lib/kubelet/kubeadm-flags.env
--node-ip=<NODE_IPV4>,<NODE_IPV6>

Expected Behavior

Cluster health: 1/1 reachable
  node (localhost)   <NODE_IPV4>,<NODE_IPV6>   2/2

Actual Behavior

$ cilium-health status
Cluster health: 0/1 reachable
  node (localhost)   <NODE_IPV4>,<NODE_IPV6>   2/2    1/2

$ cilium-health status -o json | jq '.nodes[0]."health-endpoint"."secondary-addresses"'
[{
  "http": { "status": "context deadline exceeded" },
  "icmp": { "status": "Connection timed out" },
  "ip": "fd00:10:244::36e8"
}]

Test Results

Test Result
IPv4 health check (host → health endpoint) Working
IPv6 health check (host → health endpoint) Timeout
IPv6 connectivity (pod → health endpoint) Working
# From host - FAILS
$ ping6 -c 3 fd00:10:244::36e8
3 packets transmitted, 0 received, 100% packet loss

# From pod - WORKS
$ kubectl exec -n cilium-test-1 <pod> -- ping6 -c 3 fd00:10:244::36e8
3 packets transmitted, 3 received, 0% packet loss

Diagnostic Evidence

Health endpoint is correctly configured:

$ nsenter -t <health-pid> -n ip -6 addr show
inet6 fd00:10:244::36e8/128 scope global

$ nsenter -t <health-pid> -n ss -tln | grep 4240
LISTEN 0  4096  *:4240  *:*

TCP handshake never completes:

# tcpdump on lxc_health interface
SYN    fd00:10:244::441e.54560 > fd00:10:244::36e8.4240
SYN-ACK fd00:10:244::36e8.4240 > fd00:10:244::441e.54560  ← Reply sent
SYN-ACK fd00:10:244::36e8.4240 > fd00:10:244::441e.54560  ← Duplicate
# ACK never sent - handshake incomplete

# Host socket stuck in SYN-SENT
$ ss -6 -tan | grep 36e8
SYN-SENT  0  1  [fd00:10:244::441e]:55576  [fd00:10:244::36e8]:4240

No packet drops detected:

$ cilium monitor --type drop
# No drops related to IPv6 health endpoint

Connection tracking shows entries but zero packets delivered:

$ cilium bpf ct list global | grep 36e8
TCP IN fd00:10:244::441e:54560 -> fd00:10:244::36e8:4240
  Packets=0 Bytes=0 RxFlagsSeen=0x02 TxFlagsSeen=0x12

Root Cause

SYN-ACK packets from the health endpoint reach the lxc_health/netkit interface but are not delivered to the host network stack socket layer. The issue appears specific to IPv6 packet handling in the cilium_host ingress path.

Reproducibility

  • Reproduces with veth mode (default)
  • Reproduces with netkit mode
  • Reproduces with minimal configuration (above)
  • Reproduces with advanced features (BIGTCP, BBR, etc.)

Created by Claude Code model claude-sonnet-4-5-20250929