Skip to content

Commit 5c0d8a4

Browse files
committed
frr: T7896: Configure frr profile with 'system frr profile' command
1 parent d316d80 commit 5c0d8a4

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

data/templates/frr/daemons.frr.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ valgrind_enable=no
105105

106106
#watchfrr_options=""
107107

108-
frr_profile="traditional"
108+
frr_profile="{{ profile }}"
109109

110110
MAX_FDS={{ descriptors }}
111111

interface-definitions/system_frr.xml.in

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@
3535
<valueless/>
3636
</properties>
3737
</leafNode>
38+
<leafNode name="profile">
39+
<properties>
40+
<help>Select configuration profile to adapt different defaults</help>
41+
<completionHelp>
42+
<list>traditional datacenter</list>
43+
</completionHelp>
44+
<valueHelp>
45+
<format>traditional</format>
46+
<description>Adhere mostly to IETF standards or common practices in wide-area internet routing</description>
47+
</valueHelp>
48+
<valueHelp>
49+
<format>datacenter</format>
50+
<description>Single administrative domain using aggressive timers</description>
51+
</valueHelp>
52+
<constraint>
53+
<regex>(datacenter|traditional)</regex>
54+
</constraint>
55+
</properties>
56+
<defaultValue>traditional</defaultValue>
57+
</leafNode>
3858
<node name="snmp">
3959
<properties>
4060
<help>Enable SNMP integration for next daemons</help>

python/vyos/frrender.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,15 @@ def dict_helper_nhrp_defaults(nhrp):
233233
ip_dict['afi'] = ip_version
234234
dict.update({ip_version : ip_dict})
235235

236+
# Get FRR profile
237+
frr_system_cli_path = ['system', 'frr']
238+
dict['system_frr'] = conf.get_config_dict(
239+
frr_system_cli_path,
240+
key_mangling=('-', '_'),
241+
get_first_key=True,
242+
with_recursive_defaults=True,
243+
)
244+
236245
# Enable SNMP agentx support
237246
# SNMP AgentX support cannot be disabled once enabled
238247
if conf.exists(['service', 'snmp']):
@@ -733,6 +742,11 @@ def inline_helper(config_dict) -> str:
733742
# we can not reload an empty file, thus we always embed the marker
734743
output = '!\n'
735744

745+
# FRR profile configuration
746+
tmp = dict_search('system_frr.profile', config_dict)
747+
if tmp:
748+
output += f'frr defaults {tmp}\n'
749+
736750
# Enable FRR logging
737751
output += 'log facility daemon\n'
738752
output += 'log timestamp precision 3\n'

smoketest/scripts/cli/test_system_frr.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,28 @@ def test_frr_bmp_and_snmp(self):
150150
self.assertTrue(bmp_enabled)
151151
self.assertTrue(snmp_enabled)
152152

153+
def test_frr_profile_add_remove(self):
154+
# test add profile
155+
frr_profiles = ['traditional', 'datacenter']
156+
for profile in frr_profiles:
157+
# set the profile
158+
self.cli_set(base_path + ['profile', profile])
159+
self.cli_commit()
160+
# read the config file and check content
161+
self.assertIn(f'frr_profile="{profile}"', read_file(config_file))
162+
# read the frr.conf file and check content
163+
frrconfig = self.getFRRconfig()
164+
self.assertIn(f'frr defaults {profile}', frrconfig)
165+
166+
# test remove profile
167+
self.cli_delete(base_path + ['profile'])
168+
self.cli_commit()
169+
# read the config file and check content
170+
self.assertIn(f'frr_profile="{frr_profiles[0]}"', read_file(config_file))
171+
# read the frr.conf file and check content
172+
frrconfig = self.getFRRconfig()
173+
self.assertIn(f'frr defaults {frr_profiles[0]}', frrconfig)
174+
153175
def test_frr_file_descriptors(self):
154176
file_descriptors = '4096'
155177

src/conf_mode/system_frr.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,21 @@
1919
from vyos import ConfigError
2020
from vyos.base import Warning
2121
from vyos.config import Config
22+
from vyos.frrender import FRRender
23+
from vyos.frrender import get_frrender_dict
2224
from vyos.logger import syslog
2325
from vyos.template import render_to_string
2426
from vyos.utils.boot import boot_configuration_complete
2527
from vyos.utils.file import read_file
2628
from vyos.utils.file import write_file
2729
from vyos.utils.process import call
30+
from vyos.utils.process import is_systemd_service_running
2831

2932
from vyos import airbag
3033
airbag.enable()
3134

3235
# path to daemons config and config status files
33-
config_file = '/etc/frr/daemons'
36+
daemon_config_file = '/etc/frr/daemons'
3437

3538
def get_config(config=None):
3639
if config:
@@ -42,6 +45,8 @@ def get_config(config=None):
4245
frr_config = conf.get_config_dict(base, key_mangling=('-', '_'),
4346
get_first_key=True,
4447
with_recursive_defaults=True)
48+
# get FRR configuration
49+
frr_config['frrender'] = get_frrender_dict(conf)
4550

4651
return frr_config
4752

@@ -51,15 +56,27 @@ def verify(frr_config):
5156

5257
def generate(frr_config):
5358
# read daemons config file
54-
daemons_config_current = read_file(config_file)
59+
daemons_config_current = read_file(daemon_config_file)
5560
# generate new config file
5661
daemons_config_new = render_to_string('frr/daemons.frr.tmpl', frr_config)
5762
# update configuration file if this is necessary
5863
if daemons_config_new != daemons_config_current:
5964
syslog.warning('FRR daemons configuration file need to be changed')
60-
write_file(config_file, daemons_config_new)
65+
write_file(daemon_config_file, daemons_config_new)
6166
frr_config['config_file_changed'] = True
6267

68+
# profile could be automatically generated by frr in frr.conf
69+
# and needs to be updated as it is taking precedence
70+
if 'frrender' in frr_config and 'profile' in frr_config['frrender']:
71+
frr_config['frrender']['profile'] = frr_config['profile']
72+
if frr_config['frrender'] and not is_systemd_service_running(
73+
'vyos-configd.service'
74+
):
75+
FRRender().generate(frr_config['frrender'])
76+
# apply here to keep consistency with the generated daemons
77+
# config file
78+
FRRender().apply()
79+
6380
def apply(frr_config):
6481
# display warning to user
6582
if boot_configuration_complete() and frr_config.get('config_file_changed'):

0 commit comments

Comments
 (0)