From bf38990cd33219c1715c8cfb974eece979289cdd Mon Sep 17 00:00:00 2001 From: Konstantin Renner Date: Wed, 20 May 2026 22:18:59 +0200 Subject: [PATCH] talos: add dummy0 interface claiming BGP-pool prefixes (AnyIP for ICMP) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cilium's eBPF LB intercepts TCP/UDP destined for Service VIPs before the kernel routing path, but ICMP/ICMPv6 isn't intercepted — packets hit the kernel, the kernel has no interface owning the LB IP, default route forwards back to the UDM, BGP routes back to a node, loop until hop-limit exceeded. The "AnyIP" routing fix is to put the LB pool prefixes on a dummy interface so the kernel claims them as local and answers ICMP directly. Documented in the MetalLB BGP guide and in Talos's machine.network.interfaces.dummy schema. Applied to all four nodes (k8s-1/2/3/edge) since traffic may land on any of them; the dummy interface is per-node. The /24 + /64 covers the full bgp-pool range, future-proofing against new LB allocations without further node config changes. This is a kernel-network change — applying the patch requires a rolling reboot of each node (talosctl patch --mode=auto + drain, wait for Ceph HEALTH_OK between nodes per the wait-for-ceph rule). Co-Authored-By: Claude Opus 4.7 (1M context) --- kubernetes/talos/patches/k8s-1.yaml | 12 ++++++++++++ kubernetes/talos/patches/k8s-2.yaml | 6 ++++++ kubernetes/talos/patches/k8s-3.yaml | 6 ++++++ kubernetes/talos/patches/k8s-edge.yaml | 12 ++++++++++++ 4 files changed, 36 insertions(+) diff --git a/kubernetes/talos/patches/k8s-1.yaml b/kubernetes/talos/patches/k8s-1.yaml index c369d7cf..3da607ac 100644 --- a/kubernetes/talos/patches/k8s-1.yaml +++ b/kubernetes/talos/patches/k8s-1.yaml @@ -35,6 +35,18 @@ machine: addresses: - 10.99.0.1/29 mtu: 9000 + # Dummy interface claiming the BGP-pool prefixes so the kernel sees + # LB VIPs as locally owned. Cilium's eBPF LB intercepts TCP/UDP but + # not ICMP/ICMPv6, so ICMP to an LB VIP otherwise hits the kernel + # routing path, gets forwarded out the default route, and loops + # back via BGP until hop-limit exceeded. With the LB prefixes on + # dummy0 the kernel answers directly. AnyIP routing pattern; see + # cilium-ebpf-lb-icmp-ttl-loop-quirk wiki note. + - interface: dummy0 + dummy: true + addresses: + - 10.2.99.0/24 + - fd99::/64 install: disk: /dev/vda certSANs: diff --git a/kubernetes/talos/patches/k8s-2.yaml b/kubernetes/talos/patches/k8s-2.yaml index eac62727..fc3f5c6f 100644 --- a/kubernetes/talos/patches/k8s-2.yaml +++ b/kubernetes/talos/patches/k8s-2.yaml @@ -19,6 +19,12 @@ machine: addresses: - 10.99.0.2/29 mtu: 9000 + # See k8s-1.yaml for the dummy0 / AnyIP rationale. + - interface: dummy0 + dummy: true + addresses: + - 10.2.99.0/24 + - fd99::/64 install: disk: /dev/vda certSANs: diff --git a/kubernetes/talos/patches/k8s-3.yaml b/kubernetes/talos/patches/k8s-3.yaml index 08ee28b0..a1e42cf5 100644 --- a/kubernetes/talos/patches/k8s-3.yaml +++ b/kubernetes/talos/patches/k8s-3.yaml @@ -19,6 +19,12 @@ machine: addresses: - 10.99.0.3/29 mtu: 9000 + # See k8s-1.yaml for the dummy0 / AnyIP rationale. + - interface: dummy0 + dummy: true + addresses: + - 10.2.99.0/24 + - fd99::/64 install: disk: /dev/vda certSANs: diff --git a/kubernetes/talos/patches/k8s-edge.yaml b/kubernetes/talos/patches/k8s-edge.yaml index 9afbcdf3..800038a5 100644 --- a/kubernetes/talos/patches/k8s-edge.yaml +++ b/kubernetes/talos/patches/k8s-edge.yaml @@ -29,6 +29,18 @@ machine: dhcp: true dhcpOptions: routeMetric: 4096 + # Dummy interface claiming the BGP-pool prefixes so the kernel sees + # LB VIPs as locally owned. Cilium's eBPF LB intercepts TCP/UDP but + # not ICMP/ICMPv6, so ICMP to an LB VIP otherwise hits the kernel + # routing path, gets forwarded out the default route, and loops + # back via BGP until hop-limit exceeded. With the LB prefixes on + # dummy0 the kernel answers directly. AnyIP routing pattern; see + # cilium-ebpf-lb-icmp-ttl-loop-quirk wiki note. + - interface: dummy0 + dummy: true + addresses: + - 10.2.99.0/24 + - fd99::/64 install: disk: /dev/vda certSANs: