diff options
Diffstat (limited to 'src/conf_mode/protocols_bgp.py')
-rwxr-xr-x | src/conf_mode/protocols_bgp.py | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index de0148b2f..41d89e03b 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import os + from sys import exit from vyos.config import Config @@ -28,12 +30,25 @@ from vyos import airbag airbag.enable() config_file = r'/tmp/bgp.frr' - -def get_config(): - conf = Config() +frr_daemon = 'bgpd' + +DEBUG = os.path.exists('/tmp/bgp.debug') +if DEBUG: + import logging + lg = logging.getLogger("vyos.frr") + lg.setLevel(logging.DEBUG) + ch = logging.StreamHandler() + lg.addHandler(ch) + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['protocols', 'bgp'] bgp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + # Bail out early if configuration tree does not exist if not conf.exists(base): return bgp @@ -78,8 +93,13 @@ def verify(bgp): if neighbor == 'neighbor': # remote-as must be either set explicitly for the neighbor # or for the entire peer-group - if 'remote_as' not in peer_config: - if 'peer_group' not in peer_config or 'remote_as' not in asn_config['peer_group'][peer_config['peer_group']]: + if 'interface' in peer_config: + if 'remote_as' not in peer_config['interface']: + if 'peer_group' not in peer_config['interface'] or 'remote_as' not in asn_config['peer_group'][ peer_config['interface']['peer_group'] ]: + raise ConfigError('Remote AS must be set for neighbor or peer-group!') + + elif 'remote_as' not in peer_config: + if 'peer_group' not in peer_config or 'remote_as' not in asn_config['peer_group'][ peer_config['peer_group'] ]: raise ConfigError('Remote AS must be set for neighbor or peer-group!') for afi in ['ipv4_unicast', 'ipv6_unicast']: @@ -94,7 +114,7 @@ def verify(bgp): if tmp not in afi_config['prefix_list']: # bail out early continue - # get_config_dict() mangles all '-' characters to '_' this is legitim, thus all our + # get_config_dict() mangles all '-' characters to '_' this is legitimate, thus all our # compares will run on '_' as also '_' is a valid name for a prefix-list prefix_list = afi_config['prefix_list'][tmp].replace('-', '_') if afi == 'ipv4_unicast': @@ -113,6 +133,16 @@ def verify(bgp): if dict_search(f'policy.route_map.{route_map}', asn_config) == None: raise ConfigError(f'route-map "{route_map}" used for "{tmp}" does not exist!') + # Throw an error if a peer group is not configured for allow range + for prefix in dict_search('listen.range', asn_config) or []: + # we can not use dict_search() here as prefix contains dots ... + if 'peer_group' not in asn_config['listen']['range'][prefix]: + raise ConfigError(f'Listen range for prefix "{prefix}" has no peer group configured.') + else: + peer_group = asn_config['listen']['range'][prefix]['peer_group'] + # the peer group must also exist + if not dict_search(f'peer_group.{peer_group}', asn_config): + raise ConfigError(f'Peer-group "{peer_group}" for listen range "{prefix}" does not exist!') return None @@ -135,25 +165,32 @@ def generate(bgp): def apply(bgp): # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() - frr_cfg.load_configuration(daemon='bgpd') + frr_cfg.load_configuration(frr_daemon) frr_cfg.modify_section(f'router bgp \S+', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', bgp['new_frr_config']) - frr_cfg.commit_configuration(daemon='bgpd') + + # Debugging + if DEBUG: + from pprint import pprint + print('') + print('--------- DEBUGGING ----------') + pprint(dir(frr_cfg)) + print('Existing config:\n') + for line in frr_cfg.original_config: + print(line) + print(f'Replacement config:\n') + print(f'{bgp["new_frr_config"]}') + print(f'Modified config:\n') + print(f'{frr_cfg}') + + frr_cfg.commit_configuration(frr_daemon) # If FRR config is blank, rerun the blank commit x times due to frr-reload # behavior/bug not properly clearing out on one commit. if bgp['new_frr_config'] == '': for a in range(5): - frr_cfg.commit_configuration(daemon='bgpd') + frr_cfg.commit_configuration(frr_daemon) - # Debugging - ''' - print('') - print('--------- DEBUGGING ----------') - print(f'Existing config:\n{frr_cfg["original_config"]}\n\n') - print(f'Replacement config:\n{bgp["new_frr_config"]}\n\n') - print(f'Modified config:\n{frr_cfg["modified_config"]}\n\n') - ''' return None |