diff options
| author | Alex Kudentsov <43482574+alexk37@users.noreply.github.com> | 2026-10-06 13:25:22 +0700 |
|---|---|---|
| committer | Alex Kudentsov <43482574+alexk37@users.noreply.github.com> | 2026-10-07 00:46:24 +0700 |
| commit | df22720c7af9fab801f2f7b3b69afd05e6e511e9 (patch) | |
| tree | e1c6fe82f334b2ca893cfe8555bdcbd68794c244 /smoketest/scripts/cli | |
| parent | 87e0a46281746f92a0dde4c7d71c86aa00ec90ea (diff) | |
| download | vyos-1x-df22720c7af9fab801f2f7b3b69afd05e6e511e9.tar.gz vyos-1x-df22720c7af9fab801f2f7b3b69afd05e6e511e9.zip | |
bgp: T9404: do not render "bgp default local-preference" when the value is 100
FRR does not print "bgp default local-preference 100" in show
running-config because 100 is its default, so frr-reload never finds the
line in the running config and sends it again on every reload. The
command handler calls bgp_clear_star_soft_in() whether or not the value
changed, so every reload ran "clear bgp * soft in" (once in pass 0 and
twice in pass 1), a full inbound re-evaluation of every peer.
Add the default (100) to the XML definition of parameters default
local-pref. Templates cannot query the XML definition while rendering,
so frrender takes the value from the config defaults of "parameters
default" (conf.get_config_defaults) and adds it to the BGP dict as the
key xml_default_local_pref, for the global instance and for every VRF
instance. bgpd.frr.j2 renders the line only when the configured value
differs from xml_default_local_pref, so the value 100 is not hardcoded
in the template. A real value change (100 to 200, or 200 to 100) is
still sent: frr-reload sees the difference between the rendered file and
the running config.
Diffstat (limited to 'smoketest/scripts/cli')
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_bgp.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 2ab8c8844..3e417a0f5 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -2126,5 +2126,70 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): 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()) |
