labsim: add IPv6 BGP config layer for the Gateway-API public-v6 rehearsal
Some checks failed
CI/CD / lint (push) Failing after 24s
CI/CD / typecheck (push) Failing after 22s
CI/CD / test (push) Failing after 23s
CI/CD / build (push) Has been skipped
CI/CD / publish-rpm (push) Has been skipped
CI/CD / publish-deb (push) Has been skipped

The sim's eBGP was IPv4-only; extend it to the v6 family so labsim can rehearse
Cilium BGP advertising a public-style v6 LoadBalancer /64 to the VyOS pair before
it touches production (approved plan: public IPv6 via Cilium BGP + Gateway API).

- sim-net-config.py: bgp6 inside bgp() -- ipv6-unicast peer-group K8S6 over
  fd00:2::11/12/13, prefix-list6 (le 128, /128 host routes), K8S-IN6/OUT6 route-maps
  (export deny -- never hand the cluster a default). ULA fd61:1e00::/64 as the sim
  LB range so nothing leaks into the real HE /48. All v6 lines pass the
  sim-net-apply.sh whitelist.
- sim-ha-config.py: VLANS6 = {2: fd00:2/64} -> routers hold fd00:2::252/253 on
  bond0.2 so they can peer the nodes over v6 (no v6 VRRP VIP; BGP peers the per-box
  address, as production).
- k8s-up.sh: nodes get fd00:2::11/12/13 + dual-stack k3s (dual node-ip, dual
  cluster/service CIDR). Peers line up with sim-net-config K8S_NODES_V6.

Config-gen verified for all three. Live chunk (Cilium v6+BGP+Gateway install,
bring-up, datapath/#26847 proof) is next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMVzWZgiKW2wquf5z8S1yH
This commit is contained in:
Michal
2026-09-10 01:23:03 +01:00
parent a4dcc9b379
commit c729275961
3 changed files with 60 additions and 6 deletions

View File

@@ -37,6 +37,18 @@ K8S_NODES = ["172.31.2.11", "172.31.2.12", "172.31.2.13"]
PEER_GROUP = "K8S"
PFX_LIST = "K8S-SERVICE-IPS"
RM_IN, RM_OUT = "K8S-IN", "K8S-OUT"
# IPv6 unicast. Production advertises a public Gateway LoadBalancer /64 out of
# the HE /48 (2001:470:187e:1e00::/64) and peers over VLAN 2 IPv6. The sim proves
# the MECHANISM -- ipv6-unicast eBGP, prefix-list6, /128 host routes, ECMP -- with
# a ULA so nothing here can leak into the real /48. Peering is over VLAN 2 v6
# (nodes' fd00:2::1x <-> routers' fd00:2::25x, set in sim-ha-config.py /
# k8s-up.sh), directly connected exactly as v4.
SERVICE_CIDR_V6 = "fd61:1e00::/64" # sim analog of prod :1e00::/64 LB pool
K8S_NODES_V6 = ["fd00:2::11", "fd00:2::12", "fd00:2::13"]
PEER_GROUP_V6 = "K8S6"
PFX_LIST_V6 = "K8S-SERVICE-IPS-V6"
RM_IN_V6, RM_OUT_V6 = "K8S-IN6", "K8S-OUT6"
# One route per node; ECMP across all three. 4 leaves headroom for a fourth node
# without a config change.
MAX_PATHS = 4
@@ -123,6 +135,26 @@ def bgp(role: str) -> list[str]:
f"set protocols bgp peer-group {PEER_GROUP} address-family ipv4-unicast maximum-prefix {MAX_PREFIX}",
]
out += [f"set protocols bgp neighbor {n} peer-group {PEER_GROUP}" for n in K8S_NODES]
# --- IPv6 unicast: same policy shape, over a separate v6 peer-group ---
# `prefix-list6` + `match ipv6 address` are the v6 spellings; `le 128` because
# Cilium advertises each Gateway LoadBalancer address as a /128, not the
# aggregate. Separate peer-group because the neighbors are v6 addresses; the
# export deny is the same safety property (never hand the cluster a default).
out += [
"",
f"set policy prefix-list6 {PFX_LIST_V6} rule 10 action permit",
f"set policy prefix-list6 {PFX_LIST_V6} rule 10 prefix {SERVICE_CIDR_V6}",
f"set policy prefix-list6 {PFX_LIST_V6} rule 10 le 128",
f"set policy route-map {RM_IN_V6} rule 10 action permit",
f"set policy route-map {RM_IN_V6} rule 10 match ipv6 address prefix-list {PFX_LIST_V6}",
f"set policy route-map {RM_OUT_V6} rule 10 action deny",
f"set protocols bgp address-family ipv6-unicast maximum-paths ebgp {MAX_PATHS}",
f"set protocols bgp peer-group {PEER_GROUP_V6} remote-as {CLUSTER_AS}",
f"set protocols bgp peer-group {PEER_GROUP_V6} address-family ipv6-unicast route-map import {RM_IN_V6}",
f"set protocols bgp peer-group {PEER_GROUP_V6} address-family ipv6-unicast route-map export {RM_OUT_V6}",
f"set protocols bgp peer-group {PEER_GROUP_V6} address-family ipv6-unicast maximum-prefix {MAX_PREFIX}",
]
out += [f"set protocols bgp neighbor {n} peer-group {PEER_GROUP_V6}" for n in K8S_NODES_V6]
out.append("")
return out