diff options
| author | Nataliia Solomko <natalirs1985@gmail.com> | 2026-05-26 18:27:56 +0300 |
|---|---|---|
| committer | Nataliia Solomko <natalirs1985@gmail.com> | 2026-06-09 18:41:56 +0300 |
| commit | b49e8f00560bdbd69f85539396afb6391b281519 (patch) | |
| tree | 57990da78f634de549947fd28f408a137061aaa7 /src/conf_mode | |
| parent | 6a5f1961cde6116457cb9e6b958bee7b66603c3b (diff) | |
| download | vyos-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-x | src/conf_mode/protocols_bgp.py | 51 |
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: |
