From 76ac6e9885d587921ac6dc54a3bd056c5dc74b4d Mon Sep 17 00:00:00 2001 From: zsdc Date: Sat, 27 Nov 2021 01:40:21 +0200 Subject: FRR: T4020: Added CLI options for FRR daemons Added first CLI items for controlling FRR daemons parameters that cannot be changed via vtysh and are available via arguments only. Now it is possible to enable/disable modules: SNMP (for each daemon), BMP (for BGP), IRDP (for Zebra). --- interface-definitions/system-frr.xml.in | 66 ++++++++++++ smoketest/scripts/cli/test_system_frr.py | 146 ++++++++++++++++++++++++++ src/conf_mode/snmp.py | 6 +- src/conf_mode/system_frr.py | 173 +++++++++++++++++++++++++++++++ 4 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 interface-definitions/system-frr.xml.in create mode 100755 smoketest/scripts/cli/test_system_frr.py create mode 100755 src/conf_mode/system_frr.py diff --git a/interface-definitions/system-frr.xml.in b/interface-definitions/system-frr.xml.in new file mode 100644 index 000000000..e8b447f58 --- /dev/null +++ b/interface-definitions/system-frr.xml.in @@ -0,0 +1,66 @@ + + + + + + + Configure FRR parameters + + 150 + + + + + >Enable BGP Monitoring Protocol support + + + + + + >Enable ICMP Router Discovery Protocol support + + + + + + Enable SNMP integration for next daemons + + + + + >BGP + + + + + + >OSPFv3 + + + + + + >OSPFv2 + + + + + + >RIP + + + + + + >Zebra (IP routing manager) + + + + + + + + + + + diff --git a/smoketest/scripts/cli/test_system_frr.py b/smoketest/scripts/cli/test_system_frr.py new file mode 100755 index 000000000..331133ed4 --- /dev/null +++ b/smoketest/scripts/cli/test_system_frr.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019-2020 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 . + +import re +import unittest +from base_vyostest_shim import VyOSUnitTestSHIM +from vyos.util import read_file + +config_file = '/etc/frr/daemons' +base_path = ['system', 'frr'] + + +def daemons_config_parse(daemons_config): + # create regex for parsing daemons options + regex_daemon_config = re.compile( + r'^(?P\w+)_options="(?P.*)"$', re.M) + # create empty dict for config + daemons_config_dict = {} + # fill dictionary with actual config + for daemon in regex_daemon_config.finditer(daemons_config): + daemon_name = daemon.group('daemon_name') + daemon_options = daemon.group('daemon_options') + daemons_config_dict[daemon_name] = daemon_options + + # return daemons config + return (daemons_config_dict) + + +class TestSystemFRR(VyOSUnitTestSHIM.TestCase): + + def tearDown(self): + self.cli_delete(base_path) + self.cli_commit() + + def test_frr_snmp_multipledaemons(self): + # test SNMP integration for multiple daemons + test_daemon_names = ['ospfd', 'bgpd'] + for test_daemon_name in test_daemon_names: + self.cli_set(base_path + ['snmp', test_daemon_name]) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex for matching SNMP integration + regex_snmp = re.compile(r'^.* -M snmp.*$') + for (daemon_name, daemon_options) in daemons_config_dict.items(): + snmp_enabled = regex_snmp.match(daemon_options) + if daemon_name in test_daemon_names: + self.assertTrue(snmp_enabled) + else: + self.assertFalse(snmp_enabled) + + def test_frr_snmp_addandremove(self): + # test enabling and disabling of SNMP integration + test_daemon_names = ['ospfd', 'bgpd'] + for test_daemon_name in test_daemon_names: + self.cli_set(base_path + ['snmp', test_daemon_name]) + self.cli_commit() + + self.cli_delete(base_path) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex for matching SNMP integration + regex_snmp = re.compile(r'^.* -M snmp.*$') + for test_daemon_name in test_daemon_names: + snmp_enabled = regex_snmp.match( + daemons_config_dict[test_daemon_name]) + self.assertFalse(snmp_enabled) + + def test_frr_snmp_empty(self): + # test empty config section + self.cli_set(base_path + ['snmp']) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex for matching SNMP integration + regex_snmp = re.compile(r'^.* -M snmp.*$') + for daemon_options in daemons_config_dict.values(): + snmp_enabled = regex_snmp.match(daemon_options) + self.assertFalse(snmp_enabled) + + def test_frr_bmp(self): + # test BMP + self.cli_set(base_path + ['bmp']) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex + regex_bmp = re.compile(r'^.* -M bmp.*$') + bmp_enabled = regex_bmp.match(daemons_config_dict['bgpd']) + self.assertTrue(bmp_enabled) + + def test_frr_irdp(self): + # test IRDP + self.cli_set(base_path + ['irdp']) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex + regex_irdp = re.compile(r'^.* -M irdp.*$') + irdp_enabled = regex_irdp.match(daemons_config_dict['zebra']) + self.assertTrue(irdp_enabled) + + def test_frr_bmpandsnmp(self): + # test empty config section + self.cli_set(base_path + ['bmp']) + self.cli_set(base_path + ['snmp', 'bgpd']) + self.cli_commit() + + # read the config file and check content + daemons_config = read_file(config_file) + daemons_config_dict = daemons_config_parse(daemons_config) + # prepare regex + regex_snmp = re.compile(r'^.* -M bmp.*$') + regex_snmp = re.compile(r'^.* -M snmp.*$') + bmp_enabled = regex_snmp.match(daemons_config_dict['bgpd']) + snmp_enabled = regex_snmp.match(daemons_config_dict['bgpd']) + self.assertTrue(bmp_enabled) + self.assertTrue(snmp_enabled) + + +if __name__ == '__main__': + unittest.main(verbosity=2, failfast=True) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index e1852f2ce..25dcdf7c6 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -581,7 +581,11 @@ def apply(snmp): call('systemctl restart snmpd.service') # Enable AgentX in FRR - call('vtysh -c "configure terminal" -c "agentx" >/dev/null') + # This should be done for each daemon individually because common command + # works only if all the daemons started with SNMP support + frr_daemons_list = ['bgpd', 'ospf6d', 'ospfd', 'ripd', 'zebra'] + for frr_daemon in frr_daemons_list: + call(f'vtysh -c "configure terminal" -d {frr_daemon} -c "agentx" >/dev/null') return None diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py new file mode 100755 index 000000000..cc47aa5be --- /dev/null +++ b/src/conf_mode/system_frr.py @@ -0,0 +1,173 @@ +#!/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 . + +from pathlib import Path +from re import compile as re_compile +from re import M as re_M +from sys import exit + +from vyos import ConfigError +from vyos import airbag +from vyos.config import Config +from vyos.logger import syslog +from vyos.util import read_file, write_file, run +airbag.enable() + +# path to daemons config and config status files +config_file = '/etc/frr/daemons' +vyos_status_file = '/tmp/vyos-config-status' +# path to watchfrr for FRR control +watchfrr = '/usr/lib/frr/watchfrr.sh' + + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + base = ['system', 'frr'] + if not conf.exists(base): + return {} + + frr_config = conf.get_config_dict(base) + + return frr_config + + +def daemons_config_parse(daemons_config): + # create regex for parsing daemons options + regex_daemon_config = re_compile( + r'^(?P\w+)_options="(?P.*)"$', re_M) + # create empty dict for config + daemons_config_dict = {} + # fill dictionary with actual config + for daemon in regex_daemon_config.finditer(daemons_config): + daemon_name = daemon.group('daemon_name') + daemon_options = daemon.group('daemon_options') + daemons_config_dict[daemon_name] = daemon_options + + # return daemons config + return (daemons_config_dict) + + +def verify(frr_config): + # Nothing to verify here + pass + + +def generate(frr_config): + # read daemons config file + daemons_config = read_file(config_file) + daemons_config_current = daemons_config + daemons_config_dict = daemons_config_parse(daemons_config) + + # configure SNMP integration + frr_snmp = frr_config.get('frr', {}).get('snmp', {}) + # prepare regex for matching modules + regex_snmp = re_compile(r'^.* -M snmp.*$') + regex_bmp = re_compile(r'^.* -M bmp.*$') + regex_irdp = re_compile(r'^.* -M irdp.*$') + # check each daemon's config + for (daemon_name, daemon_options) in daemons_config_dict.items(): + # check if SNMP integration is enabled in the config file + snmp_enabled = regex_snmp.match(daemon_options) + # check if BMP is enabled in the config file + bmp_enabled = regex_bmp.match(daemon_options) + # check if IRDP is enabled in the config file + irdp_enabled = regex_irdp.match(daemon_options) + + # enable SNMP integration + if daemon_name in frr_snmp and not snmp_enabled: + daemon_options_new = f'{daemon_options} -M snmp' + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + daemon_options = daemon_options_new + # disable SNMP integration + if daemon_name not in frr_snmp and snmp_enabled: + daemon_options_new = daemon_options.replace(' -M snmp', '') + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + daemon_options = daemon_options_new + + # enable BMP + if daemon_name == 'bgpd' and 'bmp' in frr_config.get( + 'frr', {}) and not bmp_enabled: + daemon_options_new = f'{daemon_options} -M bmp' + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + daemon_options = daemon_options_new + # disable BMP + if daemon_name == 'bgpd' and 'bmp' not in frr_config.get( + 'frr', {}) and bmp_enabled: + daemon_options_new = daemon_options.replace(' -M bmp', '') + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + daemon_options = daemon_options_new + + # enable IRDP + if daemon_name == 'zebra' and 'irdp' in frr_config.get( + 'frr', {}) and not irdp_enabled: + daemon_options_new = f'{daemon_options} -M irdp' + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + daemon_options = daemon_options_new + # disable IRDP + if daemon_name == 'zebra' and 'irdp' not in frr_config.get( + 'frr', {}) and irdp_enabled: + daemon_options_new = daemon_options.replace(' -M irdp', '') + daemons_config = daemons_config.replace( + f'{daemon_name}_options=\"{daemon_options}\"', + f'{daemon_name}_options=\"{daemon_options_new}\"') + + # update configuration file if this is necessary + if daemons_config != daemons_config_current: + write_file(config_file, daemons_config) + frr_config['config_file_changed'] = True + + +def apply(frr_config): + # check if this is initial commit during boot or intiated by CLI + # if the file exists, this must be CLI commit + commit_type_cli = Path(vyos_status_file).exists() + # display warning to user + if commit_type_cli and frr_config.get('config_file_changed'): + # Since FRR restart is not safe thing, better to give + # control over this to users + print(''' + You need to reboot a router (preferred) or restart FRR + to apply changes in modules settings + ''') + # restart FRR automatically. DUring the initial boot this should be + # safe in most cases + if not commit_type_cli and frr_config.get('config_file_changed'): + syslog.warning('Restarting FRR to apply changes in modules') + run(f'{watchfrr} restart') + + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) -- cgit v1.2.3 From 1af618103f288d83c51dee3d20e49f06e02b1ac7 Mon Sep 17 00:00:00 2001 From: zsdc Date: Tue, 7 Dec 2021 13:25:42 +0200 Subject: FRR: T4020: Updated CLI options processing for FRR daemons Instead of analyzing options for each daemon now we use a single template for the whole configuration file. This makes logic a bit less flexible, but much easier. Removed unnecessary check for returned by the `conf.get_config_dict(base)` config. Also, added the ability to disable `strip()` of file content while using `read_file()` what is necessary for proper comparing with updated content. --- data/templates/frr/daemons.frr.tmpl | 50 ++++++++++++++++++ python/vyos/util.py | 12 +++-- src/conf_mode/system_frr.py | 100 ++++-------------------------------- 3 files changed, 67 insertions(+), 95 deletions(-) create mode 100644 data/templates/frr/daemons.frr.tmpl diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl new file mode 100644 index 000000000..089cdae3b --- /dev/null +++ b/data/templates/frr/daemons.frr.tmpl @@ -0,0 +1,50 @@ +zebra=yes +bgpd=yes +ospfd=yes +ospf6d=yes +ripd=yes +ripngd=yes +isisd=yes +pimd=no +ldpd=yes +nhrpd=no +eigrpd=no +babeld=no +sharpd=no +pbrd=no +bfdd=yes +staticd=yes + +vtysh_enable=yes +zebra_options=" -s 90000000 --daemon -A 127.0.0.1 +{%- if irdp is defined %} -M irdp{% endif -%} +{%- if snmp is defined and snmp.zebra is defined %} -M snmp{% endif -%} +" +bgpd_options=" --daemon -A 127.0.0.1 +{%- if bmp is defined %} -M bmp{% endif -%} +{%- if snmp is defined and snmp.bgpd is defined %} -M snmp{% endif -%} +" +ospfd_options=" --daemon -A 127.0.0.1 +{%- if snmp is defined and snmp.ospfd is defined %} -M snmp{% endif -%} +" +ospf6d_options=" --daemon -A ::1 +{%- if snmp is defined and snmp.ospf6d is defined %} -M snmp{% endif -%} +" +ripd_options=" --daemon -A 127.0.0.1 +{%- if snmp is defined and snmp.ripd is defined %} -M snmp{% endif -%} +" +ripngd_options=" --daemon -A ::1" +isisd_options=" --daemon -A 127.0.0.1" +pimd_options=" --daemon -A 127.0.0.1" +ldpd_options=" --daemon -A 127.0.0.1" +nhrpd_options=" --daemon -A 127.0.0.1" +eigrpd_options=" --daemon -A 127.0.0.1" +babeld_options=" --daemon -A 127.0.0.1" +sharpd_options=" --daemon -A 127.0.0.1" +pbrd_options=" --daemon -A 127.0.0.1" +staticd_options=" --daemon -A 127.0.0.1" +bfdd_options=" --daemon -A 127.0.0.1" + +watchfrr_enable=no +valgrind_enable=no + diff --git a/python/vyos/util.py b/python/vyos/util.py index d8e83ab8d..ce5dc51f5 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -182,16 +182,20 @@ def call(command, flag='', shell=None, input=None, timeout=None, env=None, return code -def read_file(fname, defaultonfailure=None): +def read_file(fname, defaultonfailure=None, strip_end=True): """ - read the content of a file, stripping any end characters (space, newlines) + read the content of a file, optionally stripping any end characters (space, newlines) should defaultonfailure be not None, it is returned on failure to read """ try: """ Read a file to string """ with open(fname, 'r') as f: - data = f.read().strip() - return data + data = f.read() + + if strip_end: + return data.strip() + else: + return data except Exception as e: if defaultonfailure is not None: return defaultonfailure diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py index cc47aa5be..0d0b37e00 100755 --- a/src/conf_mode/system_frr.py +++ b/src/conf_mode/system_frr.py @@ -15,14 +15,13 @@ # along with this program. If not, see . from pathlib import Path -from re import compile as re_compile -from re import M as re_M from sys import exit from vyos import ConfigError from vyos import airbag from vyos.config import Config from vyos.logger import syslog +from vyos.template import render_to_string from vyos.util import read_file, write_file, run airbag.enable() @@ -38,31 +37,13 @@ def get_config(config=None): conf = config else: conf = Config() - base = ['system', 'frr'] - if not conf.exists(base): - return {} - frr_config = conf.get_config_dict(base) + base = ['system', 'frr'] + frr_config = conf.get_config_dict(base, get_first_key=True) return frr_config -def daemons_config_parse(daemons_config): - # create regex for parsing daemons options - regex_daemon_config = re_compile( - r'^(?P\w+)_options="(?P.*)"$', re_M) - # create empty dict for config - daemons_config_dict = {} - # fill dictionary with actual config - for daemon in regex_daemon_config.finditer(daemons_config): - daemon_name = daemon.group('daemon_name') - daemon_options = daemon.group('daemon_options') - daemons_config_dict[daemon_name] = daemon_options - - # return daemons config - return (daemons_config_dict) - - def verify(frr_config): # Nothing to verify here pass @@ -70,76 +51,13 @@ def verify(frr_config): def generate(frr_config): # read daemons config file - daemons_config = read_file(config_file) - daemons_config_current = daemons_config - daemons_config_dict = daemons_config_parse(daemons_config) - - # configure SNMP integration - frr_snmp = frr_config.get('frr', {}).get('snmp', {}) - # prepare regex for matching modules - regex_snmp = re_compile(r'^.* -M snmp.*$') - regex_bmp = re_compile(r'^.* -M bmp.*$') - regex_irdp = re_compile(r'^.* -M irdp.*$') - # check each daemon's config - for (daemon_name, daemon_options) in daemons_config_dict.items(): - # check if SNMP integration is enabled in the config file - snmp_enabled = regex_snmp.match(daemon_options) - # check if BMP is enabled in the config file - bmp_enabled = regex_bmp.match(daemon_options) - # check if IRDP is enabled in the config file - irdp_enabled = regex_irdp.match(daemon_options) - - # enable SNMP integration - if daemon_name in frr_snmp and not snmp_enabled: - daemon_options_new = f'{daemon_options} -M snmp' - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - daemon_options = daemon_options_new - # disable SNMP integration - if daemon_name not in frr_snmp and snmp_enabled: - daemon_options_new = daemon_options.replace(' -M snmp', '') - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - daemon_options = daemon_options_new - - # enable BMP - if daemon_name == 'bgpd' and 'bmp' in frr_config.get( - 'frr', {}) and not bmp_enabled: - daemon_options_new = f'{daemon_options} -M bmp' - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - daemon_options = daemon_options_new - # disable BMP - if daemon_name == 'bgpd' and 'bmp' not in frr_config.get( - 'frr', {}) and bmp_enabled: - daemon_options_new = daemon_options.replace(' -M bmp', '') - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - daemon_options = daemon_options_new - - # enable IRDP - if daemon_name == 'zebra' and 'irdp' in frr_config.get( - 'frr', {}) and not irdp_enabled: - daemon_options_new = f'{daemon_options} -M irdp' - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - daemon_options = daemon_options_new - # disable IRDP - if daemon_name == 'zebra' and 'irdp' not in frr_config.get( - 'frr', {}) and irdp_enabled: - daemon_options_new = daemon_options.replace(' -M irdp', '') - daemons_config = daemons_config.replace( - f'{daemon_name}_options=\"{daemon_options}\"', - f'{daemon_name}_options=\"{daemon_options_new}\"') - + daemons_config_current = read_file(config_file, strip_end=False) + # generate new config file + daemons_config_new = render_to_string('frr/daemons.frr.tmpl', frr_config) # update configuration file if this is necessary - if daemons_config != daemons_config_current: - write_file(config_file, daemons_config) + if daemons_config_new != daemons_config_current: + syslog.warning('FRR daemons configuration file need to be changed') + write_file(config_file, daemons_config_new) frr_config['config_file_changed'] = True -- cgit v1.2.3 From 373132a899cd53eaebedd23bd44702d245ce8165 Mon Sep 17 00:00:00 2001 From: zsdc Date: Wed, 29 Dec 2021 17:57:38 +0200 Subject: FRR: T4020: Updated CLI options processing for FRR daemons - Reverted changes from `python/vyos/util.py`. This may lead to unnecessary FRR restart during each boot, depending on a default file content and template, but makes this changeset cleaner. - Fixed typos in node names (extra `>` characters). - Added SNMP module for `isisd` and `ldpd`, since they have it compiled now. --- data/templates/frr/daemons.frr.tmpl | 8 ++++++-- interface-definitions/system-frr.xml.in | 27 +++++++++++++++++++-------- python/vyos/util.py | 12 ++++-------- src/conf_mode/snmp.py | 8 ++++++-- src/conf_mode/system_frr.py | 2 +- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl index 089cdae3b..ab7b14d6b 100644 --- a/data/templates/frr/daemons.frr.tmpl +++ b/data/templates/frr/daemons.frr.tmpl @@ -34,9 +34,13 @@ ripd_options=" --daemon -A 127.0.0.1 {%- if snmp is defined and snmp.ripd is defined %} -M snmp{% endif -%} " ripngd_options=" --daemon -A ::1" -isisd_options=" --daemon -A 127.0.0.1" +isisd_options=" --daemon -A 127.0.0.1 +{%- if snmp is defined and snmp.isisd is defined %} -M snmp{% endif -%} +" pimd_options=" --daemon -A 127.0.0.1" -ldpd_options=" --daemon -A 127.0.0.1" +ldpd_options=" --daemon -A 127.0.0.1 +{%- if snmp is defined and snmp.ldpd is defined %} -M snmp{% endif -%} +" nhrpd_options=" --daemon -A 127.0.0.1" eigrpd_options=" --daemon -A 127.0.0.1" babeld_options=" --daemon -A 127.0.0.1" diff --git a/interface-definitions/system-frr.xml.in b/interface-definitions/system-frr.xml.in index e8b447f58..9fe23ed75 100644 --- a/interface-definitions/system-frr.xml.in +++ b/interface-definitions/system-frr.xml.in @@ -11,13 +11,13 @@ - >Enable BGP Monitoring Protocol support + Enable BGP Monitoring Protocol support - >Enable ICMP Router Discovery Protocol support + Enable ICMP Router Discovery Protocol support @@ -28,31 +28,43 @@ - >BGP + BGP + + + + + + IS-IS + + + + + + LDP - >OSPFv3 + OSPFv3 - >OSPFv2 + OSPFv2 - >RIP + RIP - >Zebra (IP routing manager) + Zebra (IP routing manager) @@ -63,4 +75,3 @@ - diff --git a/python/vyos/util.py b/python/vyos/util.py index ce5dc51f5..d8e83ab8d 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -182,20 +182,16 @@ def call(command, flag='', shell=None, input=None, timeout=None, env=None, return code -def read_file(fname, defaultonfailure=None, strip_end=True): +def read_file(fname, defaultonfailure=None): """ - read the content of a file, optionally stripping any end characters (space, newlines) + read the content of a file, stripping any end characters (space, newlines) should defaultonfailure be not None, it is returned on failure to read """ try: """ Read a file to string """ with open(fname, 'r') as f: - data = f.read() - - if strip_end: - return data.strip() - else: - return data + data = f.read().strip() + return data except Exception as e: if defaultonfailure is not None: return defaultonfailure diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 25dcdf7c6..6c6367045 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -583,9 +583,13 @@ def apply(snmp): # Enable AgentX in FRR # This should be done for each daemon individually because common command # works only if all the daemons started with SNMP support - frr_daemons_list = ['bgpd', 'ospf6d', 'ospfd', 'ripd', 'zebra'] + frr_daemons_list = [ + 'bgpd', 'ospf6d', 'ospfd', 'ripd', 'ripngd', 'isisd', 'ldpd', 'zebra' + ] for frr_daemon in frr_daemons_list: - call(f'vtysh -c "configure terminal" -d {frr_daemon} -c "agentx" >/dev/null') + call( + f'vtysh -c "configure terminal" -d {frr_daemon} -c "agentx" >/dev/null' + ) return None diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py index 0d0b37e00..1af0055f6 100755 --- a/src/conf_mode/system_frr.py +++ b/src/conf_mode/system_frr.py @@ -51,7 +51,7 @@ def verify(frr_config): def generate(frr_config): # read daemons config file - daemons_config_current = read_file(config_file, strip_end=False) + daemons_config_current = read_file(config_file) # generate new config file daemons_config_new = render_to_string('frr/daemons.frr.tmpl', frr_config) # update configuration file if this is necessary -- cgit v1.2.3