From d6acf46709e16947766e50ebf3378439deb631c7 Mon Sep 17 00:00:00 2001 From: Mat Kowalski Date: Thu, 6 Aug 2026 16:42:26 +0200 Subject: [PATCH 1/2] BGP VIP management: render an IPv6 ToR peer on dual-stack deployments With IP_STACK=v4v6 the install-config carries one API/ingress VIP per address family, but bgpVIPConfig only rendered the IPv4 ToR peer, so the secondary-family VIPs had no same-family BGP session to be advertised over. Render a second peer for the ToR's address on the external IPv6 subnet when one exists (override: BGP_VIP_PEER_ADDRESS_V6). The ToR speaker itself already listens on both families (ENABLE_BGP_TOR renders per-family listen ranges). Validated on a dual-stack dev-scripts cluster: both sessions establish per node and both VIP families are advertised to the ToR. Assisted-By: Claude Fable 5 Signed-off-by: Mat Kowalski --- config_example.sh | 5 ++++- ocp_install_env.sh | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/config_example.sh b/config_example.sh index ef41c477a..34d6846e9 100755 --- a/config_example.sh +++ b/config_example.sh @@ -253,11 +253,14 @@ set -x # BGPBasedVIPManagement gate (DevPreviewNoUpgrade). The local ASN defaults # to BGP_CLUSTER_ASN, the peer ASN to BGP_TOR_ASN, and the peer address to # the ToR address on the external subnet; override the peer address with -# BGP_VIP_PEER_ADDRESS if your topology differs. +# BGP_VIP_PEER_ADDRESS if your topology differs. On dual-stack deployments +# a second peer is rendered for the ToR's IPv6 address on the external v6 +# subnet (override with BGP_VIP_PEER_ADDRESS_V6). # Default is unset. # #export BGP_VIP_MANAGEMENT=true #export BGP_VIP_PEER_ADDRESS= +#export BGP_VIP_PEER_ADDRESS_V6= # # FRR container image: #export BGP_TOR_IMAGE=quay.io/frrouting/frr:9.1.0 diff --git a/ocp_install_env.sh b/ocp_install_env.sh index 09d96075a..11c15aebd 100644 --- a/ocp_install_env.sh +++ b/ocp_install_env.sh @@ -200,7 +200,7 @@ EOF function bgp_vip_config() { if [[ "${BGP_VIP_MANAGEMENT:-false}" == "true" ]]; then - local peer_address + local peer_address peer_address_v6 peer_address="${BGP_VIP_PEER_ADDRESS:-$(nth_ip "${EXTERNAL_SUBNET_V4}" 1)}" cat < Date: Wed, 12 Aug 2026 21:19:18 +0200 Subject: [PATCH 2/2] bgp-vip: exercise every optional peer field in e2e deployments The FRR timer-format and dead port-field bugs on installer#10718 went undetected because e2e only ever deployed the defaults-only happy path: optional fields that are never set produce no config lines, so broken or unrendered template branches are invisible. Set port, holdTime, keepaliveTime, password, bfdEnabled and ebgpMultiHop on every rendered peer (overridable via BGP_VIP_* knobs), and configure the ToR to match: session password and BFD on the CLUSTER peer-group, bfdd enabled, and the BFD control/echo UDP ports opened. Assisted-By: Claude Fable 5 Signed-off-by: Mat Kowalski --- bgp/configure_bgp_tor.sh | 10 +++++++++- config_example.sh | 8 ++++++++ ocp_install_env.sh | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/bgp/configure_bgp_tor.sh b/bgp/configure_bgp_tor.sh index ae6be3cb0..e78bf8c9d 100755 --- a/bgp/configure_bgp_tor.sh +++ b/bgp/configure_bgp_tor.sh @@ -62,6 +62,8 @@ router bgp ${BGP_TOR_ASN} no bgp ebgp-requires-policy neighbor CLUSTER peer-group neighbor CLUSTER remote-as ${BGP_CLUSTER_ASN} + neighbor CLUSTER password ${BGP_VIP_PASSWORD:-dev-scripts-bgp} + neighbor CLUSTER bfd ${LISTEN_RANGES}${ADDRESS_FAMILIES}! EOF @@ -80,7 +82,7 @@ eigrpd=no babeld=no sharpd=no pbrd=no -bfdd=no +bfdd=yes fabricd=no vrrpd=no pathd=no @@ -88,10 +90,16 @@ pathd=no vtysh_enable=yes zebra_options=" -A 127.0.0.1 -s 90000000" bgpd_options=" -A 127.0.0.1" +bfdd_options=" -A 127.0.0.1" EOF sudo firewall-cmd --zone=libvirt --permanent --add-port=179/tcp sudo firewall-cmd --zone=libvirt --add-port=179/tcp +# BFD control and echo (single hop, RFC 5881) +for port in 3784 3785; do + sudo firewall-cmd --zone=libvirt --permanent --add-port=${port}/udp + sudo firewall-cmd --zone=libvirt --add-port=${port}/udp +done sudo podman run -d --replace --name "${BGP_TOR_NAME}" --net host --privileged \ -v "${BGP_TOR_DIR}/frr.conf:/etc/frr/frr.conf:z" \ diff --git a/config_example.sh b/config_example.sh index 34d6846e9..a3a411992 100755 --- a/config_example.sh +++ b/config_example.sh @@ -262,6 +262,14 @@ set -x #export BGP_VIP_PEER_ADDRESS= #export BGP_VIP_PEER_ADDRESS_V6= # +# Every optional peer field (port, timers, password, BFD, eBGP multihop) +# is set on purpose so the full rendering path is exercised end to end; +# the ToR is configured to match. Timers are Go durations of whole +# seconds; the session password must match on both ends. +#export BGP_VIP_HOLD_TIME=90s +#export BGP_VIP_KEEPALIVE_TIME=30s +#export BGP_VIP_PASSWORD=dev-scripts-bgp +# # FRR container image: #export BGP_TOR_IMAGE=quay.io/frrouting/frr:9.1.0 diff --git a/ocp_install_env.sh b/ocp_install_env.sh index 11c15aebd..fcce94919 100644 --- a/ocp_install_env.sh +++ b/ocp_install_env.sh @@ -202,12 +202,25 @@ function bgp_vip_config() { if [[ "${BGP_VIP_MANAGEMENT:-false}" == "true" ]]; then local peer_address peer_address_v6 peer_address="${BGP_VIP_PEER_ADDRESS:-$(nth_ip "${EXTERNAL_SUBNET_V4}" 1)}" + # Set every optional peer field so e2e exercises the full + # rendering path (dead fields and format bugs are invisible on + # the defaults-only happy path). The ToR side is configured to + # match by bgp/configure_bgp_tor.sh; the verify CI step asserts + # the negotiated timers and BFD state at the ToR. + local peer_options + peer_options=" port: 179 + holdTime: \"${BGP_VIP_HOLD_TIME:-90s}\" + keepaliveTime: \"${BGP_VIP_KEEPALIVE_TIME:-30s}\" + password: \"${BGP_VIP_PASSWORD:-dev-scripts-bgp}\" + bfdEnabled: \"true\" + ebgpMultiHop: \"true\"" cat <