From b45264da488c1594334a9b9ac15941fb17085f30 Mon Sep 17 00:00:00 2001 From: Mat Kowalski Date: Thu, 9 Jul 2026 15:38:20 +0200 Subject: [PATCH] Add optional top-of-rack BGP speaker for the baremetal network ENABLE_BGP_TOR deploys an FRR container on the host network that accepts dynamic BGP sessions from cluster nodes on the external subnet and installs learned routes on the hypervisor. Primary consumer is BGP-based VIP management (openshift/enhancements#1982): the cluster advertises API and Ingress VIPs to this speaker and the host reaches them over the BGP paths. ASNs and the FRR image are configurable; teardown is wired into host_cleanup. --- 02_configure_host.sh | 5 ++ bgp/cleanup_bgp_tor.sh | 20 ++++++++ bgp/configure_bgp_tor.sh | 101 +++++++++++++++++++++++++++++++++++++++ common.sh | 7 +++ config_example.sh | 19 ++++++++ host_cleanup.sh | 3 ++ 6 files changed, 155 insertions(+) create mode 100755 bgp/cleanup_bgp_tor.sh create mode 100755 bgp/configure_bgp_tor.sh diff --git a/02_configure_host.sh b/02_configure_host.sh index f6bcb1a97..c8aa4bdf1 100755 --- a/02_configure_host.sh +++ b/02_configure_host.sh @@ -512,3 +512,8 @@ if [ "${PERSISTENT_IMAGEREG}" == true ] ; then sudo systemctl start nfs-server sudo exportfs -a fi + +# Optionally run a top-of-rack BGP speaker on the baremetal network +if [[ -n "${ENABLE_BGP_TOR:-}" ]]; then + bgp/configure_bgp_tor.sh +fi diff --git a/bgp/cleanup_bgp_tor.sh b/bgp/cleanup_bgp_tor.sh new file mode 100755 index 000000000..2ffd907e6 --- /dev/null +++ b/bgp/cleanup_bgp_tor.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euxo pipefail + +bgp_dir="$(dirname "$(readlink -f "$0")")" +# shellcheck disable=SC1091 +source "${bgp_dir}/../common.sh" + +# Tears down the optional top-of-rack BGP speaker deployed by +# configure_bgp_tor.sh. Tolerant of a missing container / firewall rule so +# it can run unconditionally from host_cleanup.sh. + +BGP_TOR_NAME="bgp-tor" +BGP_TOR_DIR="${WORKING_DIR}/bgp-tor" + +sudo podman rm -f "${BGP_TOR_NAME}" || true + +sudo firewall-cmd --zone=libvirt --permanent --remove-port=179/tcp || true +sudo firewall-cmd --zone=libvirt --remove-port=179/tcp || true + +rm -rf "${BGP_TOR_DIR}" diff --git a/bgp/configure_bgp_tor.sh b/bgp/configure_bgp_tor.sh new file mode 100755 index 000000000..ae6be3cb0 --- /dev/null +++ b/bgp/configure_bgp_tor.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +set -euxo pipefail + +bgp_dir="$(dirname "$(readlink -f "$0")")" +# shellcheck disable=SC1091 +source "${bgp_dir}/../common.sh" +# shellcheck disable=SC1091 +source "${bgp_dir}/../network.sh" + +# Deploys an FRR container on the host network acting as a top-of-rack BGP +# speaker for the baremetal network. Cluster nodes (e.g. BGP-based VIP +# management, enhancement openshift/enhancements#1982) peer with it via +# dynamic neighbors; learned routes are installed into the host kernel by +# zebra, so the hypervisor reaches advertised VIPs over the BGP paths. + +BGP_TOR_NAME="bgp-tor" +BGP_TOR_DIR="${WORKING_DIR}/bgp-tor" + +mkdir -p "${BGP_TOR_DIR}" + +if [[ -n "${EXTERNAL_SUBNET_V4:-}" ]]; then + ROUTER_ID="$(nth_ip "${EXTERNAL_SUBNET_V4}" 1)" +else + # BGP router IDs are always in IPv4 dotted-quad format; use a fixed + # documentation-range ID for IPv6-only deployments. + ROUTER_ID="192.0.2.1" +fi + +# Accept dynamic BGP sessions from anywhere on the external subnet(s) and +# only activate the address families a peer could exist on. +LISTEN_RANGES="" +ADDRESS_FAMILIES="" +if [[ -n "${EXTERNAL_SUBNET_V4:-}" ]]; then + LISTEN_RANGES+=" bgp listen range ${EXTERNAL_SUBNET_V4} peer-group CLUSTER +" + ADDRESS_FAMILIES+=" ! + address-family ipv4 unicast + neighbor CLUSTER activate + exit-address-family +" +fi +if [[ -n "${EXTERNAL_SUBNET_V6:-}" ]]; then + LISTEN_RANGES+=" bgp listen range ${EXTERNAL_SUBNET_V6} peer-group CLUSTER +" + ADDRESS_FAMILIES+=" ! + address-family ipv6 unicast + neighbor CLUSTER activate + exit-address-family +" +fi + +# "no bgp ebgp-requires-policy" relaxes RFC 8212; without it FRR 8+ refuses +# to exchange routes with eBGP peers unless explicit policies are configured. +cat > "${BGP_TOR_DIR}/frr.conf" < "${BGP_TOR_DIR}/daemons" <