diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-02-11 14:52:41 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-02-11 14:52:41 +0100 |
commit | bd3ed52d07929c644ca5c5180689f503c349b5ba (patch) | |
tree | 70b49bafee2bb1572bfcc2a73f47ff126c928afc | |
parent | 14247c27c1446241a64da713f885b57dc82e3228 (diff) | |
parent | 5a98ca315ef96d4553c1530a1bb66d5458f38fe8 (diff) | |
download | vyos-1x-bd3ed52d07929c644ca5c5180689f503c349b5ba.tar.gz vyos-1x-bd3ed52d07929c644ca5c5180689f503c349b5ba.zip |
Merge branch 'ripng' of github.com:c-po/vyos-1x into current
* 'ripng' of github.com:c-po/vyos-1x:
smoketest: static-routes: enable VRF table leaking test
rip: T2547: fix indention of distribute-list in FRR template
Makefile: remove "interfaces ip" node as all components have been migrated
ripng: T3281: migrate to get_config_dict() and FRR reload
frr: T2638: remove dedicated per protocol debugging
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | data/configd-include.json | 1 | ||||
-rw-r--r-- | data/templates/frr/rip.frr.tmpl | 4 | ||||
-rw-r--r-- | data/templates/frr/ripng.frr.tmpl | 82 | ||||
-rw-r--r-- | interface-definitions/protocols-ripng.xml.in | 4 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_ripng.py | 8 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_static.py | 26 | ||||
-rwxr-xr-x | src/conf_mode/protocols_bgp.py | 29 | ||||
-rwxr-xr-x | src/conf_mode/protocols_ospf.py | 28 | ||||
-rwxr-xr-x | src/conf_mode/protocols_ospfv3.py | 28 | ||||
-rwxr-xr-x | src/conf_mode/protocols_rip.py | 27 | ||||
-rwxr-xr-x | src/conf_mode/protocols_ripng.py | 133 | ||||
-rwxr-xr-x | src/conf_mode/protocols_rpki.py | 28 | ||||
-rwxr-xr-x | src/conf_mode/protocols_static.py | 28 | ||||
-rwxr-xr-x | src/conf_mode/protocols_vrf.py | 28 |
15 files changed, 233 insertions, 227 deletions
@@ -45,18 +45,14 @@ interface_definitions: $(config_xml_obj) rm -f $(TMPL_DIR)/vpn/node.def rm -f $(TMPL_DIR)/vpn/ipsec/node.def rm -rf $(TMPL_DIR)/vpn/nipsec - rm -rf $(TMPL_DIR)/protocols/nripng # XXX: required until OSPF and RIP is migrated from vyatta-cfg-quagga to vyos-1x mkdir $(TMPL_DIR)/interfaces/loopback/node.tag/ipv6 mkdir $(TMPL_DIR)/interfaces/dummy/node.tag/ipv6 - mkdir $(TMPL_DIR)/interfaces/openvpn/node.tag/ip - mkdir -p $(TMPL_DIR)/interfaces/vti/node.tag/ip mkdir -p $(TMPL_DIR)/interfaces/vti/node.tag/ipv6 cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def $(TMPL_DIR)/interfaces/loopback/node.tag/ipv6 cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def $(TMPL_DIR)/interfaces/dummy/node.tag/ipv6 - cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ip/node.def $(TMPL_DIR)/interfaces/openvpn/node.tag/ip - cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ip/node.def $(TMPL_DIR)/interfaces/vti/node.tag/ip + cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def $(TMPL_DIR)/interfaces/vti/node.tag/ipv6 .PHONY: op_mode_definitions diff --git a/data/configd-include.json b/data/configd-include.json index 495000961..e50dbf1b2 100644 --- a/data/configd-include.json +++ b/data/configd-include.json @@ -40,6 +40,7 @@ "protocols_ospfv3.py", "protocols_pim.py", "protocols_rip.py", +"protocols_ripng.py", "protocols_static.py", "protocols_static_multicast.py", "protocols_vrf.py", diff --git a/data/templates/frr/rip.frr.tmpl b/data/templates/frr/rip.frr.tmpl index c0d062fc6..50db2e9de 100644 --- a/data/templates/frr/rip.frr.tmpl +++ b/data/templates/frr/rip.frr.tmpl @@ -114,10 +114,10 @@ router rip {% endif %} {% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %} {% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %} -distribute-list prefix {{ distribute_list.prefix_list.in }} in + distribute-list prefix {{ distribute_list.prefix_list.in }} in {% endif %} {% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %} -distribute-list prefix {{ distribute_list.prefix_list.out }} out + distribute-list prefix {{ distribute_list.prefix_list.out }} out {% endif %} {% endif %} {% endif %} diff --git a/data/templates/frr/ripng.frr.tmpl b/data/templates/frr/ripng.frr.tmpl new file mode 100644 index 000000000..ac14dfd3f --- /dev/null +++ b/data/templates/frr/ripng.frr.tmpl @@ -0,0 +1,82 @@ +! +router ripng +{% if default_information is defined and default_information.originate is defined %} + default-information originate +{% endif %} +{% if default_metric is defined and default_metric is not none %} + default-metric {{ default_metric }} +{% endif %} +{% if aggregate_address is defined and aggregate_address is not none %} +{% for prefix in aggregate_address %} + aggregate-address {{ prefix }} +{% endfor %} +{% endif %} +{% if passive_interface is defined and passive_interface is not none %} +{% for ifname in passive_interface %} + passive-interface {{ ifname }} +{% endfor %} +{% endif %} +{% if interface is defined and interface is not none %} +{% for ifname in interface %} + network {{ ifname }} +{% endfor %} +{% endif %} +{% if network is defined and network is not none %} +{% for net in network %} + network {{ net }} +{% endfor %} +{% endif %} +{% if route is defined and route is not none %} +{% for prefix in route %} + route {{ prefix }} +{% endfor %} +{% endif %} +{% if redistribute is defined and redistribute is not none %} +{% for protocol, protocol_config in redistribute.items() %} +{% if protocol == 'ospfv3' %} +{% set protocol = 'ospf6' %} +{% endif %} + redistribute {{ protocol }} {{ 'metric ' + protocol_config.metric if protocol_config.metric is defined }} {{ 'route-map ' + protocol_config.route_map if protocol_config.route_map is defined }} +{% endfor %} +{% endif %} +{# timers have default values #} + timers basic {{ timers['update'] }} {{ timers.timeout }} {{ timers.garbage_collection }} +{% if distribute_list is defined and distribute_list is not none %} +{% if distribute_list.access_list is defined and distribute_list.access_list is not none %} +{% if distribute_list.access_list.in is defined and distribute_list.access_list.in is not none %} + ipv6 distribute-list {{ distribute_list.access_list.in }} in +{% endif %} +{% if distribute_list.access_list.out is defined and distribute_list.access_list.out is not none %} + ipv6 distribute-list {{ distribute_list.access_list.out }} out +{% endif %} +{% endif %} +{% if distribute_list.interface is defined and distribute_list.interface is not none %} +{% for interface, interface_config in distribute_list.interface.items() %} +{% if interface_config.access_list is defined and interface_config.access_list is not none %} +{% if interface_config.access_list.in is defined and interface_config.access_list.in is not none %} + ipv6 distribute-list {{ interface_config.access_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.access_list.out is defined and interface_config.access_list.out is not none %} + ipv6 distribute-list {{ interface_config.access_list.out }} out {{ interface }} +{% endif %} +{% endif %} +{% if interface_config.prefix_list is defined and interface_config.prefix_list is not none %} +{% if interface_config.prefix_list.in is defined and interface_config.prefix_list.in is not none %} + ipv6 distribute-list prefix {{ interface_config.prefix_list.in }} in {{ interface }} +{% endif %} +{% if interface_config.prefix_list.out is defined and interface_config.prefix_list.out is not none %} + ipv6 distribute-list prefix {{ interface_config.prefix_list.out }} out {{ interface }} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% if distribute_list.prefix_list is defined and distribute_list.prefix_list is not none %} +{% if distribute_list.prefix_list.in is defined and distribute_list.prefix_list.in is not none %} + ipv6 distribute-list prefix {{ distribute_list.prefix_list.in }} in +{% endif %} +{% if distribute_list.prefix_list.out is defined and distribute_list.prefix_list.out is not none %} + ipv6 distribute-list prefix {{ distribute_list.prefix_list.out }} out +{% endif %} +{% endif %} +{% endif %} +! diff --git a/interface-definitions/protocols-ripng.xml.in b/interface-definitions/protocols-ripng.xml.in index 74f720e89..e456c3f3b 100644 --- a/interface-definitions/protocols-ripng.xml.in +++ b/interface-definitions/protocols-ripng.xml.in @@ -1,8 +1,8 @@ -<!-- Routing Information Protocol (RIPng) configuration --> +<?xml version="1.0"?> <interfaceDefinition> <node name="protocols"> <children> - <node name="nripng" owner="${vyos_conf_scripts_dir}/protocols_ripng.py"> + <node name="ripng" owner="${vyos_conf_scripts_dir}/protocols_ripng.py"> <properties> <help>Routing Information Protocol (RIPng) parameters</help> </properties> diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py index 90cbaccd8..6850b60d3 100755 --- a/smoketest/scripts/cli/test_protocols_ripng.py +++ b/smoketest/scripts/cli/test_protocols_ripng.py @@ -107,10 +107,10 @@ class TestProtocolsRIPng(unittest.TestCase): self.assertIn(f'router ripng', frrconfig) self.assertIn(f' default-information originate', frrconfig) self.assertIn(f' default-metric {metric}', frrconfig) - self.assertIn(f' distribute-list {acl_in} in', frrconfig) - self.assertIn(f' distribute-list {acl_out} out', frrconfig) - self.assertIn(f' distribute-list prefix {prefix_list_in} in', frrconfig) - self.assertIn(f' distribute-list prefix {prefix_list_out} out', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_in} in', frrconfig) + self.assertIn(f' ipv6 distribute-list {acl_out} out', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out', frrconfig) self.assertIn(f' passive-interface default', frrconfig) self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig) for aggregate in aggregates: diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py index a4c320a62..cf591f060 100755 --- a/smoketest/scripts/cli/test_protocols_static.py +++ b/smoketest/scripts/cli/test_protocols_static.py @@ -212,11 +212,8 @@ class StaticRouteTest(unittest.TestCase): self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']]) if 'interface' in next_hop_config: self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']]) - - # This is currently not supported because of an FRR issue: - # https://github.com/FRRouting/frr/issues/8016 - # if 'vrf' in next_hop_config: - # self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']]) + if 'vrf' in next_hop_config: + self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']]) if 'interface' in route_config: @@ -226,11 +223,8 @@ class StaticRouteTest(unittest.TestCase): self.session.set(base + ['interface', interface, 'disable']) if 'distance' in interface_config: self.session.set(base + ['interface', interface, 'distance', interface_config['distance']]) - - # This is currently not supported because of an FRR issue: - # https://github.com/FRRouting/frr/issues/8016 - # if 'vrf' in interface_config: - # self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']]) + if 'vrf' in interface_config: + self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']]) if 'blackhole' in route_config: self.session.set(base + ['blackhole']) @@ -259,10 +253,8 @@ class StaticRouteTest(unittest.TestCase): tmp += ' ' + next_hop_config['interface'] if 'distance' in next_hop_config: tmp += ' ' + next_hop_config['distance'] - # This is currently not supported because of an FRR issue: - # https://github.com/FRRouting/frr/issues/8016 - # if 'vrf' in next_hop_config: - # tmp += ' nexthop-vrf ' + next_hop_config['vrf'] + if 'vrf' in next_hop_config: + tmp += ' nexthop-vrf ' + next_hop_config['vrf'] tmp += ' table ' + table if 'disable' in next_hop_config: @@ -277,10 +269,8 @@ class StaticRouteTest(unittest.TestCase): tmp += ' ' + interface_config['interface'] if 'distance' in interface_config: tmp += ' ' + interface_config['distance'] - # This is currently not supported because of an FRR issue: - # https://github.com/FRRouting/frr/issues/8016 - # if 'vrf' in interface_config: - # tmp += ' nexthop-vrf ' + interface_config['vrf'] + if 'vrf' in interface_config: + tmp += ' nexthop-vrf ' + interface_config['vrf'] tmp += ' table ' + table if 'disable' in interface_config: diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 41d89e03b..a2c129149 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -20,7 +20,6 @@ from sys import exit from vyos.config import Config from vyos.configdict import dict_merge -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos.util import dict_search @@ -29,17 +28,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/bgp.frr' 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 @@ -156,10 +146,7 @@ def generate(bgp): asn = list(bgp.keys())[0] bgp[asn]['asn'] = asn - # render(config) not needed, its only for debug - render(config_file, 'frr/bgp.frr.tmpl', bgp[asn]) bgp['new_frr_config'] = render_to_string('frr/bgp.frr.tmpl', bgp[asn]) - return None def apply(bgp): @@ -168,21 +155,6 @@ def apply(bgp): 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']) - - # 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 @@ -191,7 +163,6 @@ def apply(bgp): for a in range(5): frr_cfg.commit_configuration(frr_daemon) - return None if __name__ == '__main__': diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py index 3310fac5a..5e0794fa0 100755 --- a/src/conf_mode/protocols_ospf.py +++ b/src/conf_mode/protocols_ospf.py @@ -22,7 +22,6 @@ from vyos.config import Config from vyos.configdict import dict_merge from vyos.configverify import verify_route_maps from vyos.configverify import verify_interface_exists -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos.util import dict_search @@ -32,17 +31,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/ospf.frr' frr_daemon = 'ospfd' -DEBUG = os.path.exists('/tmp/ospf.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 @@ -140,10 +130,7 @@ def generate(ospf): ospf['new_frr_config'] = '' return None - # render(config) not needed, its only for debug - render(config_file, 'frr/ospf.frr.tmpl', ospf) ospf['new_frr_config'] = render_to_string('frr/ospf.frr.tmpl', ospf) - return None def apply(ospf): @@ -153,21 +140,6 @@ def apply(ospf): frr_cfg.modify_section(r'interface \S+', '') frr_cfg.modify_section('router ospf', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospf['new_frr_config']) - - # 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'{ospf["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 diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py index e008a350b..6c3aaf426 100755 --- a/src/conf_mode/protocols_ospfv3.py +++ b/src/conf_mode/protocols_ospfv3.py @@ -21,7 +21,6 @@ from sys import exit from vyos.config import Config from vyos.configdict import dict_merge from vyos.configverify import verify_route_maps -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos.xml import defaults @@ -30,17 +29,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/ospfv3.frr' frr_daemon = 'ospf6d' -DEBUG = os.path.exists('/tmp/ospfv3.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 @@ -74,10 +64,7 @@ def generate(ospfv3): ospfv3['new_frr_config'] = '' return None - # render(config) not needed, its only for debug - render(config_file, 'frr/ospfv3.frr.tmpl', ospfv3) ospfv3['new_frr_config'] = render_to_string('frr/ospfv3.frr.tmpl', ospfv3) - return None def apply(ospfv3): @@ -86,21 +73,6 @@ def apply(ospfv3): frr_cfg.load_configuration(frr_daemon) frr_cfg.modify_section('router ospf6', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospfv3['new_frr_config']) - - # 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'{ospfv3["new_frr_config"]}') - print(f'Modified config:\n') - print(f'{frr_cfg}') - frr_cfg.commit_configuration(frr_daemon) # If FRR config is blank, re-run the blank commit x times due to frr-reload diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py index 06d7c6d49..6db5143c5 100755 --- a/src/conf_mode/protocols_rip.py +++ b/src/conf_mode/protocols_rip.py @@ -24,24 +24,14 @@ from vyos.configverify import verify_route_maps from vyos.util import call from vyos.util import dict_search from vyos.xml import defaults -from vyos.template import render from vyos.template import render_to_string from vyos import ConfigError from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/rip.frr' frr_daemon = 'ripd' -DEBUG = os.path.exists('/tmp/rip.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 @@ -106,8 +96,6 @@ def generate(rip): rip['new_frr_config'] = '' return None - # render(config) not needed, its only for debug - render(config_file, 'frr/rip.frr.tmpl', rip) rip['new_frr_config'] = render_to_string('frr/rip.frr.tmpl', rip) return None @@ -120,21 +108,6 @@ def apply(rip): frr_cfg.modify_section(r'interface \S+', '') frr_cfg.modify_section('router rip', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rip['new_frr_config']) - - # 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'{rip["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 diff --git a/src/conf_mode/protocols_ripng.py b/src/conf_mode/protocols_ripng.py new file mode 100755 index 000000000..8cc5de64a --- /dev/null +++ b/src/conf_mode/protocols_ripng.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 VyOS maintainers and contributors +# +# 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/>. + +import os + +from sys import exit + +from vyos.config import Config +from vyos.configdict import dict_merge +from vyos.configverify import verify_route_maps +from vyos.util import call +from vyos.util import dict_search +from vyos.xml import defaults +from vyos.template import render_to_string +from vyos import ConfigError +from vyos import frr +from vyos import airbag +airbag.enable() + +frr_daemon = 'ripngd' + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + base = ['protocols', 'ripng'] + ripng = 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 ripng + + # We have gathered the dict representation of the CLI, but there are default + # options which we need to update into the dictionary retrived. + default_values = defaults(base) + # merge in remaining default values + ripng = dict_merge(default_values, ripng) + + # We also need some additional information from the config, prefix-lists + # and route-maps for instance. They will be used in verify() + base = ['policy'] + tmp = conf.get_config_dict(base, key_mangling=('-', '_')) + # Merge policy dict into OSPF dict + ripng = dict_merge(tmp, ripng) + + import pprint + pprint.pprint(ripng) + return ripng + +def verify(ripng): + if not ripng: + return None + + acl_in = dict_search('distribute_list.access_list.in', ripng) + if acl_in and acl_in not in (dict_search('policy.access_list6', ripng) or []): + raise ConfigError(f'Inbound access-list6 "{acl_in}" does not exist!') + + acl_out = dict_search('distribute_list.access_list.out', ripng) + if acl_out and acl_out not in (dict_search('policy.access_list6', ripng) or []): + raise ConfigError(f'Outbound access-list6 "{acl_out}" does not exist!') + + prefix_list_in = dict_search('distribute_list.prefix_list.in', ripng) + if prefix_list_in and prefix_list_in.replace('-','_') not in (dict_search('policy.prefix_list6', ripng) or []): + raise ConfigError(f'Inbound prefix-list6 "{prefix_list_in}" does not exist!') + + prefix_list_out = dict_search('distribute_list.prefix_list.out', ripng) + if prefix_list_out and prefix_list_out.replace('-','_') not in (dict_search('policy.prefix_list6', ripng) or []): + raise ConfigError(f'Outbound prefix-list6 "{prefix_list_out}" does not exist!') + + if 'interface' in ripng: + for interface, interface_options in ripng['interface'].items(): + if 'authentication' in interface_options: + if {'md5', 'plaintext_password'} <= set(interface_options['authentication']): + raise ConfigError('Can not use both md5 and plaintext-password at the same time!') + if 'split_horizon' in interface_options: + if {'disable', 'poison_reverse'} <= set(interface_options['split_horizon']): + raise ConfigError(f'You can not have "split-horizon poison-reverse" enabled ' \ + f'with "split-horizon disable" for "{interface}"!') + + verify_route_maps(ripng) + +def generate(ripng): + if not ripng: + ripng['new_frr_config'] = '' + return None + + ripng['new_frr_config'] = render_to_string('frr/ripng.frr.tmpl', ripng) + import pprint + pprint.pprint(ripng['new_frr_config']) + + return None + +def apply(ripng): + # Save original configuration prior to starting any commit actions + frr_cfg = frr.FRRConfig() + frr_cfg.load_configuration(frr_daemon) + frr_cfg.modify_section(r'key chain \S+', '') + frr_cfg.modify_section(r'interface \S+', '') + frr_cfg.modify_section('router ripng', '') + frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ripng['new_frr_config']) + 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 ripng['new_frr_config'] == '': + for a in range(5): + frr_cfg.commit_configuration(frr_daemon) + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) diff --git a/src/conf_mode/protocols_rpki.py b/src/conf_mode/protocols_rpki.py index 0b9525caf..75b870b05 100755 --- a/src/conf_mode/protocols_rpki.py +++ b/src/conf_mode/protocols_rpki.py @@ -20,7 +20,6 @@ from sys import exit from vyos.config import Config from vyos.configdict import dict_merge -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos.util import dict_search @@ -30,17 +29,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/rpki.frr' frr_daemon = 'bgpd' -DEBUG = os.path.exists('/tmp/rpki.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 @@ -90,10 +80,7 @@ def verify(rpki): return None def generate(rpki): - # render(config) not needed, its only for debug - render(config_file, 'frr/rpki.frr.tmpl', rpki) rpki['new_frr_config'] = render_to_string('frr/rpki.frr.tmpl', rpki) - return None def apply(rpki): @@ -102,21 +89,6 @@ def apply(rpki): frr_cfg.load_configuration(frr_daemon) frr_cfg.modify_section('rpki', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rpki['new_frr_config']) - - # 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'{rpki["new_frr_config"]}') - print(f'Modified config:\n') - print(f'{frr_cfg}') - frr_cfg.commit_configuration(frr_daemon) # If FRR config is blank, re-run the blank commit x times due to frr-reload diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py index 62a3fecd7..5d101b33e 100755 --- a/src/conf_mode/protocols_static.py +++ b/src/conf_mode/protocols_static.py @@ -19,7 +19,6 @@ import os from sys import exit from vyos.config import Config -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos.configverify import verify_route_maps @@ -28,17 +27,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/static.frr' frr_daemon = 'staticd' -DEBUG = os.path.exists('/tmp/static.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 @@ -53,10 +43,7 @@ def verify(static): return None def generate(static): - # render(config) not needed, its only for debug - render(config_file, 'frr/static.frr.tmpl', static) static['new_frr_config'] = render_to_string('frr/static.frr.tmpl', static) - return None def apply(static): @@ -66,21 +53,6 @@ def apply(static): frr_cfg.modify_section(r'^ip route .*', '') frr_cfg.modify_section(r'^ipv6 route .*', '') frr_cfg.add_before(r'(interface .*|line vty)', static['new_frr_config']) - - # 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'{static["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 diff --git a/src/conf_mode/protocols_vrf.py b/src/conf_mode/protocols_vrf.py index 7c32c7013..227e7d5e1 100755 --- a/src/conf_mode/protocols_vrf.py +++ b/src/conf_mode/protocols_vrf.py @@ -19,7 +19,6 @@ import os from sys import exit from vyos.config import Config -from vyos.template import render from vyos.template import render_to_string from vyos.util import call from vyos import ConfigError @@ -27,17 +26,8 @@ from vyos import frr from vyos import airbag airbag.enable() -config_file = r'/tmp/vrf.frr' frr_daemon = 'staticd' -DEBUG = os.path.exists('/tmp/vrf.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 @@ -52,10 +42,7 @@ def verify(vrf): return None def generate(vrf): - # render(config) not needed, its only for debug - render(config_file, 'frr/vrf.frr.tmpl', vrf) vrf['new_frr_config'] = render_to_string('frr/vrf.frr.tmpl', vrf) - return None def apply(vrf): @@ -64,21 +51,6 @@ def apply(vrf): frr_cfg.load_configuration(frr_daemon) frr_cfg.modify_section(r'vrf \S+', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', vrf['new_frr_config']) - - # 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'{vrf["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 |