Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion data/templates/frr/bgpd.frr.j2
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,8 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {{ 'as-nota
{# Doesn't work in current FRR configuration; vtysh (bgp dampening 16 751 2001 61) #}
bgp dampening {{ parameters.dampening.half_life }} {{ parameters.dampening.re_use if parameters.dampening.re_use is vyos_defined }} {{ parameters.dampening.start_suppress_time if parameters.dampening.start_suppress_time is vyos_defined }} {{ parameters.dampening.max_suppress_time if parameters.dampening.max_suppress_time is vyos_defined }}
{% endif %}
{% if parameters.default.local_pref is vyos_defined %}
{# xml_default_local_pref is the XML default of parameters default local-pref, added to the dict by frrender #}
{% if parameters.default.local_pref is vyos_defined and parameters.default.local_pref != xml_default_local_pref %}
bgp default local-preference {{ parameters.default.local_pref }}
{% endif %}
{% if parameters.deterministic_med is vyos_defined %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
<validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
<defaultValue>100</defaultValue>
</leafNode>
</children>
</node>
Expand Down
8 changes: 8 additions & 0 deletions python/vyos/frrender.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@ def dict_helper_nhrp_defaults(nhrp):
no_tag_node_value_mangle=True,
with_recursive_defaults=True)
bgp['dependent_vrfs'] = {}
# The XML default of "parameters default local-pref" is added to the
# dict, the template cannot query it while rendering. Only the node
# "parameters default" is asked for, not the whole BGP tree.
tmp = conf.get_config_defaults(bgp_cli_path + ['parameters', 'default'],
key_mangling=('-', '_'), get_first_key=True)
bgp['xml_default_local_pref'] = tmp.get('local_pref')
dict.update({'bgp' : bgp})
elif conf.exists_effective(bgp_cli_path):
dict.update({'bgp' : {'deleted' : '', 'dependent_vrfs' : {}}})
Expand Down Expand Up @@ -522,6 +528,8 @@ def dict_helper_nhrp_defaults(nhrp):
# merge in remaining default values
vrf_config['protocols']['bgp'] = config_dict_merge(default_values,
vrf_config['protocols']['bgp'])
vrf_config['protocols']['bgp']['xml_default_local_pref'] = dict_search(
'parameters.default.local_pref', default_values)

# Add this BGP VRF instance as dependency into the default VRF
if 'bgp' in dict:
Expand Down
65 changes: 65 additions & 0 deletions smoketest/scripts/cli/test_protocols_bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2126,5 +2126,70 @@ def test_bgp_106_interface_l3vpn_multi_domain_switching(self):
self.assertIn(f'interface {interface}', frrconfig)
self.assertIn(f' mpls bgp l3vpn-multi-domain-switching', frrconfig)

def test_bgp_107_default_local_pref_default_value(self):
# T9404: FRR does not print "bgp default local-preference 100" in its
# running config because 100 is the default. If we render the line
# anyway, frr-reload finds it missing on every reload and sends it
# again, and FRR runs "clear bgp * soft in" for each of those. So the
# default value must not be rendered.
#
# This reads the generated FRR config file instead of getFRRconfig():
# FRR never prints the line for 100, so vtysh cannot tell if we render it.
frr_conf = '/run/frr/config/vyos.frr.conf'
local_pref = ' bgp default local-preference'

# the XML default (100) is always in the config dict, but it is the
# default, so nothing is rendered when local-pref is not configured
self.cli_commit()
frrconfig = read_file(frr_conf)
self.assertIn(f'router bgp {ASN}', frrconfig)
self.assertNotIn(local_pref, frrconfig)

self.cli_set(base_path + ['parameters', 'default', 'local-pref', '100'])
self.cli_commit()

frrconfig = read_file(frr_conf)
self.assertIn(f'router bgp {ASN}', frrconfig)
self.assertNotIn(local_pref, frrconfig)

# a value other than the default is still rendered and applied
self.cli_set(base_path + ['parameters', 'default', 'local-pref', '200'])
self.cli_commit()

self.assertIn(f'{local_pref} 200', read_file(frr_conf))
frrconfig = self.getFRRconfig(f'router bgp {ASN}', stop_section='^exit')
self.assertIn(f'{local_pref} 200', frrconfig)

# back to the default value, FRR must have the default again
self.cli_set(base_path + ['parameters', 'default', 'local-pref', '100'])
self.cli_commit()

self.assertNotIn(local_pref, read_file(frr_conf))
frrconfig = self.getFRRconfig(f'router bgp {ASN}', stop_section='^exit')
self.assertNotIn(local_pref, frrconfig)

# the VRF instance has the same default: 100 is not rendered in the
# VRF block, 200 is rendered in the VRF block only
vrf_header = f'router bgp {ASN} vrf {import_vrf}'
vrf_local_pref = import_vrf_base + [import_vrf, 'protocols', 'bgp', 'parameters', 'default', 'local-pref']
self.create_bgp_instances_for_import_test()
self.cli_set(vrf_local_pref + ['100'])
self.cli_commit()

frrconfig = read_file(frr_conf)
self.assertIn(vrf_header, frrconfig)
self.assertNotIn(local_pref, frrconfig)

self.cli_set(vrf_local_pref + ['200'])
self.cli_commit()

# the global block comes first in the file, the VRF block after it
global_block, _, vrf_block = read_file(frr_conf).partition(vrf_header)
self.assertIn(f'router bgp {ASN}', global_block)
self.assertNotIn(local_pref, global_block)
self.assertIn(f'{local_pref} 200', vrf_block)
frrconfig = self.getFRRconfig(vrf_header, stop_section='^exit')
self.assertIn(f'{local_pref} 200', frrconfig)

if __name__ == '__main__':
unittest.main(verbosity=2, failfast=VyOSUnitTestSHIM.TestCase.debug_on())
Loading