summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
authorNataliia Solomko <natalirs1985@gmail.com>2026-05-26 18:27:56 +0300
committerNataliia Solomko <natalirs1985@gmail.com>2026-06-09 18:41:56 +0300
commitb49e8f00560bdbd69f85539396afb6391b281519 (patch)
tree57990da78f634de549947fd28f408a137061aaa7 /src/conf_mode
parent6a5f1961cde6116457cb9e6b958bee7b66603c3b (diff)
downloadvyos-1x-b49e8f00560bdbd69f85539396afb6391b281519.tar.gz
vyos-1x-b49e8f00560bdbd69f85539396afb6391b281519.zip
bgp: T8223: Prevent `advertise-all-vni` in multiple BGP VRF instances simultaneously
FRR only allows one BGP instance to hold `advertise-all-vni` at a time (FRR issue #9405). When a default BGP instance is present it is always started before named VRF instances, so if a named VRF holds the flag FRR silently rejects it on every boot (regardless of default EVPN config), causing the running config to diverge from what is stored in VyOS. Enforce the following policy in verify(): - Default BGP instance may always hold `advertise-all-vni`. - A named VRF may hold it only when no default BGP instance exists. - Only one BGP instance (default or named VRF) may hold it at a time. The default BGP verify path additionally scans dependent VRFs so that adding or modifying the default BGP instance while a named VRF already holds the flag is caught even when the VRF node is not part of the current commit.
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 53561a9a3..50d8e5cab 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -214,6 +214,26 @@ def verify(config_dict):
if 'system_as' not in bgp:
raise ConfigError('BGP system-as number must be defined!')
+ # FRR #9405 blocks "advertise-all-vni" in named VRFs if a default
+ # BGP instance is initialized first (regardless of default EVPN config).
+ # On boot the default instance starts first, so if a named VRF also has
+ # the flag FRR silently rejects it, causing config divergence. Block the
+ # combination here even when the VRF node is not part of the current commit.
+ # Could be removed when FRR fixes it upstream.
+ if not vrf:
+ for dep_vrf, dep_config in bgp.get('dependent_vrfs', {}).items():
+ if dep_vrf == 'default':
+ continue
+ dep_evpn = dict_search(
+ 'protocols.bgp.address_family.l2vpn_evpn', dep_config
+ )
+ if dep_evpn and 'advertise_all_vni' in dep_evpn:
+ raise ConfigError(
+ f'BGP EVPN "advertise-all-vni" is configured in named VRF "{dep_vrf}". '
+ f'Remove it from the VRF before adding a default BGP instance, '
+ f'or move it to the default BGP instance instead.'
+ )
+
# Verify BMP
if 'bmp' in bgp:
# check bmp flag "bgpd -d -F traditional --daemon -A 127.0.0.1 -M rpki -M bmp"
@@ -580,6 +600,37 @@ def verify(config_dict):
# Checks only required for L2VPN EVPN
if afi in ['l2vpn_evpn']:
+ # T8223: FRR #9405 — only one BGP instance may hold "advertise-all-vni"
+ # at a time. When a default BGP instance coexists with a named VRF that
+ # has the flag, FRR silently rejects the VRF's copy on every boot because
+ # the default instance is always started first.
+ if 'advertise_all_vni' in afi_config:
+ if vrf:
+ # Named VRF: block whenever a default BGP instance exists.
+ default_bgp = dict_search(
+ 'dependent_vrfs.default.protocols.bgp', bgp
+ )
+ if default_bgp is not None and 'deleted' not in default_bgp:
+ raise ConfigError(
+ f'BGP EVPN "advertise-all-vni" is not supported in named VRF "{vrf}" '
+ f'when a default BGP instance exists. '
+ f'Configure it in the default BGP instance instead.'
+ )
+
+ # Block if multiple BGP instances have advertise-all-vni simultaneously.
+ advertise_all_vni_vrfs = [vrf if vrf else 'default']
+ for dep_vrf, dep_config in bgp.get('dependent_vrfs', {}).items():
+ dep_evpn = dict_search(
+ 'protocols.bgp.address_family.l2vpn_evpn', dep_config
+ )
+ if dep_evpn and 'advertise_all_vni' in dep_evpn:
+ advertise_all_vni_vrfs.append(dep_vrf)
+ if len(advertise_all_vni_vrfs) > 1:
+ raise ConfigError(
+ f'BGP EVPN "advertise-all-vni" cannot be configured in multiple '
+ f'VRFs simultaneously: {", ".join(advertise_all_vni_vrfs)}.'
+ )
+
if 'vni' in afi_config:
for vni, vni_config in afi_config['vni'].items():
if 'rd' in vni_config and 'advertise_all_vni' not in afi_config: