Skip to content

cilium_host IPv6 address is set to node IP instead of generated IPv6 router IP #16042

@eyanulis

Description

@eyanulis

Bug report

In pkg/datapath/loader/base.go, the initArgIPv6NodeIP argument is set to node.GetIPv6(). It is then passed to bpf/init.sh for datapath setup, where the value is used to set the IP address on the cilium_host veth.

if option.Config.EnableIPv4 {
args[initArgIPv4NodeIP] = node.GetInternalIPv4Router().String()
} else {
args[initArgIPv4NodeIP] = "<nil>"
}
if option.Config.EnableIPv6 {
args[initArgIPv6NodeIP] = node.GetIPv6().String()
// Docker <17.05 has an issue which causes IPv6 to be disabled in the initns for all
// interface (https://github.com/docker/libnetwork/issues/1720)
// Enable IPv6 for now
sysSettings = append(sysSettings,
sysctl.Setting{Name: "net.ipv6.conf.all.disable_ipv6", Val: "0", IgnoreErr: false})
} else {
args[initArgIPv6NodeIP] = "<nil>"
}

cilium/bpf/init.sh

Lines 358 to 365 in e34115a

# If the host does not have an IPv6 address assigned, assign our generated host
# IP to make the host accessible to endpoints
if [ "$IP6_HOST" != "<nil>" ]; then
[ -n "$(ip -6 addr show to $IP6_HOST dev $HOST_DEV1)" ] || ip -6 addr add $IP6_HOST dev $HOST_DEV1
fi
if [ "$IP4_HOST" != "<nil>" ]; then
[ -n "$(ip -4 addr show to $IP4_HOST dev $HOST_DEV1)" ] || ip -4 addr add $IP4_HOST dev $HOST_DEV1 scope link
fi

However, it is clear from the IPv4 case a few lines above - and from the comment in init.sh - that the intent was to pass in the Cilium router IP (i.e. the address generated from the node's pod CIDR) rather than the k8s node IP. The result of this error, assuming a dual-stack node, is:

  • For IPv4, cilium_host is assigned the v4 generated router address as intended.
  • For IPv6, cilium_host duplicates the address on the primary upstream interface (which is often also the k8s node IP).

This directly causes at least one condition under which #16019 can occur, but given that this likely has larger overall implications I've elected to keep it separate for now.

I'm preparing a PR to replace the node.GetIPv6() call with a node.GetIPv6Router() call and will submit it after checking the resulting behavior locally.

General Information

  • Cilium version (run cilium version): 1.9.6
  • Kernel version (run uname -a): 5.11.11-200.fc33.x86_64
  • Orchestration system version in use (e.g. kubectl version, ...): Kubernetes 1.20.5
  • Link to relevant artifacts (policies, deployments scripts, ...):
  • Generate and upload a system zip:

How to reproduce the issue

  1. Deploy an IPv6 Kubernetes cluster (dual-stack, or single-stack IPv6)
  2. Deploy Cilium through any preferred method.
  3. Observe that the IPv6 address on cilium_host has been set to the node IP rather than the Cilium-generated router IP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/datapathImpacts bpf/ or low-level forwarding details, including map management and monitor messages.feature/ipv6Relates to IPv6 protocol supportkind/bugThis is a bug in the Cilium logic.kind/community-reportThis was reported by a user in the Cilium community, eg via Slack.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions