summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2025-10-06 20:54:32 +0200
committerGitHub <noreply@github.com>2025-10-06 20:54:32 +0200
commitd21b01246a6ef01e407f62cb908e625462fbdc40 (patch)
treeb3a1d3e2cf39530af6a9e79149c7ceb75b309b18 /src
parent7bffb45f931f91416000a483c77e6749ced71206 (diff)
parentbc73a4f7452434f25119267129f337640d8a959c (diff)
downloadvyos-1x-d21b01246a6ef01e407f62cb908e625462fbdc40.tar.gz
vyos-1x-d21b01246a6ef01e407f62cb908e625462fbdc40.zip
Merge pull request #4778 from jestabro/revert-bgp-remove-per-vrf-system-as
Revert "bgp: T7760: remove per vrf instance system-as node"
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py30
-rw-r--r--src/migration-scripts/bgp/6-to-7107
-rw-r--r--src/migration-scripts/bgp/7-to-830
3 files changed, 12 insertions, 155 deletions
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 696981012..fe5740a18 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -200,7 +200,7 @@ def verify(config_dict):
if 'dependent_vrfs' in bgp:
for vrf, vrf_options in bgp['dependent_vrfs'].items():
if vrf != 'default':
- if 'protocols' in vrf_options and 'bgp' in vrf_options['protocols']:
+ if dict_search('protocols.bgp', vrf_options):
dependent_vrfs = ', '.join(bgp['dependent_vrfs'].keys())
raise ConfigError(f'Cannot delete default BGP instance, ' \
f'dependent VRF instance(s): {dependent_vrfs}')
@@ -210,20 +210,8 @@ def verify(config_dict):
return None
- ERR_MSG_GLOBAL_VRF_AS_MISSING = 'BGP "system-as" number must be defined! Use "set protocols ' \
- 'bgp system-as <asn>" to define a global BGP instance AS number.'
- system_as = None
- if vrf:
- system_as = dict_search('dependent_vrfs.default.protocols.bgp.system_as', bgp)
- if not system_as:
- raise ConfigError(ERR_MSG_GLOBAL_VRF_AS_MISSING)
-
- elif 'system_as' not in bgp:
- raise ConfigError(ERR_MSG_GLOBAL_VRF_AS_MISSING)
-
- # Cache global defined system AS number used in further checks
- if not system_as:
- system_as = bgp['system_as']
+ if 'system_as' not in bgp:
+ raise ConfigError('BGP system-as number must be defined!')
# Verify BMP
if 'bmp' in bgp:
@@ -269,7 +257,7 @@ def verify(config_dict):
if 'remote_as' in peer_config:
is_ibgp = True
if peer_config['remote_as'] != 'internal' and \
- peer_config['remote_as'] != system_as:
+ peer_config['remote_as'] != bgp['system_as']:
is_ibgp = False
if peer_group not in peer_groups_context:
@@ -290,7 +278,7 @@ def verify(config_dict):
# Neighbor local-as override can not be the same as the local-as
# we use for this BGP instane!
asn = list(peer_config['local_as'].keys())[0]
- if asn == system_as:
+ if asn == bgp['system_as']:
raise ConfigError('Cannot have local-as same as system-as number')
# Neighbor AS specified for local-as and remote-as can not be the same
@@ -343,7 +331,7 @@ def verify(config_dict):
peer_group = peer_config['interface']['v6only']['peer_group']
if 'remote_as' in peer_config['interface']['v6only'] and 'remote_as' in bgp['peer_group'][peer_group]:
raise ConfigError(f'Peer-group member "{peer}" cannot override remote-as of peer-group "{peer_group}"!')
-
+
for afi in ['ipv4_unicast', 'ipv4_multicast', 'ipv4_labeled_unicast', 'ipv4_flowspec',
'ipv6_unicast', 'ipv6_multicast', 'ipv6_labeled_unicast', 'ipv6_flowspec',
'l2vpn_evpn']:
@@ -381,6 +369,12 @@ def verify(config_dict):
if 'source_interface' in peer_config['interface']:
raise ConfigError(f'"source-interface" option not allowed for neighbor "{peer}"')
+ # Local-AS allowed only for EBGP peers
+ if 'local_as' in peer_config:
+ remote_as = verify_remote_as(peer_config, bgp)
+ if remote_as == bgp['system_as']:
+ raise ConfigError(f'local-as configured for "{peer}", allowed only for eBGP peers!')
+
for afi in ['ipv4_unicast', 'ipv4_multicast', 'ipv4_labeled_unicast', 'ipv4_flowspec',
'ipv6_unicast', 'ipv6_multicast', 'ipv6_labeled_unicast', 'ipv6_flowspec',
'l2vpn_evpn']:
diff --git a/src/migration-scripts/bgp/6-to-7 b/src/migration-scripts/bgp/6-to-7
deleted file mode 100644
index 4074cbb14..000000000
--- a/src/migration-scripts/bgp/6-to-7
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# T7760: Remove per VRF setting for system-as option and replace it with
-# local-as if required.
-
-from vyos.configtree import ConfigTree
-
-def migrate(config: ConfigTree) -> None:
- vrf_base = ['vrf', 'name']
- bgp_base = ['protocols', 'bgp']
-
- if not config.exists(vrf_base):
- return
-
- global_asn = None
- if config.exists(bgp_base + ['system-as']):
- global_asn = config.return_value(bgp_base + ['system-as'])
-
- for vrf in config.list_nodes(vrf_base):
- # bail out early if there is no per VRF BGP instance defined
- vrf_bgp_base = vrf_base + [vrf] + bgp_base
- if not config.exists(vrf_bgp_base):
- continue
-
- # This is a mandatory node in the old design but keep it optional
- # if one want's to load a weird config
- if config.exists(vrf_bgp_base + ['system-as']):
- system_as = config.return_value(vrf_bgp_base + ['system-as'])
- config.delete(vrf_bgp_base + ['system-as'])
-
- # If there is no existing global BGP instance - start one
- if not config.exists(bgp_base):
- config.set(bgp_base + ['system-as'], value=system_as)
- global_asn = system_as
-
- vrf_neighbor_base = vrf_bgp_base + ['neighbor']
- vrf_peer_group_base = vrf_bgp_base + ['peer-group']
- if config.exists(vrf_neighbor_base):
- for neighbor in config.list_nodes(vrf_neighbor_base):
- # Neighbor already has local-as option set, do not touch it
- if config.exists(vrf_neighbor_base + [neighbor, 'local-as']):
- #print(f'VRF {vrf} BGP neighbor {neighbor} has local-as set - do not migrate!')
- continue
-
- # Check if the neighbor uses a peer-group which has the local-as
- # option set, do not touch it either
- peer_group = None
- if config.exists(vrf_neighbor_base + [neighbor, 'peer-group']):
- peer_group = config.return_value(vrf_neighbor_base + [neighbor, 'peer-group'])
- # Check if the peer-group has a local-as option set
- if config.exists(vrf_peer_group_base + [peer_group, 'local-as']):
- #print(f'VRF {vrf} BGP neighbor {neighbor} uses peer-group {peer_group} which has local-as set - do not migrate!')
- continue
-
- # BGP local-as option is only allowed for eBGP speakers
- if global_asn == system_as:
- continue
-
- config.set(vrf_neighbor_base + [neighbor, 'local-as', system_as, 'no-prepend', 'replace-as'])
- config.set_tag(vrf_neighbor_base + [neighbor, 'local-as'])
-
- # We do also need to take care about BGP internas. When using local-as routes with our own AS
- # previously in the path will get rejected:
- # bgpd: x.x.x.x(Unknown) rcvd UPDATE about 192.0.2.0/24 IPv4 unicast -- DENIED due to: as-path contains our own AS;
- # Set allowas-in option
- allowas_in_numer = ['allowas-in', 'number']
- for afi in ['ipv4-labeled-unicast', 'ipv4-multicast', 'ipv4-unicast', 'ipv4-vpn',
- 'ipv6-labeled-unicast', 'ipv6-multicast', 'ipv6-unicast', 'ipv6-vpn']:
- afi_neighbor_base = vrf_neighbor_base + [neighbor, 'address-family', afi]
- afi_peer_group_base = vrf_peer_group_base + [peer_group, 'address-family', afi]
-
- # No need to change anything on an AFI not in use
- if not config.exists(afi_neighbor_base) and not config.exists(afi_peer_group_base):
- continue
-
- allowas_in_value = 0
- # Check if there is any allowas-in definition for a peer-group
- if peer_group and config.exists(afi_peer_group_base + allowas_in_numer):
- allowas_in_value = int(config.return_value(afi_peer_group_base + allowas_in_numer))
- #print(f'peer-group {peer_group} allowas-in for {afi} is {allowas_in_value}')
-
- # Per neighbor "allowas-in" definition takes higher precendence
- if config.exists(afi_neighbor_base + allowas_in_numer):
- allowas_in_value = int(config.return_value(afi_neighbor_base + allowas_in_numer))
- #print(f'neighbor {neighbor} allowas-in for {afi} is {allowas_in_value}')
-
- # Increment allowas-in by 1 as we now have one more entry
- allowas_in_value += 1
- # Clip allowas-in to 10 - max supported by FRR platform
- if allowas_in_value > 10: allowas_in_value = 10
-
- # Set per neighbor allowas-in which always takes precedence over the peer-group definition
- config.set(afi_neighbor_base + allowas_in_numer, value=allowas_in_value, replace=True)
diff --git a/src/migration-scripts/bgp/7-to-8 b/src/migration-scripts/bgp/7-to-8
deleted file mode 100644
index ced4f837e..000000000
--- a/src/migration-scripts/bgp/7-to-8
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# T7760: Remove per VRF setting for system-as option in VyOS 1.5 and onwards
-
-from vyos.configtree import ConfigTree
-
-def migrate(config: ConfigTree) -> None:
- vrf_base = ['vrf', 'name']
- if not config.exists(vrf_base):
- return
-
- for vrf in config.list_nodes(vrf_base):
- # bail out early if there is no per VRF BGP instance defined
- vrf_bgp_base = vrf_base + [vrf, 'protocols', 'bgp']
- if config.exists(vrf_bgp_base + ['system-as']):
- config.delete(vrf_bgp_base + ['system-as'])