summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-05-11 20:27:41 +0200
committerGitHub <noreply@github.com>2026-05-11 20:27:41 +0200
commit86d13cb23df0e473c5e152fd050e136c228bfb1c (patch)
tree2150a4eea7e84ec476a70ef5e71d7845b6d72093
parentd529fd96c6a2033bdacd1fd7552014a4659ebe44 (diff)
parent23a7841901d5b7e46f00c628fc1a0946197b3c5b (diff)
downloadvyos-1x-86d13cb23df0e473c5e152fd050e136c228bfb1c.tar.gz
vyos-1x-86d13cb23df0e473c5e152fd050e136c228bfb1c.zip
Merge pull request #5171 from natali-rs1985/T8607
bgp: T8607: Add CLI support for BGP update-delay and establish-wait
-rw-r--r--data/templates/frr/bgpd.frr.j23
-rw-r--r--interface-definitions/include/bgp/protocol-common-config.xml.i35
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py18
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py14
4 files changed, 70 insertions, 0 deletions
diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2
index 51273341b..3ea5d1f1b 100644
--- a/data/templates/frr/bgpd.frr.j2
+++ b/data/templates/frr/bgpd.frr.j2
@@ -669,6 +669,9 @@ bgp route-reflector allow-outbound-policy
{% if parameters.tcp_keepalive.idle is vyos_defined and parameters.tcp_keepalive.interval is vyos_defined and parameters.tcp_keepalive.probes is vyos_defined %}
bgp tcp-keepalive {{ parameters.tcp_keepalive.idle }} {{ parameters.tcp_keepalive.interval }} {{ parameters.tcp_keepalive.probes }}
{% endif %}
+{% if parameters.update_delay.max_delay is vyos_defined %}
+ update-delay {{ parameters.update_delay.max_delay }}{{ ' ' ~ parameters.update_delay.establish_wait if parameters.update_delay.establish_wait is vyos_defined }}
+{% endif %}
{% if srv6.locator is vyos_defined %}
segment-routing srv6
locator {{ srv6.locator }}
diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i
index 6e1b3f8c5..f342402bb 100644
--- a/interface-definitions/include/bgp/protocol-common-config.xml.i
+++ b/interface-definitions/include/bgp/protocol-common-config.xml.i
@@ -1687,6 +1687,41 @@
</leafNode>
</children>
</node>
+ <node name="update-delay">
+ <properties>
+ <help>BGP update-delay read-only mode</help>
+ </properties>
+ <children>
+ <leafNode name="max-delay">
+ <properties>
+ <help>Maximum delay before exiting read-only mode</help>
+ <valueHelp>
+ <format>u32:0</format>
+ <description>Disable feature</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-3600</format>
+ <description>Delay in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-3600"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="establish-wait">
+ <properties>
+ <help>Time to wait for peers to reach Established state before determining expected peers</help>
+ <valueHelp>
+ <format>u32:1-3600</format>
+ <description>Wait time in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-3600"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
<tagNode name="peer-group">
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 0179356d2..c2a6f3dd1 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -329,6 +329,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
tcp_keepalive_idle = '66'
tcp_keepalive_interval = '77'
tcp_keepalive_probes = '22'
+ max_delay = '120'
+ establish_wait = '60'
self.cli_set(base_path + ['parameters', 'allow-martian-nexthop'])
self.cli_set(base_path + ['parameters', 'disable-ebgp-connected-route-check'])
@@ -376,6 +378,21 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'maximum-paths', 'ebgp', max_path_v6])
self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'maximum-paths', 'ibgp', max_path_v6ibgp])
+ # BGP update-delay
+ self.cli_set(
+ base_path + ['parameters', 'update-delay', 'establish-wait', '200']
+ )
+ # establish-wait should not be set without max-delay
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['parameters', 'update-delay', 'max-delay', max_delay])
+ # establish-wait should not be greater than max-delay
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(
+ base_path + ['parameters', 'update-delay', 'establish-wait', establish_wait]
+ )
+
# commit changes
self.cli_commit()
@@ -408,6 +425,7 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' bgp tcp-keepalive {tcp_keepalive_idle} {tcp_keepalive_interval} {tcp_keepalive_probes}', frrconfig)
self.assertNotIn(f'bgp ebgp-requires-policy', frrconfig)
self.assertIn(f' no bgp suppress-duplicates', frrconfig)
+ self.assertIn(f' update-delay {max_delay} {establish_wait}', frrconfig)
afiv4_config = self.getFRRconfig(f'router bgp {ASN}', stop_section='^exit',
start_subsection=' address-family ipv4 unicast',
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index 24e244bb9..53561a9a3 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -478,6 +478,20 @@ def verify(config_dict):
if not {'idle', 'interval', 'probes'} <= set(bgp['parameters']['tcp_keepalive']):
raise ConfigError('TCP keepalive incomplete - idle, keepalive and probes must be set')
+ # Validate BGP update-delay: 'establish-wait' requires 'max-delay' and must not exceed it
+ if dict_search('parameters.update_delay', bgp) != None:
+ update_delay = dict_search('parameters.update_delay.max_delay', bgp)
+ establish_wait = dict_search('parameters.update_delay.establish_wait', bgp)
+ if establish_wait is not None:
+ if update_delay is None:
+ raise ConfigError(
+ 'BGP update-delay establish-wait requires max-delay to be set!'
+ )
+ if int(establish_wait) > int(update_delay):
+ raise ConfigError(
+ 'BGP update-delay establish-wait cannot be greater than max-delay!'
+ )
+
# Address Family specific validation
if 'address_family' in bgp:
for afi, afi_config in bgp['address_family'].items():