diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 593b4b415..c19bfcfe2 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -1,1320 +1,1324 @@
 # Copyright (C) 2019-2024 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 <http://www.gnu.org/licenses/>.
 
 import re
 
 from netifaces import AF_INET
 from netifaces import AF_INET6
 from netifaces import ifaddresses
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.defaults import directories
 from vyos.ifconfig import Interface
 from vyos.ifconfig import Section
 from vyos.pki import CERT_BEGIN
 from vyos.utils.file import read_file
 from vyos.utils.dict import dict_search
 from vyos.utils.process import cmd
 from vyos.utils.process import process_named_running
 from vyos.utils.network import get_interface_config
 from vyos.utils.network import get_interface_vrf
 from vyos.utils.network import get_vrf_tableid
 from vyos.utils.network import interface_exists
 from vyos.utils.network import is_intf_addr_assigned
 from vyos.utils.network import is_ipv6_link_local
 from vyos.utils.network import get_nft_vrf_zone_mapping
 from vyos.xml_ref import cli_defined
 
 dhclient_base_dir = directories['isc_dhclient_dir']
 dhclient_process_name = 'dhclient'
 dhcp6c_base_dir = directories['dhcp6_client_dir']
 dhcp6c_process_name = 'dhcp6c'
 
 server_ca_root_cert_data = """
 MIIBcTCCARagAwIBAgIUDcAf1oIQV+6WRaW7NPcSnECQ/lUwCgYIKoZIzj0EAwIw
 HjEcMBoGA1UEAwwTVnlPUyBzZXJ2ZXIgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjBa
 Fw0zMjAyMTUxOTQxMjBaMB4xHDAaBgNVBAMME1Z5T1Mgc2VydmVyIHJvb3QgQ0Ew
 WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ0y24GzKQf4aM2Ir12tI9yITOIzAUj
 ZXyJeCmYI6uAnyAMqc4Q4NKyfq3nBi4XP87cs1jlC1P2BZ8MsjL5MdGWozIwMDAP
 BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRwC/YaieMEnjhYa7K3Flw/o0SFuzAK
 BggqhkjOPQQDAgNJADBGAiEAh3qEj8vScsjAdBy5shXzXDVVOKWCPTdGrPKnu8UW
 a2cCIQDlDgkzWmn5ujc5ATKz1fj+Se/aeqwh4QyoWCVTFLIxhQ==
 """
 
 server_ca_intermediate_cert_data = """
 MIIBmTCCAT+gAwIBAgIUNzrtHzLmi3QpPK57tUgCnJZhXXQwCgYIKoZIzj0EAwIw
 HjEcMBoGA1UEAwwTVnlPUyBzZXJ2ZXIgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjFa
 Fw0zMjAyMTUxOTQxMjFaMCYxJDAiBgNVBAMMG1Z5T1Mgc2VydmVyIGludGVybWVk
 aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEl2nJ1CzoqPV6hWII2m
 eGN/uieU6wDMECTk/LgG8CCCSYb488dibUiFN/1UFsmoLIdIhkx/6MUCYh62m8U2
 WNujUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMV3YwH88I5gFsFUibbQ
 kMR0ECPsMB8GA1UdIwQYMBaAFHAL9hqJ4wSeOFhrsrcWXD+jRIW7MAoGCCqGSM49
 BAMCA0gAMEUCIQC/ahujD9dp5pMMCd3SZddqGC9cXtOwMN0JR3e5CxP13AIgIMQm
 jMYrinFoInxmX64HfshYqnUY8608nK9D2BNPOHo=
 """
 
 client_ca_root_cert_data = """
 MIIBcDCCARagAwIBAgIUZmoW2xVdwkZSvglnkCq0AHKa6zIwCgYIKoZIzj0EAwIw
 HjEcMBoGA1UEAwwTVnlPUyBjbGllbnQgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjFa
 Fw0zMjAyMTUxOTQxMjFaMB4xHDAaBgNVBAMME1Z5T1MgY2xpZW50IHJvb3QgQ0Ew
 WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATUpKXzQk2NOVKDN4VULk2yw4mOKPvn
 mg947+VY7lbpfOfAUD0QRg95qZWCw899eKnXp/U4TkAVrmEKhUb6OJTFozIwMDAP
 BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTXu6xGWUl25X3sBtrhm3BJSICIATAK
 BggqhkjOPQQDAgNIADBFAiEAnTzEwuTI9bz2Oae3LZbjP6f/f50KFJtjLZFDbQz7
 DpYCIDNRHV8zBUibC+zg5PqMpQBKd/oPfNU76nEv6xkp/ijO
 """
 
 client_ca_intermediate_cert_data = """
 MIIBmDCCAT+gAwIBAgIUJEMdotgqA7wU4XXJvEzDulUAGqgwCgYIKoZIzj0EAwIw
 HjEcMBoGA1UEAwwTVnlPUyBjbGllbnQgcm9vdCBDQTAeFw0yMjAyMTcxOTQxMjJa
 Fw0zMjAyMTUxOTQxMjJaMCYxJDAiBgNVBAMMG1Z5T1MgY2xpZW50IGludGVybWVk
 aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGyIVIi217s9j3O+WQ2b
 6R65/Z0ZjQpELxPjBRc0CA0GFCo+pI5EvwI+jNFArvTAJ5+ZdEWUJ1DQhBKDDQdI
 avCjUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOUS8oNJjChB1Rb9Blcl
 ETvziHJ9MB8GA1UdIwQYMBaAFNe7rEZZSXblfewG2uGbcElIgIgBMAoGCCqGSM49
 BAMCA0cAMEQCIArhaxWgRsAUbEeNHD/ULtstLHxw/P97qPUSROLQld53AiBjgiiz
 9pDfISmpekZYz6bIDWRIR0cXUToZEMFNzNMrQg==
 """
 
 client_cert_data = """
 MIIBmTCCAUCgAwIBAgIUV5T77XdE/tV82Tk4Vzhp5BIFFm0wCgYIKoZIzj0EAwIw
 JjEkMCIGA1UEAwwbVnlPUyBjbGllbnQgaW50ZXJtZWRpYXRlIENBMB4XDTIyMDIx
 NzE5NDEyMloXDTMyMDIxNTE5NDEyMlowIjEgMB4GA1UEAwwXVnlPUyBjbGllbnQg
 Y2VydGlmaWNhdGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARuyynqfc/qJj5e
 KJ03oOH8X4Z8spDeAPO9WYckMM0ldPj+9kU607szFzPwjaPWzPdgyIWz3hcN8yAh
 CIhytmJao1AwTjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTIFKrxZ+PqOhYSUqnl
 TGCUmM7wTjAfBgNVHSMEGDAWgBTlEvKDSYwoQdUW/QZXJRE784hyfTAKBggqhkjO
 PQQDAgNHADBEAiAvO8/jvz05xqmP3OXD53XhfxDLMIxzN4KPoCkFqvjlhQIgIHq2
 /geVx3rAOtSps56q/jiDouN/aw01TdpmGKVAa9U=
 """
 
 client_key_data = """
 MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgxaxAQsJwjoOCByQE
 +qSYKtKtJzbdbOnTsKNSrfgkFH6hRANCAARuyynqfc/qJj5eKJ03oOH8X4Z8spDe
 APO9WYckMM0ldPj+9kU607szFzPwjaPWzPdgyIWz3hcN8yAhCIhytmJa
 """
 
 def get_wpa_supplicant_value(interface, key):
     tmp = read_file(f'/run/wpa_supplicant/{interface}.conf')
     tmp = re.findall(r'\n?{}=(.*)'.format(key), tmp)
     return tmp[0]
 
 def get_certificate_count(interface, cert_type):
     tmp = read_file(f'/run/wpa_supplicant/{interface}_{cert_type}.pem')
     return tmp.count(CERT_BEGIN)
 
 def is_mirrored_to(interface, mirror_if, qdisc):
     """
     Ask TC if we are mirroring traffic to a discrete interface.
 
     interface: source interface
     mirror_if: destination where we mirror our data to
     qdisc: must be ffff or 1 for ingress/egress
     """
     if qdisc not in ['ffff', '1']:
         raise ValueError()
 
     ret_val = False
     tmp = cmd(f'tc -s -p filter ls dev {interface} parent {qdisc}: | grep mirred')
     tmp = tmp.lower()
     if mirror_if in tmp:
         ret_val = True
     return ret_val
 class BasicInterfaceTest:
     class TestCase(VyOSUnitTestSHIM.TestCase):
         _test_dhcp = False
         _test_eapol = False
         _test_ip = False
         _test_mtu = False
         _test_vlan = False
         _test_qinq = False
         _test_ipv6 = False
         _test_ipv6_pd = False
         _test_ipv6_dhcpc6 = False
         _test_mirror = False
         _test_vrf = False
         _base_path = []
 
         _options = {}
         _interfaces = []
         _qinq_range = ['10', '20', '30']
         _vlan_range = ['100', '200', '300', '2000']
         _test_addr = ['192.0.2.1/26', '192.0.2.255/31', '192.0.2.64/32',
                       '2001:db8:1::ffff/64', '2001:db8:101::1/112']
 
         _mirror_interfaces = []
         # choose IPv6 minimum MTU value for tests - this must always work
         _mtu = '1280'
 
         @classmethod
         def setUpClass(cls):
             super(BasicInterfaceTest.TestCase, cls).setUpClass()
 
             # XXX the case of test_vif_8021q_mtu_limits, below, shows that
             # we should extend cli_defined to support more complex queries
             cls._test_vlan = cli_defined(cls._base_path, 'vif')
             cls._test_qinq = cli_defined(cls._base_path, 'vif-s')
             cls._test_dhcp = cli_defined(cls._base_path, 'dhcp-options')
             cls._test_eapol = cli_defined(cls._base_path, 'eapol')
             cls._test_ip = cli_defined(cls._base_path, 'ip')
             cls._test_ipv6 = cli_defined(cls._base_path, 'ipv6')
             cls._test_ipv6_dhcpc6 = cli_defined(cls._base_path, 'dhcpv6-options')
             cls._test_ipv6_pd = cli_defined(cls._base_path + ['dhcpv6-options'], 'pd')
             cls._test_mtu = cli_defined(cls._base_path, 'mtu')
             cls._test_vrf = cli_defined(cls._base_path, 'vrf')
 
             # Setup mirror interfaces for SPAN (Switch Port Analyzer)
             for span in cls._mirror_interfaces:
                 section = Section.section(span)
                 cls.cli_set(cls, ['interfaces', section, span])
 
+            # Enable CSTORE guard time required by FRR related tests
+            cls._commit_guard_time = CSTORE_GUARD_TIME
+
         @classmethod
         def tearDownClass(cls):
             # Tear down mirror interfaces for SPAN (Switch Port Analyzer)
             for span in cls._mirror_interfaces:
                 section = Section.section(span)
                 cls.cli_delete(cls, ['interfaces', section, span])
 
             super(BasicInterfaceTest.TestCase, cls).tearDownClass()
 
         def tearDown(self):
             self.cli_delete(self._base_path)
             self.cli_commit()
 
             # Verify that no previously interface remained on the system
             ct_map = get_nft_vrf_zone_mapping()
             for intf in self._interfaces:
                 self.assertFalse(interface_exists(intf))
                 for map_entry in ct_map:
                      self.assertNotEqual(intf, map_entry['interface'])
 
             # No daemon started during tests should remain running
             for daemon in ['dhcp6c', 'dhclient']:
                 # if _interface list is populated do a more fine grained search
                 # by also checking the cmd arguments passed to the daemon
                 if self._interfaces:
                     for tmp in self._interfaces:
                         self.assertFalse(process_named_running(daemon, tmp))
                 else:
                     self.assertFalse(process_named_running(daemon))
 
         def test_dhcp_disable_interface(self):
             if not self._test_dhcp:
                 self.skipTest('not supported')
 
             # When interface is configured as admin down, it must be admin down
             # even when dhcpc starts on the given interface
             for interface in self._interfaces:
                 self.cli_set(self._base_path + [interface, 'disable'])
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
 
                 # Also enable DHCP (ISC DHCP always places interface in admin up
                 # state so we check that we do not start DHCP client.
                 # https://vyos.dev/T2767
                 self.cli_set(self._base_path + [interface, 'address', 'dhcp'])
 
             self.cli_commit()
 
             # Validate interface state
             for interface in self._interfaces:
                 flags = read_file(f'/sys/class/net/{interface}/flags')
                 self.assertEqual(int(flags, 16) & 1, 0)
 
         def test_dhcp_client_options(self):
             if not self._test_dhcp or not self._test_vrf:
                 self.skipTest('not supported')
 
             client_id = 'VyOS-router'
             distance = '100'
             hostname = 'vyos'
             vendor_class_id = 'vyos-vendor'
             user_class = 'vyos'
 
             for interface in self._interfaces:
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
 
                 self.cli_set(self._base_path + [interface, 'address', 'dhcp'])
                 self.cli_set(self._base_path + [interface, 'dhcp-options', 'client-id', client_id])
                 self.cli_set(self._base_path + [interface, 'dhcp-options', 'default-route-distance', distance])
                 self.cli_set(self._base_path + [interface, 'dhcp-options', 'host-name', hostname])
                 self.cli_set(self._base_path + [interface, 'dhcp-options', 'vendor-class-id', vendor_class_id])
                 self.cli_set(self._base_path + [interface, 'dhcp-options', 'user-class', user_class])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 # Check if dhclient process runs
                 dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface, timeout=10)
                 self.assertTrue(dhclient_pid)
 
                 dhclient_config = read_file(f'{dhclient_base_dir}/dhclient_{interface}.conf')
                 self.assertIn(f'request subnet-mask, broadcast-address, routers, domain-name-servers', dhclient_config)
                 self.assertIn(f'require subnet-mask;', dhclient_config)
                 self.assertIn(f'send host-name "{hostname}";', dhclient_config)
                 self.assertIn(f'send dhcp-client-identifier "{client_id}";', dhclient_config)
                 self.assertIn(f'send vendor-class-identifier "{vendor_class_id}";', dhclient_config)
                 self.assertIn(f'send user-class "{user_class}";', dhclient_config)
 
                 # and the commandline has the appropriate options
                 cmdline = read_file(f'/proc/{dhclient_pid}/cmdline')
                 self.assertIn(f'-e\x00IF_METRIC={distance}', cmdline)
 
         def test_dhcp_vrf(self):
             if not self._test_dhcp or not self._test_vrf:
                 self.skipTest('not supported')
 
             vrf_name = 'purple4'
             self.cli_set(['vrf', 'name', vrf_name, 'table', '65000'])
 
             for interface in self._interfaces:
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
 
                 self.cli_set(self._base_path + [interface, 'address', 'dhcp'])
                 self.cli_set(self._base_path + [interface, 'vrf', vrf_name])
 
             self.cli_commit()
 
             # Validate interface state
             for interface in self._interfaces:
                 tmp = get_interface_vrf(interface)
                 self.assertEqual(tmp, vrf_name)
 
                 # Check if dhclient process runs
                 dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface, timeout=10)
                 self.assertTrue(dhclient_pid)
                 # .. inside the appropriate VRF instance
                 vrf_pids = cmd(f'ip vrf pids {vrf_name}')
                 self.assertIn(str(dhclient_pid), vrf_pids)
                 # and the commandline has the appropriate options
                 cmdline = read_file(f'/proc/{dhclient_pid}/cmdline')
                 self.assertIn('-e\x00IF_METRIC=210', cmdline) # 210 is the default value
 
             self.cli_delete(['vrf', 'name', vrf_name])
 
         def test_dhcpv6_vrf(self):
             if not self._test_ipv6_dhcpc6 or not self._test_vrf:
                 self.skipTest('not supported')
 
             vrf_name = 'purple6'
             self.cli_set(['vrf', 'name', vrf_name, 'table', '65001'])
 
             # When interface is configured as admin down, it must be admin down
             # even when dhcpc starts on the given interface
             for interface in self._interfaces:
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
 
                 self.cli_set(self._base_path + [interface, 'address', 'dhcpv6'])
                 self.cli_set(self._base_path + [interface, 'vrf', vrf_name])
 
             self.cli_commit()
 
             # Validate interface state
             for interface in self._interfaces:
                 tmp = get_interface_vrf(interface)
                 self.assertEqual(tmp, vrf_name)
 
                 # Check if dhclient process runs
                 tmp = process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10)
                 self.assertTrue(tmp)
                 # .. inside the appropriate VRF instance
                 vrf_pids = cmd(f'ip vrf pids {vrf_name}')
                 self.assertIn(str(tmp), vrf_pids)
 
             self.cli_delete(['vrf', 'name', vrf_name])
 
         def test_move_interface_between_vrf_instances(self):
             if not self._test_vrf:
                 self.skipTest('not supported')
 
             vrf1_name = 'smoketest_mgmt1'
             vrf1_table = '5424'
             vrf2_name = 'smoketest_mgmt2'
             vrf2_table = '7412'
 
             self.cli_set(['vrf', 'name', vrf1_name, 'table', vrf1_table])
             self.cli_set(['vrf', 'name', vrf2_name, 'table', vrf2_table])
 
             # move interface into first VRF
             for interface in self._interfaces:
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
                 self.cli_set(self._base_path + [interface, 'vrf', vrf1_name])
 
             self.cli_commit()
 
             # check that interface belongs to proper VRF
             for interface in self._interfaces:
                 tmp = get_interface_vrf(interface)
                 self.assertEqual(tmp, vrf1_name)
 
                 tmp = get_interface_config(vrf1_name)
                 self.assertEqual(int(vrf1_table), get_vrf_tableid(interface))
 
             # move interface into second VRF
             for interface in self._interfaces:
                 self.cli_set(self._base_path + [interface, 'vrf', vrf2_name])
 
             self.cli_commit()
 
             # check that interface belongs to proper VRF
             for interface in self._interfaces:
                 tmp = get_interface_vrf(interface)
                 self.assertEqual(tmp, vrf2_name)
 
                 tmp = get_interface_config(vrf2_name)
                 self.assertEqual(int(vrf2_table), get_vrf_tableid(interface))
 
             self.cli_delete(['vrf', 'name', vrf1_name])
             self.cli_delete(['vrf', 'name', vrf2_name])
 
         def test_add_to_invalid_vrf(self):
             if not self._test_vrf:
                 self.skipTest('not supported')
 
             # move interface into first VRF
             for interface in self._interfaces:
                 for option in self._options.get(interface, []):
                     self.cli_set(self._base_path + [interface] + option.split())
                 self.cli_set(self._base_path + [interface, 'vrf', 'invalid'])
 
             # check validate() - can not use a non-existing VRF
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
             for interface in self._interfaces:
                 self.cli_delete(self._base_path + [interface, 'vrf', 'invalid'])
                 self.cli_set(self._base_path + [interface, 'description', 'test_add_to_invalid_vrf'])
 
         def test_span_mirror(self):
             if not self._mirror_interfaces:
                 self.skipTest('not supported')
 
             # Check the two-way mirror rules of ingress and egress
             for mirror in self._mirror_interfaces:
                 for interface in self._interfaces:
                     self.cli_set(self._base_path + [interface, 'mirror', 'ingress', mirror])
                     self.cli_set(self._base_path + [interface, 'mirror', 'egress',  mirror])
 
             self.cli_commit()
 
             # Verify config
             for mirror in self._mirror_interfaces:
                 for interface in self._interfaces:
                     self.assertTrue(is_mirrored_to(interface, mirror, 'ffff'))
                     self.assertTrue(is_mirrored_to(interface, mirror, '1'))
 
         def test_interface_disable(self):
             # Check if description can be added to interface and
             # can be read back
             for intf in self._interfaces:
                 self.cli_set(self._base_path + [intf, 'disable'])
                 for option in self._options.get(intf, []):
                     self.cli_set(self._base_path + [intf] + option.split())
 
             self.cli_commit()
 
             # Validate interface description
             for intf in self._interfaces:
                 self.assertEqual(Interface(intf).get_admin_state(), 'down')
 
         def test_interface_description(self):
             # Check if description can be added to interface and
             # can be read back
             for intf in self._interfaces:
                 test_string=f'Description-Test-{intf}'
                 self.cli_set(self._base_path + [intf, 'description', test_string])
                 for option in self._options.get(intf, []):
                     self.cli_set(self._base_path + [intf] + option.split())
 
             self.cli_commit()
 
             # Validate interface description
             for intf in self._interfaces:
                 test_string=f'Description-Test-{intf}'
                 tmp = read_file(f'/sys/class/net/{intf}/ifalias')
                 self.assertEqual(tmp, test_string)
                 self.assertEqual(Interface(intf).get_alias(), test_string)
                 self.cli_delete(self._base_path + [intf, 'description'])
 
             self.cli_commit()
 
             # Validate remove interface description "empty"
             for intf in self._interfaces:
                 tmp = read_file(f'/sys/class/net/{intf}/ifalias')
                 self.assertEqual(tmp, str())
                 self.assertEqual(Interface(intf).get_alias(), str())
 
             # Test maximum interface description lengt (255 characters)
             test_string='abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789___'
             for intf in self._interfaces:
 
                 self.cli_set(self._base_path + [intf, 'description', test_string])
                 for option in self._options.get(intf, []):
                     self.cli_set(self._base_path + [intf] + option.split())
 
             self.cli_commit()
 
             # Validate interface description
             for intf in self._interfaces:
                 tmp = read_file(f'/sys/class/net/{intf}/ifalias')
                 self.assertEqual(tmp, test_string)
                 self.assertEqual(Interface(intf).get_alias(), test_string)
 
         def test_add_single_ip_address(self):
             addr = '192.0.2.0/31'
             for intf in self._interfaces:
                 self.cli_set(self._base_path + [intf, 'address', addr])
                 for option in self._options.get(intf, []):
                     self.cli_set(self._base_path + [intf] + option.split())
 
             self.cli_commit()
 
             for intf in self._interfaces:
                 self.assertTrue(is_intf_addr_assigned(intf, addr))
                 self.assertEqual(Interface(intf).get_admin_state(), 'up')
 
         def test_add_multiple_ip_addresses(self):
             # Add address
             for intf in self._interfaces:
                 for option in self._options.get(intf, []):
                     self.cli_set(self._base_path + [intf] + option.split())
                 for addr in self._test_addr:
                     self.cli_set(self._base_path + [intf, 'address', addr])
 
             self.cli_commit()
 
             # Validate address
             for intf in self._interfaces:
                 for af in AF_INET, AF_INET6:
                     for addr in ifaddresses(intf)[af]:
                         # checking link local addresses makes no sense
                         if is_ipv6_link_local(addr['addr']):
                             continue
 
                         self.assertTrue(is_intf_addr_assigned(intf, addr['addr']))
 
         def test_ipv6_link_local_address(self):
             # Common function for IPv6 link-local address assignemnts
             if not self._test_ipv6:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 # just set the interface base without any option - some interfaces
                 # (VTI) do not require any option to be brought up
                 self.cli_set(base)
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
             # after commit we must have an IPv6 link-local address
             self.cli_commit()
 
             for interface in self._interfaces:
                 self.assertIn(AF_INET6, ifaddresses(interface))
                 for addr in ifaddresses(interface)[AF_INET6]:
                     self.assertTrue(is_ipv6_link_local(addr['addr']))
 
             # disable IPv6 link-local address assignment
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 self.cli_set(base + ['ipv6', 'address', 'no-default-link-local'])
 
             # after commit we must have no IPv6 link-local address
             self.cli_commit()
 
             for interface in self._interfaces:
                 self.assertNotIn(AF_INET6, ifaddresses(interface))
 
         def test_interface_mtu(self):
             if not self._test_mtu:
                 self.skipTest('not supported')
 
             for intf in self._interfaces:
                 base = self._base_path + [intf]
                 self.cli_set(base + ['mtu', self._mtu])
                 for option in self._options.get(intf, []):
                     self.cli_set(base + option.split())
 
             # commit interface changes
             self.cli_commit()
 
             # verify changed MTU
             for intf in self._interfaces:
                 tmp = get_interface_config(intf)
                 self.assertEqual(tmp['mtu'], int(self._mtu))
 
         def test_mtu_1200_no_ipv6_interface(self):
             # Testcase if MTU can be changed to 1200 on non IPv6
             # enabled interfaces
             if not self._test_mtu:
                 self.skipTest('not supported')
 
             old_mtu = self._mtu
             self._mtu = '1200'
 
             for intf in self._interfaces:
                 base = self._base_path + [intf]
                 for option in self._options.get(intf, []):
                     self.cli_set(base + option.split())
                 self.cli_set(base + ['mtu', self._mtu])
 
             # check validate() - can not set low MTU if 'no-default-link-local'
             # is not set on CLI
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
             for intf in self._interfaces:
                 base = self._base_path + [intf]
                 self.cli_set(base + ['ipv6', 'address', 'no-default-link-local'])
 
             # commit interface changes
             self.cli_commit()
 
             # verify changed MTU
             for intf in self._interfaces:
                 tmp = get_interface_config(intf)
                 self.assertEqual(tmp['mtu'], int(self._mtu))
 
             self._mtu = old_mtu
 
         def test_vif_8021q_interfaces(self):
             # XXX: This testcase is not allowed to run as first testcase, reason
             # is the Wireless test will first load the wifi kernel hwsim module
             # which creates a wlan0 and wlan1 interface which will fail the
             # tearDown() test in the end that no interface is allowed to survive!
             if not self._test_vlan:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
                 for vlan in self._vlan_range:
                     base = self._base_path + [interface, 'vif', vlan]
                     for address in self._test_addr:
                         self.cli_set(base + ['address', address])
 
             self.cli_commit()
 
             for intf in self._interfaces:
                 for vlan in self._vlan_range:
                     vif = f'{intf}.{vlan}'
                     for address in self._test_addr:
                         self.assertTrue(is_intf_addr_assigned(vif, address))
 
                     self.assertEqual(Interface(vif).get_admin_state(), 'up')
 
             # T4064: Delete interface addresses, keep VLAN interface
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for vlan in self._vlan_range:
                     base = self._base_path + [interface, 'vif', vlan]
                     self.cli_delete(base + ['address'])
 
             self.cli_commit()
 
             # Verify no IP address is assigned
             for interface in self._interfaces:
                 for vlan in self._vlan_range:
                     vif = f'{intf}.{vlan}'
                     for address in self._test_addr:
                         self.assertFalse(is_intf_addr_assigned(vif, address))
 
 
         def test_vif_8021q_mtu_limits(self):
             # XXX: This testcase is not allowed to run as first testcase, reason
             # is the Wireless test will first load the wifi kernel hwsim module
             # which creates a wlan0 and wlan1 interface which will fail the
             # tearDown() test in the end that no interface is allowed to survive!
             if not self._test_vlan or not self._test_mtu:
                 self.skipTest('not supported')
 
             mtu_1500 = '1500'
             mtu_9000 = '9000'
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 self.cli_set(base + ['mtu', mtu_1500])
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
                     if 'source-interface' in option:
                         iface = option.split()[-1]
                         iface_type = Section.section(iface)
                         self.cli_set(['interfaces', iface_type, iface, 'mtu', mtu_9000])
 
                 for vlan in self._vlan_range:
                     base = self._base_path + [interface, 'vif', vlan]
                     self.cli_set(base + ['mtu', mtu_9000])
 
             # check validate() - Interface MTU "9000" too high, parent interface MTU is "1500"!
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
             # Change MTU on base interface to be the same as on the VIF interface
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 self.cli_set(base + ['mtu', mtu_9000])
 
             self.cli_commit()
 
             # Verify MTU on base and VIF interfaces
             for interface in self._interfaces:
                 tmp = get_interface_config(interface)
                 self.assertEqual(tmp['mtu'], int(mtu_9000))
 
                 for vlan in self._vlan_range:
                     tmp = get_interface_config(f'{interface}.{vlan}')
                     self.assertEqual(tmp['mtu'], int(mtu_9000))
 
 
         def test_vif_8021q_qos_change(self):
             # XXX: This testcase is not allowed to run as first testcase, reason
             # is the Wireless test will first load the wifi kernel hwsim module
             # which creates a wlan0 and wlan1 interface which will fail the
             # tearDown() test in the end that no interface is allowed to survive!
             if not self._test_vlan:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
                 for vlan in self._vlan_range:
                     base = self._base_path + [interface, 'vif', vlan]
                     self.cli_set(base + ['ingress-qos', '0:1'])
                     self.cli_set(base + ['egress-qos', '1:6'])
 
             self.cli_commit()
 
             for intf in self._interfaces:
                 for vlan in self._vlan_range:
                     vif = f'{intf}.{vlan}'
                     tmp = get_interface_config(f'{vif}')
 
                     tmp2 = dict_search('linkinfo.info_data.ingress_qos', tmp)
                     for item in tmp2 if tmp2 else []:
                         from_key = item['from']
                         to_key = item['to']
                         self.assertEqual(from_key, 0)
                         self.assertEqual(to_key, 1)
 
                     tmp2 = dict_search('linkinfo.info_data.egress_qos', tmp)
                     for item in tmp2 if tmp2 else []:
                         from_key = item['from']
                         to_key = item['to']
                         self.assertEqual(from_key, 1)
                         self.assertEqual(to_key, 6)
 
                     self.assertEqual(Interface(vif).get_admin_state(), 'up')
 
             new_ingress_qos_from = 1
             new_ingress_qos_to = 6
             new_egress_qos_from = 2
             new_egress_qos_to = 7
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for vlan in self._vlan_range:
                     base = self._base_path + [interface, 'vif', vlan]
                     self.cli_set(base + ['ingress-qos', f'{new_ingress_qos_from}:{new_ingress_qos_to}'])
                     self.cli_set(base + ['egress-qos', f'{new_egress_qos_from}:{new_egress_qos_to}'])
 
             self.cli_commit()
 
             for intf in self._interfaces:
                 for vlan in self._vlan_range:
                     vif = f'{intf}.{vlan}'
                     tmp = get_interface_config(f'{vif}')
 
                     tmp2 = dict_search('linkinfo.info_data.ingress_qos', tmp)
                     if tmp2:
                         from_key = tmp2[0]['from']
                         to_key = tmp2[0]['to']
                         self.assertEqual(from_key, new_ingress_qos_from)
                         self.assertEqual(to_key, new_ingress_qos_to)
 
                     tmp2 = dict_search('linkinfo.info_data.egress_qos', tmp)
                     if tmp2:
                         from_key = tmp2[0]['from']
                         to_key = tmp2[0]['to']
                         self.assertEqual(from_key, new_egress_qos_from)
                         self.assertEqual(to_key, new_egress_qos_to)
 
         def test_vif_8021q_lower_up_down(self):
             # Testcase for https://vyos.dev/T3349
             if not self._test_vlan:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
                 # disable the lower interface
                 self.cli_set(base + ['disable'])
 
                 for vlan in self._vlan_range:
                     vlan_base = self._base_path + [interface, 'vif', vlan]
                     # disable the vlan interface
                     self.cli_set(vlan_base + ['disable'])
 
             self.cli_commit()
 
             # re-enable all lower interfaces
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 self.cli_delete(base + ['disable'])
 
             self.cli_commit()
 
             # verify that the lower interfaces are admin up and the vlan
             # interfaces are all admin down
             for interface in self._interfaces:
                 self.assertEqual(Interface(interface).get_admin_state(), 'up')
 
                 for vlan in self._vlan_range:
                     ifname = f'{interface}.{vlan}'
                     self.assertEqual(Interface(ifname).get_admin_state(), 'down')
 
 
         def test_vif_s_8021ad_vlan_interfaces(self):
             # XXX: This testcase is not allowed to run as first testcase, reason
             # is the Wireless test will first load the wifi kernel hwsim module
             # which creates a wlan0 and wlan1 interface which will fail the
             # tearDown() test in the end that no interface is allowed to survive!
             if not self._test_qinq:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
                 for vif_s in self._qinq_range:
                     for vif_c in self._vlan_range:
                         base = self._base_path + [interface, 'vif-s', vif_s, 'vif-c', vif_c]
                         self.cli_set(base + ['mtu', self._mtu])
                         for address in self._test_addr:
                             self.cli_set(base + ['address', address])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 for vif_s in self._qinq_range:
                     tmp = get_interface_config(f'{interface}.{vif_s}')
                     self.assertEqual(dict_search('linkinfo.info_data.protocol', tmp), '802.1ad')
 
                     for vif_c in self._vlan_range:
                         vif = f'{interface}.{vif_s}.{vif_c}'
                         # For an unknown reason this regularely fails on the QEMU builds,
                         # thus the test for reading back IP addresses is temporary
                         # disabled. There is no big deal here, as this uses the same
                         # methods on 802.1q and here it works and is verified.
 #                       for address in self._test_addr:
 #                           self.assertTrue(is_intf_addr_assigned(vif, address))
 
                         tmp = get_interface_config(vif)
                         self.assertEqual(tmp['mtu'], int(self._mtu))
 
 
             # T4064: Delete interface addresses, keep VLAN interface
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for vif_s in self._qinq_range:
                     for vif_c in self._vlan_range:
                         self.cli_delete(self._base_path + [interface, 'vif-s', vif_s, 'vif-c', vif_c, 'address'])
 
             self.cli_commit()
             # Verify no IP address is assigned
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for vif_s in self._qinq_range:
                     for vif_c in self._vlan_range:
                         vif = f'{interface}.{vif_s}.{vif_c}'
                         for address in self._test_addr:
                             self.assertFalse(is_intf_addr_assigned(vif, address))
 
             # T3972: remove vif-c interfaces from vif-s
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for vif_s in self._qinq_range:
                     base = self._base_path + [interface, 'vif-s', vif_s, 'vif-c']
                     self.cli_delete(base)
 
             self.cli_commit()
 
 
         def test_vif_s_protocol_change(self):
             # XXX: This testcase is not allowed to run as first testcase, reason
             # is the Wireless test will first load the wifi kernel hwsim module
             # which creates a wlan0 and wlan1 interface which will fail the
             # tearDown() test in the end that no interface is allowed to survive!
             if not self._test_qinq:
                 self.skipTest('not supported')
 
             for interface in self._interfaces:
                 base = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(base + option.split())
 
                 for vif_s in self._qinq_range:
                     for vif_c in self._vlan_range:
                         base = self._base_path + [interface, 'vif-s', vif_s, 'vif-c', vif_c]
                         for address in self._test_addr:
                             self.cli_set(base + ['address', address])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 for vif_s in self._qinq_range:
                     tmp = get_interface_config(f'{interface}.{vif_s}')
                     # check for the default value
                     self.assertEqual(tmp['linkinfo']['info_data']['protocol'], '802.1ad')
 
             # T3532: now change ethertype
             new_protocol = '802.1q'
             for interface in self._interfaces:
                 for vif_s in self._qinq_range:
                     base = self._base_path + [interface, 'vif-s', vif_s]
                     self.cli_set(base + ['protocol', new_protocol])
 
             self.cli_commit()
 
             # Verify new ethertype configuration
             for interface in self._interfaces:
                 for vif_s in self._qinq_range:
                     tmp = get_interface_config(f'{interface}.{vif_s}')
                     self.assertEqual(tmp['linkinfo']['info_data']['protocol'], new_protocol.upper())
 
         def test_interface_ip_options(self):
             if not self._test_ip:
                 self.skipTest('not supported')
 
             arp_tmo = '300'
             mss = '1420'
 
             for interface in self._interfaces:
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 # Options
                 if cli_defined(self._base_path + ['ip'], 'adjust-mss'):
                     self.cli_set(path + ['ip', 'adjust-mss', mss])
 
                 if cli_defined(self._base_path + ['ip'], 'arp-cache-timeout'):
                     self.cli_set(path + ['ip', 'arp-cache-timeout', arp_tmo])
 
                 if cli_defined(self._base_path + ['ip'], 'disable-arp-filter'):
                     self.cli_set(path + ['ip', 'disable-arp-filter'])
 
                 if cli_defined(self._base_path + ['ip'], 'disable-forwarding'):
                     self.cli_set(path + ['ip', 'disable-forwarding'])
 
                 if cli_defined(self._base_path + ['ip'], 'enable-directed-broadcast'):
                     self.cli_set(path + ['ip', 'enable-directed-broadcast'])
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-accept'):
                     self.cli_set(path + ['ip', 'enable-arp-accept'])
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-announce'):
                     self.cli_set(path + ['ip', 'enable-arp-announce'])
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-ignore'):
                     self.cli_set(path + ['ip', 'enable-arp-ignore'])
 
                 if cli_defined(self._base_path + ['ip'], 'enable-proxy-arp'):
                     self.cli_set(path + ['ip', 'enable-proxy-arp'])
 
                 if cli_defined(self._base_path + ['ip'], 'proxy-arp-pvlan'):
                     self.cli_set(path + ['ip', 'proxy-arp-pvlan'])
 
                 if cli_defined(self._base_path + ['ip'], 'source-validation'):
                     self.cli_set(path + ['ip', 'source-validation', 'loose'])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 if cli_defined(self._base_path + ['ip'], 'adjust-mss'):
                     base_options = f'oifname "{interface}"'
                     out = cmd('sudo nft list chain raw VYOS_TCP_MSS')
                     for line in out.splitlines():
                         if line.startswith(base_options):
                             self.assertIn(f'tcp option maxseg size set {mss}', line)
 
                 if cli_defined(self._base_path + ['ip'], 'arp-cache-timeout'):
                     tmp = read_file(f'/proc/sys/net/ipv4/neigh/{interface}/base_reachable_time_ms')
                     self.assertEqual(tmp, str((int(arp_tmo) * 1000))) # tmo value is in milli seconds
 
                 proc_base = f'/proc/sys/net/ipv4/conf/{interface}'
 
                 if cli_defined(self._base_path + ['ip'], 'disable-arp-filter'):
                     tmp = read_file(f'{proc_base}/arp_filter')
                     self.assertEqual('0', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-accept'):
                     tmp = read_file(f'{proc_base}/arp_accept')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-announce'):
                     tmp = read_file(f'{proc_base}/arp_announce')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'enable-arp-ignore'):
                     tmp = read_file(f'{proc_base}/arp_ignore')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'disable-forwarding'):
                     tmp = read_file(f'{proc_base}/forwarding')
                     self.assertEqual('0', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'enable-directed-broadcast'):
                     tmp = read_file(f'{proc_base}/bc_forwarding')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'enable-proxy-arp'):
                     tmp = read_file(f'{proc_base}/proxy_arp')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'proxy-arp-pvlan'):
                     tmp = read_file(f'{proc_base}/proxy_arp_pvlan')
                     self.assertEqual('1', tmp)
 
                 if cli_defined(self._base_path + ['ip'], 'source-validation'):
                     base_options = f'iifname "{interface}"'
                     out = cmd('sudo nft list chain ip raw vyos_rpfilter')
                     for line in out.splitlines():
                         if line.startswith(base_options):
                             self.assertIn('fib saddr oif 0', line)
                             self.assertIn('drop', line)
 
         def test_interface_ipv6_options(self):
             if not self._test_ipv6:
                 self.skipTest('not supported')
 
             mss = '1400'
             dad_transmits = '10'
             accept_dad = '0'
             source_validation = 'strict'
 
             for interface in self._interfaces:
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 # Options
                 if cli_defined(self._base_path + ['ipv6'], 'adjust-mss'):
                     self.cli_set(path + ['ipv6', 'adjust-mss', mss])
 
                 if cli_defined(self._base_path + ['ipv6'], 'accept-dad'):
                     self.cli_set(path + ['ipv6', 'accept-dad', accept_dad])
 
                 if cli_defined(self._base_path + ['ipv6'], 'dup-addr-detect-transmits'):
                     self.cli_set(path + ['ipv6', 'dup-addr-detect-transmits', dad_transmits])
 
                 if cli_defined(self._base_path + ['ipv6'], 'disable-forwarding'):
                     self.cli_set(path + ['ipv6', 'disable-forwarding'])
 
                 if cli_defined(self._base_path + ['ipv6'], 'source-validation'):
                     self.cli_set(path + ['ipv6', 'source-validation', source_validation])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 proc_base = f'/proc/sys/net/ipv6/conf/{interface}'
                 if cli_defined(self._base_path + ['ipv6'], 'adjust-mss'):
                     base_options = f'oifname "{interface}"'
                     out = cmd('sudo nft list chain ip6 raw VYOS_TCP_MSS')
                     for line in out.splitlines():
                         if line.startswith(base_options):
                             self.assertIn(f'tcp option maxseg size set {mss}', line)
 
                 if cli_defined(self._base_path + ['ipv6'], 'accept-dad'):
                     tmp = read_file(f'{proc_base}/accept_dad')
                     self.assertEqual(accept_dad, tmp)
 
                 if cli_defined(self._base_path + ['ipv6'], 'dup-addr-detect-transmits'):
                     tmp = read_file(f'{proc_base}/dad_transmits')
                     self.assertEqual(dad_transmits, tmp)
 
                 if cli_defined(self._base_path + ['ipv6'], 'disable-forwarding'):
                     tmp = read_file(f'{proc_base}/forwarding')
                     self.assertEqual('0', tmp)
 
                 if cli_defined(self._base_path + ['ipv6'], 'source-validation'):
                     base_options = f'iifname "{interface}"'
                     out = cmd('sudo nft list chain ip6 raw vyos_rpfilter')
                     for line in out.splitlines():
                         if line.startswith(base_options):
                             self.assertIn('fib saddr . iif oif 0', line)
                             self.assertIn('drop', line)
 
         def test_dhcpv6_client_options(self):
             if not self._test_ipv6_dhcpc6:
                 self.skipTest('not supported')
 
             duid_base = 10
             for interface in self._interfaces:
                 duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base)
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 # Enable DHCPv6 client
                 self.cli_set(path + ['address', 'dhcpv6'])
                 self.cli_set(path + ['dhcpv6-options', 'no-release'])
                 self.cli_set(path + ['dhcpv6-options', 'rapid-commit'])
                 self.cli_set(path + ['dhcpv6-options', 'parameters-only'])
                 self.cli_set(path + ['dhcpv6-options', 'duid', duid])
                 duid_base += 1
 
             self.cli_commit()
 
             duid_base = 10
             for interface in self._interfaces:
                 duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base)
                 dhcpc6_config = read_file(f'{dhcp6c_base_dir}/dhcp6c.{interface}.conf')
                 self.assertIn(f'interface {interface} ' + '{', dhcpc6_config)
                 self.assertIn(f'  request domain-name-servers;', dhcpc6_config)
                 self.assertIn(f'  request domain-name;', dhcpc6_config)
                 self.assertIn(f'  information-only;', dhcpc6_config)
                 self.assertIn(f'  send ia-na 0;', dhcpc6_config)
                 self.assertIn(f'  send rapid-commit;', dhcpc6_config)
                 self.assertIn(f'  send client-id {duid};', dhcpc6_config)
                 self.assertIn('};', dhcpc6_config)
                 duid_base += 1
 
                 # Better ask the process about it's commandline in the future
                 pid = process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10)
                 self.assertTrue(pid)
 
                 dhcp6c_options = read_file(f'/proc/{pid}/cmdline')
                 self.assertIn('-n', dhcp6c_options)
 
         def test_dhcpv6pd_auto_sla_id(self):
             if not self._test_ipv6_pd:
                 self.skipTest('not supported')
 
             prefix_len = '56'
             sla_len = str(64 - int(prefix_len))
 
             # Create delegatee interfaces first to avoid any confusion by dhcpc6
             # this is mainly an "issue" with virtual-ethernet interfaces
             delegatees = ['dum2340', 'dum2341', 'dum2342', 'dum2343', 'dum2344']
             for delegatee in delegatees:
                 section = Section.section(delegatee)
                 self.cli_set(['interfaces', section, delegatee])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 address = '1'
                 # prefix delegation stuff
                 pd_base = path + ['dhcpv6-options', 'pd', '0']
                 self.cli_set(pd_base + ['length', prefix_len])
 
                 for delegatee in delegatees:
                     self.cli_set(pd_base + ['interface', delegatee, 'address', address])
                     # increment interface address
                     address = str(int(address) + 1)
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 dhcpc6_config = read_file(f'{dhcp6c_base_dir}/dhcp6c.{interface}.conf')
 
                 # verify DHCPv6 prefix delegation
                 self.assertIn(f'prefix ::/{prefix_len} infinity;', dhcpc6_config)
 
                 address = '1'
                 sla_id = '0'
                 for delegatee in delegatees:
                     self.assertIn(f'prefix-interface {delegatee}' + r' {', dhcpc6_config)
                     self.assertIn(f'ifid {address};', dhcpc6_config)
                     self.assertIn(f'sla-id {sla_id};', dhcpc6_config)
                     self.assertIn(f'sla-len {sla_len};', dhcpc6_config)
 
                     # increment sla-id
                     sla_id = str(int(sla_id) + 1)
                     # increment interface address
                     address = str(int(address) + 1)
 
                 # Check for running process
                 self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10))
 
             for delegatee in delegatees:
                 # we can already cleanup the test delegatee interface here
                 # as until commit() is called, nothing happens
                 section = Section.section(delegatee)
                 self.cli_delete(['interfaces', section, delegatee])
 
         def test_dhcpv6pd_manual_sla_id(self):
             if not self._test_ipv6_pd:
                 self.skipTest('not supported')
 
             prefix_len = '56'
             sla_len = str(64 - int(prefix_len))
 
             # Create delegatee interfaces first to avoid any confusion by dhcpc6
             # this is mainly an "issue" with virtual-ethernet interfaces
             delegatees = ['dum3340', 'dum3341', 'dum3342', 'dum3343', 'dum3344']
             for delegatee in delegatees:
                 section = Section.section(delegatee)
                 self.cli_set(['interfaces', section, delegatee])
 
             self.cli_commit()
 
             for interface in self._interfaces:
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 # prefix delegation stuff
                 address = '1'
                 sla_id = '1'
                 pd_base = path + ['dhcpv6-options', 'pd', '0']
                 self.cli_set(pd_base + ['length', prefix_len])
 
                 for delegatee in delegatees:
                     self.cli_set(pd_base + ['interface', delegatee, 'address', address])
                     self.cli_set(pd_base + ['interface', delegatee, 'sla-id', sla_id])
 
                     # increment interface address
                     address = str(int(address) + 1)
                     sla_id = str(int(sla_id) + 1)
 
             self.cli_commit()
 
             # Verify dhcpc6 client configuration
             for interface in self._interfaces:
                 address = '1'
                 sla_id = '1'
                 dhcpc6_config = read_file(f'{dhcp6c_base_dir}/dhcp6c.{interface}.conf')
 
                 # verify DHCPv6 prefix delegation
                 self.assertIn(f'prefix ::/{prefix_len} infinity;', dhcpc6_config)
 
                 for delegatee in delegatees:
                     self.assertIn(f'prefix-interface {delegatee}' + r' {', dhcpc6_config)
                     self.assertIn(f'ifid {address};', dhcpc6_config)
                     self.assertIn(f'sla-id {sla_id};', dhcpc6_config)
                     self.assertIn(f'sla-len {sla_len};', dhcpc6_config)
 
                     # increment sla-id
                     sla_id = str(int(sla_id) + 1)
                     # increment interface address
                     address = str(int(address) + 1)
 
                 # Check for running process
                 self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10))
 
             for delegatee in delegatees:
                 # we can already cleanup the test delegatee interface here
                 # as until commit() is called, nothing happens
                 section = Section.section(delegatee)
                 self.cli_delete(['interfaces', section, delegatee])
 
         def test_eapol(self):
             if not self._test_eapol:
                 self.skipTest('not supported')
 
             cfg_dir = '/run/wpa_supplicant'
 
             ca_certs = {
                 'eapol-server-ca-root': server_ca_root_cert_data,
                 'eapol-server-ca-intermediate': server_ca_intermediate_cert_data,
                 'eapol-client-ca-root': client_ca_root_cert_data,
                 'eapol-client-ca-intermediate': client_ca_intermediate_cert_data,
             }
             cert_name = 'eapol-client'
 
             for name, data in ca_certs.items():
                 self.cli_set(['pki', 'ca', name, 'certificate', data.replace('\n','')])
 
             self.cli_set(['pki', 'certificate', cert_name, 'certificate', client_cert_data.replace('\n','')])
             self.cli_set(['pki', 'certificate', cert_name, 'private', 'key', client_key_data.replace('\n','')])
 
             for interface in self._interfaces:
                 path = self._base_path + [interface]
                 for option in self._options.get(interface, []):
                     self.cli_set(path + option.split())
 
                 # Enable EAPoL
                 self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-server-ca-intermediate'])
                 self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-client-ca-intermediate'])
                 self.cli_set(self._base_path + [interface, 'eapol', 'certificate', cert_name])
 
             self.cli_commit()
 
             # Test multiple CA chains
             self.assertEqual(get_certificate_count(interface, 'ca'), 4)
 
             for interface in self._interfaces:
                 self.cli_delete(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-client-ca-intermediate'])
 
             self.cli_commit()
 
             # Validate interface config
             for interface in self._interfaces:
                 tmp = get_wpa_supplicant_value(interface, 'key_mgmt')
                 self.assertEqual('IEEE8021X', tmp)
 
                 tmp = get_wpa_supplicant_value(interface, 'eap')
                 self.assertEqual('TLS', tmp)
 
                 tmp = get_wpa_supplicant_value(interface, 'eapol_flags')
                 self.assertEqual('0', tmp)
 
                 tmp = get_wpa_supplicant_value(interface, 'ca_cert')
                 self.assertEqual(f'"{cfg_dir}/{interface}_ca.pem"', tmp)
 
                 tmp = get_wpa_supplicant_value(interface, 'client_cert')
                 self.assertEqual(f'"{cfg_dir}/{interface}_cert.pem"', tmp)
 
                 tmp = get_wpa_supplicant_value(interface, 'private_key')
                 self.assertEqual(f'"{cfg_dir}/{interface}_cert.key"', tmp)
 
                 mac = read_file(f'/sys/class/net/{interface}/address')
                 tmp = get_wpa_supplicant_value(interface, 'identity')
                 self.assertEqual(f'"{mac}"', tmp)
 
                 # Check certificate files have the full chain
                 self.assertEqual(get_certificate_count(interface, 'ca'), 2)
                 self.assertEqual(get_certificate_count(interface, 'cert'), 3)
 
                 # Check for running process
                 self.assertTrue(process_named_running('wpa_supplicant', cmdline=f'-i{interface}'))
 
             # Remove EAPoL configuration
             for interface in self._interfaces:
                 self.cli_delete(self._base_path + [interface, 'eapol'])
 
             # Commit and check that process is no longer running
             self.cli_commit()
             self.assertFalse(process_named_running('wpa_supplicant'))
 
             for name in ca_certs:
                 self.cli_delete(['pki', 'ca', name])
             self.cli_delete(['pki', 'certificate', cert_name])
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index 2be25ff22..a54622700 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -1,206 +1,209 @@
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import os
 import unittest
 import paramiko
 import pprint
 
 from time import sleep
 from typing import Type
 
 from vyos.configsession import ConfigSession
 from vyos.configsession import ConfigSessionError
 from vyos import ConfigError
 from vyos.defaults import commit_lock
 from vyos.utils.process import cmd
 from vyos.utils.process import run
 
 save_config = '/tmp/vyos-smoketest-save'
 
 # The commit process is not finished until all pending files from
 # VYATTA_CHANGES_ONLY_DIR are copied to VYATTA_ACTIVE_CONFIGURATION_DIR. This
 # is done inside libvyatta-cfg1 and the FUSE UnionFS part. On large non-
 # interactive commits FUSE UnionFS might not replicate the real state in time,
 # leading to errors when querying the working and effective configuration.
 # TO BE DELETED AFTER SWITCH TO IN MEMORY CONFIG
 CSTORE_GUARD_TIME = 4
 
 # This class acts as shim between individual Smoketests developed for VyOS and
 # the Python UnitTest framework. Before every test is loaded, we dump the current
 # system configuration and reload it after the test - despite the test results.
 #
 # Using this approach we can not render a live system useless while running any
 # kind of smoketest. In addition it adds debug capabilities like printing the
 # command used to execute the test.
 class VyOSUnitTestSHIM:
     class TestCase(unittest.TestCase):
         # if enabled in derived class, print out each and every set/del command
         # on the CLI. This is usefull to grap all the commands required to
         # trigger the certain failure condition.
         # Use "self.debug = True" in derived classes setUp() method
         debug = False
+        # Time to wait after a commit to ensure the CStore is up to date
+        # only required for testcases using FRR
+        _commit_guard_time = 0
         @classmethod
         def setUpClass(cls):
             cls._session = ConfigSession(os.getpid())
             cls._session.save_config(save_config)
             if os.path.exists('/tmp/vyos.smoketest.debug'):
                 cls.debug = True
             pass
 
         @classmethod
         def tearDownClass(cls):
             # discard any pending changes which might caused a messed up config
             cls._session.discard()
             # ... and restore the initial state
             cls._session.migrate_and_load_config(save_config)
 
             try:
                 cls._session.commit()
             except (ConfigError, ConfigSessionError):
                 cls._session.discard()
                 cls.fail(cls)
 
         def cli_set(self, config):
             if self.debug:
                 print('set ' + ' '.join(config))
             self._session.set(config)
 
         def cli_delete(self, config):
             if self.debug:
                 print('del ' + ' '.join(config))
             self._session.delete(config)
 
         def cli_discard(self):
             if self.debug:
                 print('DISCARD')
             self._session.discard()
 
         def cli_commit(self):
             if self.debug:
                 print('commit')
             self._session.commit()
             # During a commit there is a process opening commit_lock, and run()
             # returns 0
             while run(f'sudo lsof -nP {commit_lock}') == 0:
                 sleep(0.250)
             # Wait for CStore completion for fast non-interactive commits
-            sleep(CSTORE_GUARD_TIME)
+            sleep(self._commit_guard_time)
 
         def op_mode(self, path : list) -> None:
             """
             Execute OP-mode command and return stdout
             """
             if self.debug:
                 print('commit')
             path = ' '.join(path)
             out = cmd(f'/opt/vyatta/bin/vyatta-op-cmd-wrapper {path}')
             if self.debug:
                 print(f'\n\ncommand "{path}" returned:\n')
                 pprint.pprint(out)
             return out
 
         def getFRRconfig(self, string=None, end='$', endsection='^!',
                          substring=None, endsubsection=None, empty_retry=0):
             """
             Retrieve current "running configuration" from FRR
 
             string:        search for a specific start string in the configuration
             end:           end of the section to search for (line ending)
             endsection:    end of the configuration
             substring:     search section under the result found by string
             endsubsection: end of the subsection (usually something with "exit")
             """
             command = f'vtysh -c "show run no-header"'
             if string:
                 command += f' | sed -n "/^{string}{end}/,/{endsection}/p"'
                 if substring and endsubsection:
                     command += f' | sed -n "/^{substring}/,/{endsubsection}/p"'
             out = cmd(command)
             if self.debug:
                 print(f'\n\ncommand "{command}" returned:\n')
                 pprint.pprint(out)
             if empty_retry > 0:
                 retry_count = 0
                 while not out and retry_count < empty_retry:
                     if self.debug and retry_count % 10 == 0:
                         print(f"Attempt {retry_count}: FRR config is still empty. Retrying...")
                     retry_count += 1
                     sleep(1)
                     out = cmd(command)
                 if not out:
                     print(f'FRR configuration still empty after {empty_retry} retires!')
             return out
 
         @staticmethod
         def ssh_send_cmd(command, username, password, hostname='localhost'):
             """ SSH command execution helper """
             # Try to login via SSH
             ssh_client = paramiko.SSHClient()
             ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
             ssh_client.connect(hostname=hostname, username=username, password=password)
             _, stdout, stderr = ssh_client.exec_command(command)
             output = stdout.read().decode().strip()
             error = stderr.read().decode().strip()
             ssh_client.close()
             return output, error
 
         # Verify nftables output
         def verify_nftables(self, nftables_search, table, inverse=False, args=''):
             nftables_output = cmd(f'sudo nft {args} list table {table}')
 
             for search in nftables_search:
                 matched = False
                 for line in nftables_output.split("\n"):
                     if all(item in line for item in search):
                         matched = True
                         break
                 self.assertTrue(not matched if inverse else matched, msg=search)
 
         def verify_nftables_chain(self, nftables_search, table, chain, inverse=False, args=''):
             nftables_output = cmd(f'sudo nft {args} list chain {table} {chain}')
 
             for search in nftables_search:
                 matched = False
                 for line in nftables_output.split("\n"):
                     if all(item in line for item in search):
                         matched = True
                         break
                 self.assertTrue(not matched if inverse else matched, msg=search)
 
         # Verify ip rule output
         def verify_rules(self, rules_search, inverse=False, addr_family='inet'):
             rule_output = cmd(f'ip -family {addr_family} rule show')
 
             for search in rules_search:
                 matched = False
                 for line in rule_output.split("\n"):
                     if all(item in line for item in search):
                         matched = True
                         break
                 self.assertTrue(not matched if inverse else matched, msg=search)
 
 # standard construction; typing suggestion: https://stackoverflow.com/a/70292317
 def ignore_warning(warning: Type[Warning]):
     import warnings
     from functools import wraps
 
     def inner(f):
         @wraps(f)
         def wrapped(*args, **kwargs):
             with warnings.catch_warnings():
                 warnings.simplefilter("ignore", category=warning)
                 return f(*args, **kwargs)
         return wrapped
     return inner
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 7ea1b610e..9d4fc0845 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -1,1994 +1,2006 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.utils.process import cmd
 
 base_path = ['policy']
 
 class TestPolicy(VyOSUnitTestSHIM.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        super(TestPolicy, cls).setUpClass()
+
+        # ensure we can also run this test on a live system - so lets clean
+        # out the current configuration :)
+        cls.cli_delete(cls, base_path)
+        cls.cli_delete(cls, ['vrf'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
+
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
     def test_access_list(self):
         acls = {
             '50' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'source' : { 'any' : '' },
                     },
                     '10' : {
                         'action' : 'deny',
                         'source' : { 'host' : '1.2.3.4' },
                     },
                 },
              },
             '150' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'source' : { 'any' : '' },
                         'destination' : { 'host' : '2.2.2.2' },
                     },
                     '10' : {
                         'action' : 'deny',
                         'source' : { 'any' : '' },
                         'destination' : { 'any' : '' },
                     },
                 },
             },
             '2000' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'destination' : { 'any' : '' },
                         'source' : { 'network' : '10.0.0.0', 'inverse-mask' : '0.255.255.255' },
                     },
                     '10' : {
                         'action' : 'permit',
                         'destination' : { 'any' : '' },
                         'source' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' },
                     },
                     '15' : {
                         'action' : 'permit',
                         'destination' : { 'any' : '' },
                         'source' : { 'network' : '192.168.0.0', 'inverse-mask' : '0.0.255.255' },
                     },
                     '20' : {
                         'action' : 'permit',
                         'destination' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' },
                         'source' : { 'network' : '10.0.0.0', 'inverse-mask' : '0.255.255.255' },
                     },
                     '25' : {
                         'action' : 'deny',
                         'destination' : { 'network' : '192.168.0.0', 'inverse-mask' : '0.0.255.255' },
                         'source' : { 'network' : '172.16.0.0', 'inverse-mask' : '0.15.255.255' },
                     },
                     '30' : {
                         'action' : 'deny',
                         'destination' : { 'any' : '' },
                         'source' : { 'any' : '' },
                     },
                 },
             },
         }
 
         for acl, acl_config in acls.items():
             path = base_path + ['access-list', acl]
             self.cli_set(path + ['description', f'VyOS-ACL-{acl}'])
             if 'rule' not in acl_config:
                 continue
 
             for rule, rule_config in acl_config['rule'].items():
                 self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 for direction in ['source', 'destination']:
                     if direction in rule_config:
                         if 'any' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'any'])
                         if 'host' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'host', rule_config[direction]['host']])
                         if 'network' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']])
                             self.cli_set(path + ['rule', rule, direction, 'inverse-mask', rule_config[direction]['inverse-mask']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('access-list', end='')
         for acl, acl_config in acls.items():
             for rule, rule_config in acl_config['rule'].items():
                 tmp = f'access-list {acl} seq {rule}'
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 if {'source', 'destination'} <= set(rule_config):
                     tmp += ' ip'
 
                 for direction in ['source', 'destination']:
                     if direction in rule_config:
                         if 'any' in rule_config[direction]:
                             tmp += ' any'
                         if 'host' in rule_config[direction]:
                             # XXX: Some weird side rule from the old vyatta days
                             # possible to clean this up after the vyos-1x migration
                             if int(acl) in range(100, 200) or int(acl) in range(2000, 2700):
                                 tmp += ' host'
 
                             tmp += ' ' + rule_config[direction]['host']
                         if 'network' in rule_config[direction]:
                             tmp += ' ' + rule_config[direction]['network'] + ' ' + rule_config[direction]['inverse-mask']
 
                 self.assertIn(tmp, config)
 
     def test_access_list6(self):
         acls = {
             '50' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'source' : { 'any' : '' },
                     },
                     '10' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:10::/48', 'exact-match' : '' },
                     },
                     '15' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:20::/48' },
                     },
                 },
              },
             '100' : {
                 'rule' : {
                     '5' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:10::/64', 'exact-match' : '' },
                     },
                     '10' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:20::/64', },
                     },
                     '15' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:30::/64', 'exact-match' : '' },
                     },
                     '20' : {
                         'action' : 'deny',
                         'source' : { 'network' : '2001:db8:40::/64', 'exact-match' : '' },
                     },
                     '25' : {
                         'action' : 'deny',
                         'source' : { 'any' : '' },
                     },
                 },
              },
         }
 
         for acl, acl_config in acls.items():
             path = base_path + ['access-list6', acl]
             self.cli_set(path + ['description', f'VyOS-ACL-{acl}'])
             if 'rule' not in acl_config:
                 continue
 
             for rule, rule_config in acl_config['rule'].items():
                 self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 for direction in ['source', 'destination']:
                     if direction in rule_config:
                         if 'any' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'any'])
                         if 'network' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'network', rule_config[direction]['network']])
                         if 'exact-match' in rule_config[direction]:
                             self.cli_set(path + ['rule', rule, direction, 'exact-match'])
 
         self.cli_commit()
 
         config = self.getFRRconfig('ipv6 access-list', end='')
         for acl, acl_config in acls.items():
             for rule, rule_config in acl_config['rule'].items():
                 tmp = f'ipv6 access-list {acl} seq {rule}'
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 if {'source', 'destination'} <= set(rule_config):
                     tmp += ' ip'
 
                 for direction in ['source', 'destination']:
                     if direction in rule_config:
                         if 'any' in rule_config[direction]:
                             tmp += ' any'
                         if 'network' in rule_config[direction]:
                             tmp += ' ' + rule_config[direction]['network']
                         if 'exact-match' in rule_config[direction]:
                             tmp += ' exact-match'
 
                 self.assertIn(tmp, config)
 
 
     def test_as_path_list(self):
         test_data = {
             'VyOS' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '^44501 64502$',
                     },
                     '10' : {
                         'action' : 'permit',
                         'regex'  : '44501|44502|44503',
                     },
                     '15' : {
                         'action' : 'permit',
                         'regex'  : '^44501_([0-9]+_)+',
                     },
                 },
             },
             'Customers' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '_10_',
                     },
                     '10' : {
                         'action' : 'permit',
                         'regex'  : '_20_',
                     },
                     '15' : {
                         'action' : 'permit',
                         'regex'  : '_30_',
                     },
                     '20' : {
                         'action' : 'deny',
                         'regex'  : '_40_',
                     },
                 },
             },
             'bogons' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '_0_',
                     },
                     '10' : {
                         'action' : 'permit',
                         'regex'  : '_23456_',
                     },
                     '15' : {
                         'action' : 'permit',
                         'regex'  : '_6449[6-9]_|_65[0-4][0-9][0-9]_|_655[0-4][0-9]_|_6555[0-1]_',
                     },
                     '20' : {
                         'action' : 'permit',
                         'regex'  : '_6555[2-9]_|_655[6-9][0-9]_|_65[6-9][0-9][0-9]_|_6[6-9][0-9][0-9][0-]_|_[7-9][0-9][0-9][0-9][0-9]_|_1[0-2][0-9][0-9][0-9][0-9]_|_130[0-9][0-9][0-9]_|_1310[0-6][0-9]_|_13107[01]_',
                     },
                 },
             },
         }
 
         for as_path, as_path_config in test_data.items():
             path = base_path + ['as-path-list', as_path]
             self.cli_set(path + ['description', f'VyOS-ASPATH-{as_path}'])
             if 'rule' not in as_path_config:
                 continue
 
             for rule, rule_config in as_path_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'regex' in rule_config:
                     self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('bgp as-path access-list', end='')
         for as_path, as_path_config in test_data.items():
             if 'rule' not in as_path_config:
                 continue
 
             for rule, rule_config in as_path_config['rule'].items():
                 tmp = f'bgp as-path access-list {as_path} seq {rule}'
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['regex']
 
                 self.assertIn(tmp, config)
 
     def test_community_list(self):
         test_data = {
             '100' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '.*',
                     },
                 },
             },
             '200' : {
                 'rule' : {
                     '5' : {
                         'action' : 'deny',
                         'regex'  : '^1:201$',
                     },
                     '10' : {
                         'action' : 'deny',
                         'regex'  : '1:101$',
                     },
                     '15' : {
                         'action' : 'deny',
                         'regex'  : '^1:100$',
                     },
                 },
             },
         }
 
         for comm_list, comm_list_config in test_data.items():
             path = base_path + ['community-list', comm_list]
             self.cli_set(path + ['description', f'VyOS-COMM-{comm_list}'])
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'regex' in rule_config:
                     self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('bgp community-list', end='')
         for comm_list, comm_list_config in test_data.items():
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 tmp = f'bgp community-list {comm_list} seq {rule}'
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['regex']
 
                 self.assertIn(tmp, config)
 
     def test_extended_community_list(self):
         test_data = {
             'foo' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '.*',
                     },
                 },
             },
             '200' : {
                 'rule' : {
                     '5' : {
                         'action' : 'deny',
                         'regex'  : '^1:201$',
                     },
                     '10' : {
                         'action' : 'deny',
                         'regex'  : '1:101$',
                     },
                     '15' : {
                         'action' : 'deny',
                         'regex'  : '^1:100$',
                     },
                 },
             },
         }
 
         for comm_list, comm_list_config in test_data.items():
             path = base_path + ['extcommunity-list', comm_list]
             self.cli_set(path + ['description', f'VyOS-EXTCOMM-{comm_list}'])
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'regex' in rule_config:
                     self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('bgp extcommunity-list', end='')
         for comm_list, comm_list_config in test_data.items():
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 # if the community is not a number but a name, the expanded
                 # keyword is used
                 expanded = ''
                 if not comm_list.isnumeric():
                     expanded = ' expanded'
                 tmp = f'bgp extcommunity-list{expanded} {comm_list} seq {rule}'
 
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['regex']
 
                 self.assertIn(tmp, config)
 
 
     def test_large_community_list(self):
         test_data = {
             'foo' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '667:123:100',
                     },
                 },
             },
             'bar' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'regex'  : '65000:120:10',
                     },
                     '10' : {
                         'action' : 'permit',
                         'regex'  : '65000:120:20',
                     },
                     '15' : {
                         'action' : 'permit',
                         'regex'  : '65000:120:30',
                     },
                 },
             },
         }
 
         for comm_list, comm_list_config in test_data.items():
             path = base_path + ['large-community-list', comm_list]
             self.cli_set(path + ['description', f'VyOS-LARGECOMM-{comm_list}'])
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'regex' in rule_config:
                     self.cli_set(path + ['rule', rule, 'regex', rule_config['regex']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('bgp large-community-list', end='')
         for comm_list, comm_list_config in test_data.items():
             if 'rule' not in comm_list_config:
                 continue
 
             for rule, rule_config in comm_list_config['rule'].items():
                 tmp = f'bgp large-community-list expanded {comm_list} seq {rule}'
 
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['regex']
 
                 self.assertIn(tmp, config)
 
 
     def test_prefix_list(self):
         test_data = {
             'foo' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'prefix'  : '10.0.0.0/8',
                         'ge' : '16',
                         'le' : '24',
                     },
                     '10' : {
                         'action' : 'deny',
                         'prefix'  : '172.16.0.0/12',
                         'ge' : '16',
                     },
                     '15' : {
                         'action' : 'permit',
                         'prefix'  : '192.168.0.0/16',
                     },
                 },
             },
             'bar' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'prefix'  : '10.0.10.0/24',
                         'ge' : '25',
                         'le' : '26',
                     },
                     '10' : {
                         'action' : 'deny',
                         'prefix'  : '10.0.20.0/24',
                         'le' : '25',
                     },
                     '15' : {
                         'action' : 'permit',
                         'prefix'  : '10.0.25.0/24',
                     },
                 },
             },
         }
 
         for prefix_list, prefix_list_config in test_data.items():
             path = base_path + ['prefix-list', prefix_list]
             self.cli_set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}'])
             if 'rule' not in prefix_list_config:
                 continue
 
             for rule, rule_config in prefix_list_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'prefix' in rule_config:
                     self.cli_set(path + ['rule', rule, 'prefix', rule_config['prefix']])
                 if 'ge' in rule_config:
                     self.cli_set(path + ['rule', rule, 'ge', rule_config['ge']])
                 if 'le' in rule_config:
                     self.cli_set(path + ['rule', rule, 'le', rule_config['le']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('ip prefix-list', end='')
         for prefix_list, prefix_list_config in test_data.items():
             if 'rule' not in prefix_list_config:
                 continue
 
             for rule, rule_config in prefix_list_config['rule'].items():
                 tmp = f'ip prefix-list {prefix_list} seq {rule}'
 
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['prefix']
 
                 if 'ge' in rule_config:
                     tmp += ' ge ' + rule_config['ge']
                 if 'le' in rule_config:
                     tmp += ' le ' + rule_config['le']
 
                 self.assertIn(tmp, config)
 
 
     def test_prefix_list6(self):
         test_data = {
             'foo' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'prefix'  : '2001:db8::/32',
                         'ge' : '40',
                         'le' : '48',
                     },
                     '10' : {
                         'action' : 'deny',
                         'prefix'  : '2001:db8::/32',
                         'ge' : '48',
                     },
                     '15' : {
                         'action' : 'permit',
                         'prefix'  : '2001:db8:1000::/64',
                     },
                 },
             },
             'bar' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'prefix'  : '2001:db8:100::/40',
                         'ge' : '48',
                     },
                     '10' : {
                         'action' : 'permit',
                         'prefix'  : '2001:db8:200::/40',
                         'ge' : '48',
                     },
                     '15' : {
                         'action' : 'deny',
                         'prefix'  : '2001:db8:300::/40',
                         'le' : '64',
                     },
                 },
             },
         }
 
         for prefix_list, prefix_list_config in test_data.items():
             path = base_path + ['prefix-list6', prefix_list]
             self.cli_set(path + ['description', f'VyOS-PFX-LIST-{prefix_list}'])
             if 'rule' not in prefix_list_config:
                 continue
 
             for rule, rule_config in prefix_list_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'prefix' in rule_config:
                     self.cli_set(path + ['rule', rule, 'prefix', rule_config['prefix']])
                 if 'ge' in rule_config:
                     self.cli_set(path + ['rule', rule, 'ge', rule_config['ge']])
                 if 'le' in rule_config:
                     self.cli_set(path + ['rule', rule, 'le', rule_config['le']])
 
         self.cli_commit()
 
         config = self.getFRRconfig('ipv6 prefix-list', end='')
         for prefix_list, prefix_list_config in test_data.items():
             if 'rule' not in prefix_list_config:
                 continue
 
             for rule, rule_config in prefix_list_config['rule'].items():
                 tmp = f'ipv6 prefix-list {prefix_list} seq {rule}'
 
                 if rule_config['action'] == 'permit':
                     tmp += ' permit'
                 else:
                     tmp += ' deny'
 
                 tmp += ' ' + rule_config['prefix']
 
                 if 'ge' in rule_config:
                     tmp += ' ge ' + rule_config['ge']
                 if 'le' in rule_config:
                     tmp += ' le ' + rule_config['le']
 
                 self.assertIn(tmp, config)
 
     def test_prefix_list_duplicates(self):
         # FRR does not allow to specify the same profix list rule multiple times
         #
         # vyos(config)# ip prefix-list foo seq 10 permit 192.0.2.0/24
         # vyos(config)# ip prefix-list foo seq 20 permit 192.0.2.0/24
         # % Configuration failed.
         # Error type: validation
         # Error description: duplicated prefix list value: 192.0.2.0/24
 
         # There is also a VyOS verify() function to test this
 
         prefix = '100.64.0.0/10'
         prefix_list = 'duplicates'
         test_range = range(20, 25)
         path = base_path + ['prefix-list', prefix_list]
 
         for rule in test_range:
             self.cli_set(path + ['rule', str(rule), 'action', 'permit'])
             self.cli_set(path + ['rule', str(rule), 'prefix', prefix])
 
         # Duplicate prefixes
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         for rule in test_range:
             self.cli_set(path + ['rule', str(rule), 'le', str(rule)])
 
         self.cli_commit()
 
         config = self.getFRRconfig('ip prefix-list', end='')
         for rule in test_range:
             tmp = f'ip prefix-list {prefix_list} seq {rule} permit {prefix} le {rule}'
             self.assertIn(tmp, config)
     def test_route_map_community_set(self):
         test_data = {
             "community-configuration": {
                 "rule": {
                     "10": {
                         "action": "permit",
                         "set": {
                             "community": {
                                 "replace": [
                                     "65000:10",
                                     "65001:11"
                                 ]
                             },
                             "extcommunity": {
                                 "bandwidth": "200",
                                 "rt": [
                                     "65000:10",
                                     "192.168.0.1:11"
                                 ],
                                 "soo": [
                                     "192.168.0.1:11",
                                     "65000:10"
                                 ]
                             },
                             "large-community": {
                                 "replace": [
                                     "65000:65000:10",
                                     "65000:65000:11"
                                 ]
                             }
                         }
                     },
                     "20": {
                         "action": "permit",
                         "set": {
                             "community": {
                                 "add": [
                                     "65000:10",
                                     "65001:11"
                                 ]
                             },
                             "extcommunity": {
                                 "bandwidth": "200",
                                 "bandwidth-non-transitive": {}
                             },
                             "large-community": {
                                 "add": [
                                     "65000:65000:10",
                                     "65000:65000:11"
                                 ]
                             }
                         }
                     },
                     "30": {
                         "action": "permit",
                         "set": {
                             "community": {
                                 "none": {}
                             },
                             "extcommunity": {
                                 "none": {}
                             },
                             "large-community": {
                                 "none": {}
                             }
                         }
                     }
                 }
             }
         }
         for route_map, route_map_config in test_data.items():
             path = base_path + ['route-map', route_map]
             self.cli_set(path + ['description', f'VyOS ROUTE-MAP {route_map}'])
             if 'rule' not in route_map_config:
                 continue
 
             for rule, rule_config in route_map_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
                 if 'set' in rule_config:
 
                     #Add community in configuration
                     if 'community' in rule_config['set']:
                         if 'none' in rule_config['set']['community']:
                             self.cli_set(path + ['rule', rule, 'set', 'community', 'none'])
                         else:
                             community_path = path + ['rule', rule, 'set', 'community']
                             if 'add' in rule_config['set']['community']:
                                 for community_unit in rule_config['set']['community']['add']:
                                     self.cli_set(community_path + ['add', community_unit])
                             if 'replace' in rule_config['set']['community']:
                                 for community_unit in rule_config['set']['community']['replace']:
                                     self.cli_set(community_path + ['replace', community_unit])
 
                     #Add large-community in configuration
                     if 'large-community' in rule_config['set']:
                         if 'none' in rule_config['set']['large-community']:
                             self.cli_set(path + ['rule', rule, 'set', 'large-community', 'none'])
                         else:
                             community_path = path + ['rule', rule, 'set', 'large-community']
                             if 'add' in rule_config['set']['large-community']:
                                 for community_unit in rule_config['set']['large-community']['add']:
                                     self.cli_set(community_path + ['add', community_unit])
                             if 'replace' in rule_config['set']['large-community']:
                                 for community_unit in rule_config['set']['large-community']['replace']:
                                     self.cli_set(community_path + ['replace', community_unit])
 
                     #Add extcommunity in configuration
                     if 'extcommunity' in rule_config['set']:
                         if 'none' in rule_config['set']['extcommunity']:
                             self.cli_set(path + ['rule', rule, 'set', 'extcommunity', 'none'])
                         else:
                             if 'bandwidth' in rule_config['set']['extcommunity']:
                                 self.cli_set(path + ['rule', rule, 'set', 'extcommunity', 'bandwidth', rule_config['set']['extcommunity']['bandwidth']])
                             if 'bandwidth-non-transitive' in rule_config['set']['extcommunity']:
                                 self.cli_set(path + ['rule', rule, 'set','extcommunity', 'bandwidth-non-transitive'])
                             if 'rt' in rule_config['set']['extcommunity']:
                                 for community_unit in rule_config['set']['extcommunity']['rt']:
                                     self.cli_set(path + ['rule', rule, 'set', 'extcommunity','rt',community_unit])
                             if 'soo' in rule_config['set']['extcommunity']:
                                 for community_unit in rule_config['set']['extcommunity']['soo']:
                                     self.cli_set(path + ['rule', rule, 'set', 'extcommunity','soo',community_unit])
         self.cli_commit()
 
         for route_map, route_map_config in test_data.items():
             if 'rule' not in route_map_config:
                 continue
             for rule, rule_config in route_map_config['rule'].items():
                 name = f'route-map {route_map} {rule_config["action"]} {rule}'
                 config = self.getFRRconfig(name)
                 self.assertIn(name, config)
 
                 if 'set' in rule_config:
                     #Check community
                     if 'community' in rule_config['set']:
                         if 'none' in rule_config['set']['community']:
                             tmp = f'set community none'
                             self.assertIn(tmp, config)
                         if 'replace' in rule_config['set']['community']:
                             values = ' '.join(rule_config['set']['community']['replace'])
                             tmp = f'set community {values}'
                             self.assertIn(tmp, config)
                         if 'add' in rule_config['set']['community']:
                             values = ' '.join(rule_config['set']['community']['add'])
                             tmp = f'set community {values} additive'
                             self.assertIn(tmp, config)
                     #Check large-community
                     if 'large-community' in rule_config['set']:
                         if 'none' in rule_config['set']['large-community']:
                             tmp = f'set large-community none'
                             self.assertIn(tmp, config)
                         if 'replace' in rule_config['set']['large-community']:
                             values = ' '.join(rule_config['set']['large-community']['replace'])
                             tmp = f'set large-community {values}'
                             self.assertIn(tmp, config)
                         if 'add' in rule_config['set']['large-community']:
                             values = ' '.join(rule_config['set']['large-community']['add'])
                             tmp = f'set large-community {values} additive'
                             self.assertIn(tmp, config)
                     #Check extcommunity
                     if 'extcommunity' in rule_config['set']:
                         if 'none' in rule_config['set']['extcommunity']:
                             tmp = 'set extcommunity none'
                             self.assertIn(tmp, config)
                         if 'bandwidth' in rule_config['set']['extcommunity']:
                             values = rule_config['set']['extcommunity']['bandwidth']
                             tmp = f'set extcommunity bandwidth {values}'
                             if 'bandwidth-non-transitive' in rule_config['set']['extcommunity']:
                                 tmp = tmp + ' non-transitive'
                             self.assertIn(tmp, config)
                         if 'rt' in rule_config['set']['extcommunity']:
                             values = ' '.join(rule_config['set']['extcommunity']['rt'])
                             tmp = f'set extcommunity rt {values}'
                             self.assertIn(tmp, config)
                         if 'soo' in rule_config['set']['extcommunity']:
                             values = ' '.join(rule_config['set']['extcommunity']['soo'])
                             tmp = f'set extcommunity soo {values}'
                             self.assertIn(tmp, config)
 
     def test_route_map(self):
         access_list = '50'
         as_path_list = '100'
         test_interface = 'eth0'
         community_list = 'BGP-comm-0815'
 
         # ext community name only allows alphanumeric characters and no hyphen :/
         # maybe change this if possible in vyos-1x rewrite
         extcommunity_list = 'BGPextcomm123'
 
         large_community_list = 'bgp-large-community-123456'
         prefix_list = 'foo-pfx-list'
         ipv6_nexthop_address = 'fe80::1'
         local_pref = '300'
         metric = '50'
         peer = '2.3.4.5'
         peerv6 = '2001:db8::1'
         tag = '6542'
         goto = '25'
 
         ipv4_nexthop_address= '192.0.2.2'
         ipv4_prefix_len= '18'
         ipv6_prefix_len= '122'
         ipv4_nexthop_type= 'blackhole'
         ipv6_nexthop_type= 'blackhole'
 
         test_data = {
             'foo-map-bar' : {
                 'rule' : {
                     '5' : {
                         'action' : 'permit',
                         'continue' : '20',
                     },
                     '10' : {
                         'action' : 'permit',
                         'call' : 'complicated-configuration',
                     },
                 },
             },
             'a-matching-rule-0815': {
                 'rule' : {
                     '5' : {
                         'action' : 'deny',
                         'match' : {
                             'as-path' : as_path_list,
                             'rpki-invalid': '',
                             'tag': tag,
                         },
                     },
                     '10' : {
                         'action' : 'permit',
                         'match' : {
                             'community' : community_list,
                             'interface' : test_interface,
                             'rpki-not-found': '',
                         },
                     },
                     '15' : {
                         'action' : 'permit',
                         'match' : {
                             'extcommunity' : extcommunity_list,
                             'rpki-valid': '',
                         },
                         'on-match' : {
                             'next' : '',
                         },
                     },
                     '20' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-address-acl': access_list,
                             'ip-nexthop-acl': access_list,
                             'ip-route-source-acl': access_list,
                             'ipv6-address-acl': access_list,
                             'origin-incomplete' : '',
                         },
                         'on-match' : {
                             'goto' : goto,
                         },
                     },
                     '25' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-address-pfx': prefix_list,
                             'ip-nexthop-pfx': prefix_list,
                             'ip-route-source-pfx': prefix_list,
                             'ipv6-address-pfx': prefix_list,
                             'origin-igp': '',
                         },
                     },
                     '30' : {
                         'action' : 'permit',
                         'match' : {
                             'ipv6-nexthop-address' : ipv6_nexthop_address,
                             'ipv6-nexthop-access-list' : access_list,
                             'ipv6-nexthop-prefix-list' : prefix_list,
                             'ipv6-nexthop-type' : ipv6_nexthop_type,
                             'ipv6-address-pfx-len' : ipv6_prefix_len,
                             'large-community' : large_community_list,
                             'local-pref' : local_pref,
                             'metric': metric,
                             'origin-egp': '',
                             'peer' : peer,
                         },
                     },
 
                     '31' : {
                         'action' : 'permit',
                         'match' : {
                             'peer' : peerv6,
                         },
                     },
 
                     '40' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-nexthop-addr' : ipv4_nexthop_address,
                             'ip-address-pfx-len' : ipv4_prefix_len,
                         },
                     },
                     '42' : {
                         'action' : 'deny',
                         'match' : {
                             'ip-nexthop-plen' : ipv4_prefix_len,
                         },
                     },
                     '44' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-nexthop-type' : ipv4_nexthop_type,
                         },
                     },
                 },
             },
             'complicated-configuration' : {
                 'rule' : {
                     '10' : {
                         'action' : 'deny',
                         'set' : {
                             'aggregator-as'           : '1234567890',
                             'aggregator-ip'           : '10.255.255.0',
                             'as-path-exclude'         : '1234',
                             'as-path-prepend'         : '1234567890 987654321',
                             'as-path-prepend-last-as' : '5',
                             'atomic-aggregate'        : '',
                             'distance'                : '110',
                             'ipv6-next-hop-global'    : '2001::1',
                             'ipv6-next-hop-local'     : 'fe80::1',
                             'ip-next-hop'             : '192.168.1.1',
                             'local-preference'        : '500',
                             'metric'                  : '150',
                             'metric-type'             : 'type-1',
                             'origin'                  : 'incomplete',
                             'l3vpn'                   : '',
                             'originator-id'           : '172.16.10.1',
                             'src'                     : '100.0.0.1',
                             'tag'                     : '65530',
                             'weight'                  : '2',
                         },
                     },
                 },
             },
             'bandwidth-configuration' : {
                 'rule' : {
                     '10' : {
                         'action' : 'deny',
                         'set' : {
                             'as-path-prepend'     : '100 100',
                             'distance'            : '200',
                             'extcommunity-bw'     : 'num-multipaths',
                         },
                     },
                 },
             },
             'evpn-configuration' : {
                 'rule' : {
                     '10' : {
                         'action' : 'permit',
                         'match' : {
                             'evpn-default-route'  : '',
                             'evpn-rd'             : '100:300',
                             'evpn-route-type'     : 'prefix',
                             'evpn-vni'            : '1234',
                         },
                     },
                     '20' : {
                         'action' : 'permit',
                         'set' : {
                             'as-path-exclude'     : 'all',
                             'evpn-gateway-ipv4'   : '192.0.2.99',
                             'evpn-gateway-ipv6'   : '2001:db8:f00::1',
                         },
                     },
                 },
             },
             'match-protocol' : {
                 'rule' : {
                     '10' : {
                         'action' : 'permit',
                         'match' : {
                             'protocol'  : 'static',
                         },
                     },
                     '20' : {
                         'action' : 'permit',
                         'match' : {
                             'protocol'   : 'bgp',
                         },
                     },
                 },
             },
             'relative-metric' : {
                 'rule' : {
                     '10' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-nexthop-addr' : ipv4_nexthop_address,
                         },
                         'set' : {
                             'metric' : '+10',
                         },
                     },
                     '20' : {
                         'action' : 'permit',
                         'match' : {
                             'ip-nexthop-addr' : ipv4_nexthop_address,
                         },
                         'set' : {
                             'metric' : '-20',
                         },
                     },
                     '30': {
                         'action': 'permit',
                         'match': {
                             'ip-nexthop-addr': ipv4_nexthop_address,
                         },
                         'set': {
                             'metric': 'rtt',
                         },
                     },
                     '40': {
                         'action': 'permit',
                         'match': {
                             'ip-nexthop-addr': ipv4_nexthop_address,
                         },
                         'set': {
                             'metric': '+rtt',
                         },
                     },
                     '50': {
                         'action': 'permit',
                         'match': {
                             'ip-nexthop-addr': ipv4_nexthop_address,
                         },
                         'set': {
                             'metric': '-rtt',
                         },
                     },
                 },
             },
         }
 
         self.cli_set(['policy', 'access-list', access_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'access-list', access_list, 'rule', '10', 'source', 'host', '1.1.1.1'])
         self.cli_set(['policy', 'access-list6', access_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'access-list6', access_list, 'rule', '10', 'source', 'network', '2001:db8::/32'])
 
         self.cli_set(['policy', 'as-path-list', as_path_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'as-path-list', as_path_list, 'rule', '10', 'regex', '64501 64502'])
         self.cli_set(['policy', 'community-list', community_list, 'rule', '10', 'action', 'deny'])
         self.cli_set(['policy', 'community-list', community_list, 'rule', '10', 'regex', '65432'])
         self.cli_set(['policy', 'extcommunity-list', extcommunity_list, 'rule', '10', 'action', 'deny'])
         self.cli_set(['policy', 'extcommunity-list', extcommunity_list, 'rule', '10', 'regex', '65000'])
         self.cli_set(['policy', 'large-community-list', large_community_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'large-community-list', large_community_list, 'rule', '10', 'regex', '100:200:300'])
 
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '10', 'prefix', '192.0.2.0/24'])
         self.cli_set(['policy', 'prefix-list6', prefix_list, 'rule', '10', 'action', 'permit'])
         self.cli_set(['policy', 'prefix-list6', prefix_list, 'rule', '10', 'prefix', '2001:db8::/32'])
 
         for route_map, route_map_config in test_data.items():
             path = base_path + ['route-map', route_map]
             self.cli_set(path + ['description', f'VyOS ROUTE-MAP {route_map}'])
             if 'rule' not in route_map_config:
                 continue
 
             for rule, rule_config in route_map_config['rule'].items():
                 if 'action' in rule_config:
                     self.cli_set(path + ['rule', rule, 'action', rule_config['action']])
 
                 if 'call' in rule_config:
                     self.cli_set(path + ['rule', rule, 'call', rule_config['call']])
 
                 if 'continue' in rule_config:
                     self.cli_set(path + ['rule', rule, 'continue', rule_config['continue']])
 
                 if 'match' in rule_config:
                     if 'as-path' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'as-path', rule_config['match']['as-path']])
                     if 'community' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'community', 'community-list', rule_config['match']['community']])
                         self.cli_set(path + ['rule', rule, 'match', 'community', 'exact-match'])
                     if 'evpn-default-route' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'evpn', 'default-route'])
                     if 'evpn-rd' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'evpn', 'rd', rule_config['match']['evpn-rd']])
                     if 'evpn-route-type' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'evpn', 'route-type', rule_config['match']['evpn-route-type']])
                     if 'evpn-vni' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'evpn', 'vni', rule_config['match']['evpn-vni']])
                     if 'extcommunity' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'extcommunity', rule_config['match']['extcommunity']])
                     if 'interface' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'interface', rule_config['match']['interface']])
                     if 'ip-address-acl' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'address', 'access-list', rule_config['match']['ip-address-acl']])
                     if 'ip-address-pfx' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'address', 'prefix-list', rule_config['match']['ip-address-pfx']])
                     if 'ip-address-pfx-len' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'address', 'prefix-len', rule_config['match']['ip-address-pfx-len']])
                     if 'ip-nexthop-acl' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'access-list', rule_config['match']['ip-nexthop-acl']])
                     if 'ip-nexthop-pfx' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'prefix-list', rule_config['match']['ip-nexthop-pfx']])
                     if 'ip-nexthop-addr' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'address', rule_config['match']['ip-nexthop-addr']])
                     if 'ip-nexthop-plen' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'prefix-len', rule_config['match']['ip-nexthop-plen']])
                     if 'ip-nexthop-type' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'nexthop', 'type', rule_config['match']['ip-nexthop-type']])
                     if 'ip-route-source-acl' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'route-source', 'access-list', rule_config['match']['ip-route-source-acl']])
                     if 'ip-route-source-pfx' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ip', 'route-source', 'prefix-list', rule_config['match']['ip-route-source-pfx']])
                     if 'ipv6-address-acl' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'access-list', rule_config['match']['ipv6-address-acl']])
                     if 'ipv6-address-pfx' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'prefix-list', rule_config['match']['ipv6-address-pfx']])
                     if 'ipv6-address-pfx-len' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'address', 'prefix-len', rule_config['match']['ipv6-address-pfx-len']])
                     if 'ipv6-nexthop-address' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'address', rule_config['match']['ipv6-nexthop-address']])
                     if 'ipv6-nexthop-access-list' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'access-list', rule_config['match']['ipv6-nexthop-access-list']])
                     if 'ipv6-nexthop-prefix-list' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'prefix-list', rule_config['match']['ipv6-nexthop-prefix-list']])
                     if 'ipv6-nexthop-type' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'ipv6', 'nexthop', 'type', rule_config['match']['ipv6-nexthop-type']])
                     if 'large-community' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'large-community', 'large-community-list', rule_config['match']['large-community']])
                     if 'local-pref' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'local-preference', rule_config['match']['local-pref']])
                     if 'metric' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'metric', rule_config['match']['metric']])
                     if 'origin-igp' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'origin', 'igp'])
                     if 'origin-egp' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'origin', 'egp'])
                     if 'origin-incomplete' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'origin', 'incomplete'])
                     if 'peer' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'peer', rule_config['match']['peer']])
                     if 'rpki-invalid' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'rpki', 'invalid'])
                     if 'rpki-not-found' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'rpki', 'notfound'])
                     if 'rpki-valid' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'rpki', 'valid'])
                     if 'protocol' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'protocol', rule_config['match']['protocol']])
                     if 'tag' in rule_config['match']:
                         self.cli_set(path + ['rule', rule, 'match', 'tag', rule_config['match']['tag']])
 
                 if 'on-match' in rule_config:
                     if 'goto' in rule_config['on-match']:
                         self.cli_set(path + ['rule', rule, 'on-match', 'goto', rule_config['on-match']['goto']])
                     if 'next' in rule_config['on-match']:
                         self.cli_set(path + ['rule', rule, 'on-match', 'next'])
 
                 if 'set' in rule_config:
                     if 'aggregator-as' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'aggregator', 'as', rule_config['set']['aggregator-as']])
                     if 'aggregator-ip' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'aggregator', 'ip', rule_config['set']['aggregator-ip']])
                     if 'as-path-exclude' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'as-path', 'exclude', rule_config['set']['as-path-exclude']])
                     if 'as-path-prepend' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'as-path', 'prepend', rule_config['set']['as-path-prepend']])
                     if 'atomic-aggregate' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'atomic-aggregate'])
                     if 'distance' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'distance', rule_config['set']['distance']])
                     if 'ipv6-next-hop-global' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'ipv6-next-hop', 'global', rule_config['set']['ipv6-next-hop-global']])
                     if 'ipv6-next-hop-local' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'ipv6-next-hop', 'local', rule_config['set']['ipv6-next-hop-local']])
                     if 'ip-next-hop' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'ip-next-hop', rule_config['set']['ip-next-hop']])
                     if 'l3vpn' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'l3vpn-nexthop', 'encapsulation', 'gre'])
                     if 'local-preference' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'local-preference', rule_config['set']['local-preference']])
                     if 'metric' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'metric', rule_config['set']['metric']])
                     if 'metric-type' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'metric-type', rule_config['set']['metric-type']])
                     if 'origin' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'origin', rule_config['set']['origin']])
                     if 'originator-id' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'originator-id', rule_config['set']['originator-id']])
                     if 'src' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'src', rule_config['set']['src']])
                     if 'tag' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'tag', rule_config['set']['tag']])
                     if 'weight' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'weight', rule_config['set']['weight']])
                     if 'evpn-gateway-ipv4' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'evpn', 'gateway', 'ipv4', rule_config['set']['evpn-gateway-ipv4']])
                     if 'evpn-gateway-ipv6' in rule_config['set']:
                         self.cli_set(path + ['rule', rule, 'set', 'evpn', 'gateway', 'ipv6', rule_config['set']['evpn-gateway-ipv6']])
 
         self.cli_commit()
 
         for route_map, route_map_config in test_data.items():
             if 'rule' not in route_map_config:
                 continue
             for rule, rule_config in route_map_config['rule'].items():
                 name = f'route-map {route_map} {rule_config["action"]} {rule}'
                 config = self.getFRRconfig(name)
                 self.assertIn(name, config)
 
                 if 'call' in rule_config:
                     tmp = 'call ' + rule_config['call']
                     self.assertIn(tmp, config)
 
                 if 'continue' in rule_config:
                     tmp = 'on-match goto ' + rule_config['continue']
                     self.assertIn(tmp, config)
 
                 if 'match' in rule_config:
                     if 'as-path' in rule_config['match']:
                         tmp = 'match as-path ' + rule_config['match']['as-path']
                         self.assertIn(tmp, config)
                     if 'community' in rule_config['match']:
                         tmp = f'match community {rule_config["match"]["community"]} exact-match'
                         self.assertIn(tmp, config)
                     if 'evpn-default-route' in rule_config['match']:
                         tmp = f'match evpn default-route'
                         self.assertIn(tmp, config)
                     if 'evpn-rd' in rule_config['match']:
                         tmp = f'match evpn rd {rule_config["match"]["evpn-rd"]}'
                         self.assertIn(tmp, config)
                     if 'evpn-route-type' in rule_config['match']:
                         tmp = f'match evpn route-type {rule_config["match"]["evpn-route-type"]}'
                         self.assertIn(tmp, config)
                     if 'evpn-vni' in rule_config['match']:
                         tmp = f'match evpn vni {rule_config["match"]["evpn-vni"]}'
                         self.assertIn(tmp, config)
                     if 'extcommunity' in rule_config['match']:
                         tmp = f'match extcommunity {rule_config["match"]["extcommunity"]}'
                         self.assertIn(tmp, config)
                     if 'interface' in rule_config['match']:
                         tmp = f'match interface {rule_config["match"]["interface"]}'
                         self.assertIn(tmp, config)
                     if 'ip-address-acl' in rule_config['match']:
                         tmp = f'match ip address {rule_config["match"]["ip-address-acl"]}'
                         self.assertIn(tmp, config)
                     if 'ip-address-pfx' in rule_config['match']:
                         tmp = f'match ip address prefix-list {rule_config["match"]["ip-address-pfx"]}'
                         self.assertIn(tmp, config)
                     if 'ip-address-pfx-len' in rule_config['match']:
                         tmp = f'match ip address prefix-len {rule_config["match"]["ip-address-pfx-len"]}'
                         self.assertIn(tmp, config)
                     if 'ip-nexthop-acl' in rule_config['match']:
                         tmp = f'match ip next-hop {rule_config["match"]["ip-nexthop-acl"]}'
                         self.assertIn(tmp, config)
                     if 'ip-nexthop-pfx' in rule_config['match']:
                         tmp = f'match ip next-hop prefix-list {rule_config["match"]["ip-nexthop-pfx"]}'
                         self.assertIn(tmp, config)
                     if 'ip-nexthop-addr' in rule_config['match']:
                         tmp = f'match ip next-hop address {rule_config["match"]["ip-nexthop-addr"]}'
                         self.assertIn(tmp, config)
                     if 'ip-nexthop-plen' in rule_config['match']:
                         tmp = f'match ip next-hop prefix-len {rule_config["match"]["ip-nexthop-plen"]}'
                         self.assertIn(tmp, config)
                     if 'ip-nexthop-type' in rule_config['match']:
                         tmp = f'match ip next-hop type {rule_config["match"]["ip-nexthop-type"]}'
                         self.assertIn(tmp, config)
                     if 'ip-route-source-acl' in rule_config['match']:
                         tmp = f'match ip route-source {rule_config["match"]["ip-route-source-acl"]}'
                         self.assertIn(tmp, config)
                     if 'ip-route-source-pfx' in rule_config['match']:
                         tmp = f'match ip route-source prefix-list {rule_config["match"]["ip-route-source-pfx"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-address-acl' in rule_config['match']:
                         tmp = f'match ipv6 address {rule_config["match"]["ipv6-address-acl"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-address-pfx' in rule_config['match']:
                         tmp = f'match ipv6 address prefix-list {rule_config["match"]["ipv6-address-pfx"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-address-pfx-len' in rule_config['match']:
                         tmp = f'match ipv6 address prefix-len {rule_config["match"]["ipv6-address-pfx-len"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-nexthop-address' in rule_config['match']:
                         tmp = f'match ipv6 next-hop address {rule_config["match"]["ipv6-nexthop-address"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-nexthop-access-list' in rule_config['match']:
                         tmp = f'match ipv6 next-hop {rule_config["match"]["ipv6-nexthop-access-list"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-nexthop-prefix-list' in rule_config['match']:
                         tmp = f'match ipv6 next-hop prefix-list {rule_config["match"]["ipv6-nexthop-prefix-list"]}'
                         self.assertIn(tmp, config)
                     if 'ipv6-nexthop-type' in rule_config['match']:
                         tmp = f'match ipv6 next-hop type {rule_config["match"]["ipv6-nexthop-type"]}'
                         self.assertIn(tmp, config)
                     if 'large-community' in rule_config['match']:
                         tmp = f'match large-community {rule_config["match"]["large-community"]}'
                         self.assertIn(tmp, config)
                     if 'local-pref' in rule_config['match']:
                         tmp = f'match local-preference {rule_config["match"]["local-pref"]}'
                         self.assertIn(tmp, config)
                     if 'metric' in rule_config['match']:
                         tmp = f'match metric {rule_config["match"]["metric"]}'
                         self.assertIn(tmp, config)
                     if 'origin-igp' in rule_config['match']:
                         tmp = f'match origin igp'
                         self.assertIn(tmp, config)
                     if 'origin-egp' in rule_config['match']:
                         tmp = f'match origin egp'
                         self.assertIn(tmp, config)
                     if 'origin-incomplete' in rule_config['match']:
                         tmp = f'match origin incomplete'
                         self.assertIn(tmp, config)
                     if 'peer' in rule_config['match']:
                         tmp = f'match peer {rule_config["match"]["peer"]}'
                         self.assertIn(tmp, config)
                     if 'protocol' in rule_config['match']:
                         tmp = f'match source-protocol {rule_config["match"]["protocol"]}'
                         self.assertIn(tmp, config)
                     if 'rpki-invalid' in rule_config['match']:
                         tmp = f'match rpki invalid'
                         self.assertIn(tmp, config)
                     if 'rpki-not-found' in rule_config['match']:
                         tmp = f'match rpki notfound'
                         self.assertIn(tmp, config)
                     if 'rpki-valid' in rule_config['match']:
                         tmp = f'match rpki valid'
                         self.assertIn(tmp, config)
                     if 'tag' in rule_config['match']:
                         tmp = f'match tag {rule_config["match"]["tag"]}'
                         self.assertIn(tmp, config)
 
                 if 'on-match' in rule_config:
                     if 'goto' in rule_config['on-match']:
                         tmp = f'on-match goto {rule_config["on-match"]["goto"]}'
                         self.assertIn(tmp, config)
                     if 'next' in rule_config['on-match']:
                         tmp = f'on-match next'
                         self.assertIn(tmp, config)
 
                 if 'set' in rule_config:
                     tmp = ' set '
                     if 'aggregator-as' in rule_config['set']:
                         tmp += 'aggregator as ' + rule_config['set']['aggregator-as']
                     elif 'aggregator-ip' in rule_config['set']:
                         tmp += ' ' + rule_config['set']['aggregator-ip']
                     elif 'as-path-exclude' in rule_config['set']:
                         tmp += 'as-path exclude ' + rule_config['set']['as-path-exclude']
                     elif 'as-path-prepend' in rule_config['set']:
                         tmp += 'as-path prepend ' + rule_config['set']['as-path-prepend']
                     elif 'as-path-prepend-last-as' in rule_config['set']:
                         tmp += 'as-path prepend last-as' + rule_config['set']['as-path-prepend-last-as']
                     elif 'atomic-aggregate' in rule_config['set']:
                         tmp += 'atomic-aggregate'
                     elif 'distance' in rule_config['set']:
                         tmp += 'distance ' + rule_config['set']['distance']
                     elif 'ip-next-hop' in rule_config['set']:
                         tmp += 'ip next-hop ' + rule_config['set']['ip-next-hop']
                     elif 'ipv6-next-hop-global' in rule_config['set']:
                         tmp += 'ipv6 next-hop global ' + rule_config['set']['ipv6-next-hop-global']
                     elif 'ipv6-next-hop-local' in rule_config['set']:
                         tmp += 'ipv6 next-hop local ' + rule_config['set']['ipv6-next-hop-local']
                     elif 'l3vpn' in rule_config['set']:
                         tmp += 'l3vpn next-hop encapsulation gre'
                     elif 'local-preference' in rule_config['set']:
                         tmp += 'local-preference ' + rule_config['set']['local-preference']
                     elif 'metric' in rule_config['set']:
                         tmp += 'metric ' + rule_config['set']['metric']
                     elif 'metric-type' in rule_config['set']:
                         tmp += 'metric-type ' + rule_config['set']['metric-type']
                     elif 'origin' in rule_config['set']:
                         tmp += 'origin ' + rule_config['set']['origin']
                     elif 'originator-id' in rule_config['set']:
                         tmp += 'originator-id ' + rule_config['set']['originator-id']
                     elif 'src' in rule_config['set']:
                         tmp += 'src ' + rule_config['set']['src']
                     elif 'tag' in rule_config['set']:
                         tmp += 'tag ' + rule_config['set']['tag']
                     elif 'weight' in rule_config['set']:
                         tmp += 'weight ' + rule_config['set']['weight']
                     elif 'vpn-gateway-ipv4' in rule_config['set']:
                         tmp += 'evpn gateway ipv4 ' + rule_config['set']['vpn-gateway-ipv4']
                     elif 'vpn-gateway-ipv6' in rule_config['set']:
                         tmp += 'evpn gateway ipv6 ' + rule_config['set']['vpn-gateway-ipv6']
 
                     self.assertIn(tmp, config)
 
 
     # Test set table for some sources
     def test_table_id(self):
         path = base_path + ['local-route']
 
         sources = ['203.0.113.1', '203.0.113.2']
         rule = '50'
         table = '23'
         for src in sources:
             self.cli_set(path + ['rule', rule, 'set', 'table', table])
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
 
         self.cli_commit()
 
         original = """
         50:	from 203.0.113.1 lookup 23
         50:	from 203.0.113.2 lookup 23
         """
         tmp = cmd('ip rule show prio 50')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for fwmark
     def test_fwmark_table_id(self):
         path = base_path + ['local-route']
 
         fwmk = '24'
         rule = '101'
         table = '154'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         101:    from all fwmark 0x18 lookup 154
         """
         tmp = cmd('ip rule show prio 101')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for destination
     def test_destination_table_id(self):
         path = base_path + ['local-route']
 
         dst = '203.0.113.1'
         rule = '102'
         table = '154'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
 
         self.cli_commit()
 
         original = """
         102:    from all to 203.0.113.1 lookup 154
         """
         tmp = cmd('ip rule show prio 102')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for destination and protocol
     def test_protocol_destination_table_id(self):
         path = base_path + ['local-route']
 
         dst = '203.0.113.12'
         rule = '85'
         table = '104'
         proto = 'tcp'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
         self.cli_set(path + ['rule', rule, 'protocol', proto])
 
         self.cli_commit()
 
         original = """
         85:	from all to 203.0.113.12 ipproto tcp lookup 104
         """
         tmp = cmd('ip rule show prio 85')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for destination, source, protocol, fwmark and port
     def test_protocol_port_address_fwmark_table_id(self):
         path = base_path + ['local-route']
 
         dst = '203.0.113.5'
         src_list = ['203.0.113.1', '203.0.113.2']
         rule = '23'
         fwmark = '123456'
         table = '123'
         new_table = '111'
         proto = 'udp'
         new_proto = 'tcp'
         src_port = '5555'
         dst_port = '8888'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
         self.cli_set(path + ['rule', rule, 'source', 'port', src_port])
         self.cli_set(path + ['rule', rule, 'protocol', proto])
         self.cli_set(path + ['rule', rule, 'fwmark', fwmark])
         self.cli_set(path + ['rule', rule, 'destination', 'port', dst_port])
         for src in src_list:
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
 
         self.cli_commit()
 
         original = """
         23:	from 203.0.113.1 to 203.0.113.5 fwmark 0x1e240 ipproto udp sport 5555 dport 8888 lookup 123
         23:	from 203.0.113.2 to 203.0.113.5 fwmark 0x1e240 ipproto udp sport 5555 dport 8888 lookup 123
         """
         tmp = cmd(f'ip rule show prio {rule}')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
         # Change table and protocol, delete fwmark and source port
         self.cli_delete(path + ['rule', rule, 'fwmark'])
         self.cli_delete(path + ['rule', rule, 'source', 'port'])
         self.cli_set(path + ['rule', rule, 'set', 'table', new_table])
         self.cli_set(path + ['rule', rule, 'protocol', new_proto])
 
         self.cli_commit()
 
         original = """
         23:	from 203.0.113.1 to 203.0.113.5 ipproto tcp dport 8888 lookup 111
         23:	from 203.0.113.2 to 203.0.113.5 ipproto tcp dport 8888 lookup 111
         """
         tmp = cmd(f'ip rule show prio {rule}')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources with fwmark
     def test_fwmark_sources_table_id(self):
         path = base_path + ['local-route']
 
         sources = ['203.0.113.11', '203.0.113.12']
         fwmk = '23'
         rule = '100'
         table = '150'
         for src in sources:
             self.cli_set(path + ['rule', rule, 'set', 'table', table])
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
             self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         100:	from 203.0.113.11 fwmark 0x17 lookup 150
         100:	from 203.0.113.12 fwmark 0x17 lookup 150
         """
         tmp = cmd('ip rule show prio 100')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources with iif
     def test_iif_sources_table_id(self):
         path = base_path + ['local-route']
 
         sources = ['203.0.113.11', '203.0.113.12']
         iif = 'lo'
         rule = '100'
         table = '150'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
         for src in sources:
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
 
         self.cli_commit()
 
         # Check generated configuration
         # Expected values
         original = """
         100:	from 203.0.113.11 iif lo lookup 150
         100:	from 203.0.113.12 iif lo lookup 150
         """
         tmp = cmd('ip rule show prio 100')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources and destinations with fwmark
     def test_fwmark_sources_destination_table_id(self):
         path = base_path + ['local-route']
 
         sources = ['203.0.113.11', '203.0.113.12']
         destinations = ['203.0.113.13', '203.0.113.15']
         fwmk = '23'
         rule = '103'
         table = '150'
         for src in sources:
             for dst in destinations:
                 self.cli_set(path + ['rule', rule, 'set', 'table', table])
                 self.cli_set(path + ['rule', rule, 'source', 'address', src])
                 self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
                 self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         103:	from 203.0.113.11 to 203.0.113.13 fwmark 0x17 lookup 150
         103:	from 203.0.113.11 to 203.0.113.15 fwmark 0x17 lookup 150
         103:	from 203.0.113.12 to 203.0.113.13 fwmark 0x17 lookup 150
         103:	from 203.0.113.12 to 203.0.113.15 fwmark 0x17 lookup 150
         """
         tmp = cmd('ip rule show prio 103')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table ipv6 for some sources ipv6
     def test_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         sources = ['2001:db8:123::/48', '2001:db8:126::/48']
         rule = '50'
         table = '23'
         for src in sources:
             self.cli_set(path + ['rule', rule, 'set', 'table', table])
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
 
         self.cli_commit()
 
         original = """
         50:	from 2001:db8:123::/48 lookup 23
         50:	from 2001:db8:126::/48 lookup 23
         """
         tmp = cmd('ip -6 rule show prio 50')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for fwmark ipv6
     def test_fwmark_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         fwmk = '24'
         rule = '100'
         table = '154'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         100:    from all fwmark 0x18 lookup 154
         """
         tmp = cmd('ip -6 rule show prio 100')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for destination ipv6
     def test_destination_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         dst = '2001:db8:1337::/126'
         rule = '101'
         table = '154'
 
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
 
         self.cli_commit()
 
         original = """
         101:    from all to 2001:db8:1337::/126 lookup 154
         """
         tmp = cmd('ip -6 rule show prio 101')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources with fwmark ipv6
     def test_fwmark_sources_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         sources = ['2001:db8:1338::/126', '2001:db8:1339::/126']
         fwmk = '23'
         rule = '102'
         table = '150'
         for src in sources:
             self.cli_set(path + ['rule', rule, 'set', 'table', table])
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
             self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         102:	from 2001:db8:1338::/126 fwmark 0x17 lookup 150
         102:	from 2001:db8:1339::/126 fwmark 0x17 lookup 150
         """
         tmp = cmd('ip -6 rule show prio 102')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources with iif ipv6
     def test_iif_sources_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         sources = ['2001:db8:1338::/126', '2001:db8:1339::/126']
         iif = 'lo'
         rule = '102'
         table = '150'
         for src in sources:
             self.cli_set(path + ['rule', rule, 'set', 'table', table])
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
             self.cli_set(path + ['rule', rule, 'inbound-interface', iif])
 
         self.cli_commit()
 
         # Check generated configuration
         # Expected values
         original = """
         102:	from 2001:db8:1338::/126 iif lo lookup 150
         102:	from 2001:db8:1339::/126 iif lo lookup 150
         """
         tmp = cmd('ip -6 rule show prio 102')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test set table for sources and destinations with fwmark ipv6
     def test_fwmark_sources_destination_ipv6_table_id(self):
         path = base_path + ['local-route6']
 
         sources = ['2001:db8:1338::/126', '2001:db8:1339::/56']
         destinations = ['2001:db8:13::/48', '2001:db8:16::/48']
         fwmk = '23'
         rule = '103'
         table = '150'
         for src in sources:
             for dst in destinations:
                 self.cli_set(path + ['rule', rule, 'set', 'table', table])
                 self.cli_set(path + ['rule', rule, 'source', 'address', src])
                 self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
                 self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         103:	from 2001:db8:1338::/126 to 2001:db8:13::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150
         """
         tmp = cmd('ip -6 rule show prio 103')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
 
     # Test delete table for sources and destination with fwmark ipv4/ipv6
     def test_delete_ipv4_ipv6_table_id(self):
         path = base_path + ['local-route']
         path_v6 = base_path + ['local-route6']
 
         sources = ['203.0.113.0/24', '203.0.114.5']
         destinations = ['203.0.112.0/24', '203.0.116.5']
         sources_v6 = ['2001:db8:1338::/126', '2001:db8:1339::/56']
         destinations_v6 = ['2001:db8:13::/48', '2001:db8:16::/48']
         fwmk = '23'
         rule = '103'
         table = '150'
         for src in sources:
             for dst in destinations:
                 self.cli_set(path + ['rule', rule, 'set', 'table', table])
                 self.cli_set(path + ['rule', rule, 'source', 'address', src])
                 self.cli_set(path + ['rule', rule, 'destination', 'address', dst])
                 self.cli_set(path + ['rule', rule, 'fwmark', fwmk])
 
         for src in sources_v6:
             for dst in destinations_v6:
                 self.cli_set(path_v6 + ['rule', rule, 'set', 'table', table])
                 self.cli_set(path_v6 + ['rule', rule, 'source', 'address', src])
                 self.cli_set(path_v6 + ['rule', rule, 'destination', 'address', dst])
                 self.cli_set(path_v6 + ['rule', rule, 'fwmark', fwmk])
 
         self.cli_commit()
 
         original = """
         103:	from 203.0.113.0/24 to 203.0.116.5 fwmark 0x17 lookup 150
         103:	from 203.0.114.5 to 203.0.112.0/24 fwmark 0x17 lookup 150
         103:	from 203.0.114.5 to 203.0.116.5 fwmark 0x17 lookup 150
         103:	from 203.0.113.0/24 to 203.0.112.0/24 fwmark 0x17 lookup 150
         """
         original_v6 = """
         103:	from 2001:db8:1338::/126 to 2001:db8:16::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1339::/56 to 2001:db8:13::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1339::/56 to 2001:db8:16::/48 fwmark 0x17 lookup 150
         103:	from 2001:db8:1338::/126 to 2001:db8:13::/48 fwmark 0x17 lookup 150
         """
         tmp = cmd('ip rule show prio 103')
         tmp_v6 = cmd('ip -6 rule show prio 103')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original))
         self.assertEqual(sort_ip(tmp_v6), sort_ip(original_v6))
 
         self.cli_delete(path)
         self.cli_delete(path_v6)
         self.cli_commit()
 
         tmp = cmd('ip rule show prio 103')
         tmp_v6 = cmd('ip -6 rule show prio 103')
 
         self.assertEqual(sort_ip(tmp), [])
         self.assertEqual(sort_ip(tmp_v6), [])
 
     # Test multiple commits ipv4
     def test_multiple_commit_ipv4_table_id(self):
         path = base_path + ['local-route']
 
         sources = ['192.0.2.1', '192.0.2.2']
         destination = '203.0.113.25'
         rule = '105'
         table = '151'
         self.cli_set(path + ['rule', rule, 'set', 'table', table])
         for src in sources:
             self.cli_set(path + ['rule', rule, 'source', 'address', src])
 
         self.cli_commit()
 
         original_first = """
         105:	from 192.0.2.1 lookup 151
         105:	from 192.0.2.2 lookup 151
         """
         tmp = cmd('ip rule show prio 105')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original_first))
 
         # Create second commit with added destination
         self.cli_set(path + ['rule', rule, 'destination', 'address', destination])
         self.cli_commit()
 
         original_second = """
         105:	from 192.0.2.1 to 203.0.113.25 lookup 151
         105:	from 192.0.2.2 to 203.0.113.25 lookup 151
         """
         tmp = cmd('ip rule show prio 105')
 
         self.assertEqual(sort_ip(tmp), sort_ip(original_second))
 
     def test_frr_individual_remove_T6283_T6250(self):
         path = base_path + ['route-map']
         route_maps = ['RMAP-1', 'RMAP_2']
         seq = '10'
         base_local_preference = 300
         base_table = 50
 
         # T6250
         local_preference = base_local_preference
         table = base_table
         for route_map in route_maps:
             self.cli_set(path + [route_map, 'rule', seq, 'action', 'permit'])
             self.cli_set(path + [route_map, 'rule', seq, 'set', 'table', str(table)])
             self.cli_set(path + [route_map, 'rule', seq, 'set', 'local-preference', str(local_preference)])
             local_preference += 20
             table += 5
 
         self.cli_commit()
 
         local_preference = base_local_preference
         table = base_table
         for route_map in route_maps:
             config = self.getFRRconfig(f'route-map {route_map} permit {seq}', end='', endsection='^exit')
             self.assertIn(f' set local-preference {local_preference}', config)
             self.assertIn(f' set table {table}', config)
             local_preference += 20
             table += 5
 
         for route_map in route_maps:
             self.cli_delete(path + [route_map, 'rule', '10', 'set', 'table'])
             # we explicitly commit multiple times to be as vandal as possible to the system
             self.cli_commit()
 
         local_preference = base_local_preference
         for route_map in route_maps:
             config = self.getFRRconfig(f'route-map {route_map} permit {seq}', end='', endsection='^exit')
             self.assertIn(f' set local-preference {local_preference}', config)
             local_preference += 20
 
         # T6283
         seq = '20'
         prepend = '100 100 100'
         for route_map in route_maps:
             self.cli_set(path + [route_map, 'rule', seq, 'action', 'permit'])
             self.cli_set(path + [route_map, 'rule', seq, 'set', 'as-path', 'prepend', prepend])
 
         self.cli_commit()
 
         for route_map in route_maps:
             config = self.getFRRconfig(f'route-map {route_map} permit {seq}', end='', endsection='^exit')
             self.assertIn(f' set as-path prepend {prepend}', config)
 
         for route_map in route_maps:
             self.cli_delete(path + [route_map, 'rule', seq, 'set'])
             # we explicitly commit multiple times to be as vandal as possible to the system
             self.cli_commit()
 
         for route_map in route_maps:
             config = self.getFRRconfig(f'route-map {route_map} permit {seq}', end='', endsection='^exit')
             self.assertNotIn(f' set', config)
 
 def sort_ip(output):
     o = '\n'.join([' '.join(line.strip().split()) for line in output.strip().splitlines()])
     o = o.splitlines()
     o.sort()
     return o
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_policy_local-route.py b/smoketest/scripts/cli/test_policy_local-route.py
index 8d6ba40dc..a4239b8a1 100644
--- a/smoketest/scripts/cli/test_policy_local-route.py
+++ b/smoketest/scripts/cli/test_policy_local-route.py
@@ -1,171 +1,174 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2024 VyOS maintainers and contributors
+# Copyright (C) 2024-2025 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 interface = 'eth0'
 mark = '100'
 table_id = '101'
 extra_table_id = '102'
 vrf_name = 'LPBRVRF'
 vrf_rt_id = '202'
 
 class TestPolicyLocalRoute(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestPolicyLocalRoute, cls).setUpClass()
         # Clear out current configuration to allow running this test on a live system
         cls.cli_delete(cls, ['policy', 'local-route'])
         cls.cli_delete(cls, ['policy', 'local-route6'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
         cls.cli_set(cls, ['vrf', 'name', vrf_name, 'table', vrf_rt_id])
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['vrf', 'name', vrf_name])
 
         super(TestPolicyLocalRoute, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(['policy', 'local-route'])
         self.cli_delete(['policy', 'local-route6'])
         self.cli_commit()
 
         ip_rule_search = [
             [f'lookup {table_id}']
         ]
 
         self.verify_rules(ip_rule_search, inverse=True)
         self.verify_rules(ip_rule_search, inverse=True, addr_family='inet6')
 
     def test_local_pbr_matching_criteria(self):
         self.cli_set(['policy', 'local-route', 'rule', '4', 'inbound-interface', interface])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'protocol', 'udp'])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'fwmark', mark])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'destination', 'address', '198.51.100.0/24'])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'destination', 'port', '111'])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'source', 'address', '198.51.100.1'])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'source', 'port', '443'])
         self.cli_set(['policy', 'local-route', 'rule', '4', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'inbound-interface', interface])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'protocol', 'tcp'])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'fwmark', mark])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'destination', 'address', '2001:db8::/64'])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'destination', 'port', '123'])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'source', 'address', '2001:db8::1'])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'source', 'port', '80'])
         self.cli_set(['policy', 'local-route6', 'rule', '6', 'set', 'table', table_id])
 
         self.cli_commit()
 
         rule_lookup = f'lookup {table_id}'
         rule_fwmark = 'fwmark ' + hex(int(mark))
         rule_interface = f'iif {interface}'
 
         ip4_rule_search = [
             ['from 198.51.100.1', 'to 198.51.100.0/24', rule_fwmark, rule_interface, 'ipproto udp', 'sport 443', 'dport 111', rule_lookup]
         ]
 
         self.verify_rules(ip4_rule_search)
 
         ip6_rule_search = [
             ['from 2001:db8::1', 'to 2001:db8::/64', rule_fwmark, rule_interface, 'ipproto tcp', 'sport 80', 'dport 123', rule_lookup]
         ]
 
         self.verify_rules(ip6_rule_search, addr_family='inet6')
 
     def test_local_pbr_rule_removal(self):
         self.cli_set(['policy', 'local-route', 'rule', '1', 'destination', 'address', '198.51.100.1'])
         self.cli_set(['policy', 'local-route', 'rule', '1', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'local-route', 'rule', '2', 'destination', 'address', '198.51.100.2'])
         self.cli_set(['policy', 'local-route', 'rule', '2', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'local-route', 'rule', '3', 'destination', 'address', '198.51.100.3'])
         self.cli_set(['policy', 'local-route', 'rule', '3', 'set', 'table', table_id])
 
         self.cli_commit()
 
         rule_lookup = f'lookup {table_id}'
 
         ip_rule_search = [
             ['to 198.51.100.1', rule_lookup],
             ['to 198.51.100.2', rule_lookup],
             ['to 198.51.100.3', rule_lookup],
         ]
 
         self.verify_rules(ip_rule_search)
 
         self.cli_delete(['policy', 'local-route', 'rule', '2'])
         self.cli_commit()
 
         ip_rule_missing = [
             ['to 198.51.100.2', rule_lookup],
         ]
 
         self.verify_rules(ip_rule_missing, inverse=True)
 
     def test_local_pbr_rule_changes(self):
         self.cli_set(['policy', 'local-route', 'rule', '1', 'destination', 'address', '198.51.100.0/24'])
         self.cli_set(['policy', 'local-route', 'rule', '1', 'set', 'table', table_id])
 
         self.cli_commit()
 
         self.cli_set(['policy', 'local-route', 'rule', '1', 'set', 'table', extra_table_id])
         self.cli_commit()
 
         ip_rule_search_extra = [
             ['to 198.51.100.0/24', f'lookup {extra_table_id}']
         ]
 
         self.verify_rules(ip_rule_search_extra)
 
         ip_rule_search_orig = [
             ['to 198.51.100.0/24', f'lookup {table_id}']
         ]
 
         self.verify_rules(ip_rule_search_orig, inverse=True)
 
         self.cli_delete(['policy', 'local-route', 'rule', '1', 'set', 'table'])
         self.cli_set(['policy', 'local-route', 'rule', '1', 'set', 'vrf', vrf_name])
 
         self.cli_commit()
 
         ip_rule_search_vrf = [
             ['to 198.51.100.0/24', f'lookup {vrf_name}']
         ]
 
         self.verify_rules(ip_rule_search_extra, inverse=True)
         self.verify_rules(ip_rule_search_vrf)
 
     def test_local_pbr_target_vrf(self):
         self.cli_set(['policy', 'local-route', 'rule', '1', 'destination', 'address', '198.51.100.0/24'])
         self.cli_set(['policy', 'local-route', 'rule', '1', 'set', 'vrf', vrf_name])
 
         self.cli_commit()
 
         ip_rule_search = [
             ['to 198.51.100.0/24', f'lookup {vrf_name}']
         ]
 
         self.verify_rules(ip_rule_search)
 
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py
index 672865eb0..53761b7d6 100755
--- a/smoketest/scripts/cli/test_policy_route.py
+++ b/smoketest/scripts/cli/test_policy_route.py
@@ -1,308 +1,311 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 mark = '100'
 conn_mark = '555'
 conn_mark_set = '111'
 table_mark_offset = 0x7fffffff
 table_id = '101'
 vrf = 'PBRVRF'
 vrf_table_id = '102'
 interface = 'eth0'
 interface_wc = 'ppp*'
 interface_ip = '172.16.10.1/24'
 
 class TestPolicyRoute(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestPolicyRoute, cls).setUpClass()
         # Clear out current configuration to allow running this test on a live system
         cls.cli_delete(cls, ['policy', 'route'])
         cls.cli_delete(cls, ['policy', 'route6'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
         cls.cli_set(cls, ['interfaces', 'ethernet', interface, 'address', interface_ip])
         cls.cli_set(cls, ['protocols', 'static', 'table', table_id, 'route', '0.0.0.0/0', 'interface', interface])
 
         cls.cli_set(cls, ['vrf', 'name', vrf, 'table', vrf_table_id])
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['interfaces', 'ethernet', interface, 'address', interface_ip])
         cls.cli_delete(cls, ['protocols', 'static', 'table', table_id])
         cls.cli_delete(cls, ['vrf', 'name', vrf])
 
         super(TestPolicyRoute, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(['policy', 'route'])
         self.cli_delete(['policy', 'route6'])
         self.cli_commit()
 
         # Verify nftables cleanup
         nftables_search = [
             ['set N_smoketest_network'],
             ['set N_smoketest_network1'],
             ['chain VYOS_PBR_smoketest']
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle', inverse=True)
 
         # Verify ip rule cleanup
         ip_rule_search = [
             ['fwmark ' + hex(table_mark_offset - int(table_id)), 'lookup ' + table_id]
         ]
 
         self.verify_rules(ip_rule_search, inverse=True)
 
     def test_pbr_group(self):
         self.cli_set(['firewall', 'group', 'network-group', 'smoketest_network', 'network', '172.16.99.0/24'])
         self.cli_set(['firewall', 'group', 'network-group', 'smoketest_network1', 'network', '172.16.101.0/24'])
         self.cli_set(['firewall', 'group', 'network-group', 'smoketest_network1', 'include', 'smoketest_network'])
 
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'group', 'network-group', 'smoketest_network1'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'mark', mark])
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
 
         self.cli_commit()
 
         nftables_search = [
             [f'iifname "{interface}"','jump VYOS_PBR_UD_smoketest'],
             ['ip daddr @N_smoketest_network1', 'ip saddr @N_smoketest_network'],
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
         self.cli_delete(['firewall'])
 
     def test_pbr_mark(self):
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'mark', mark])
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
 
         self.cli_commit()
 
         mark_hex = "{0:#010x}".format(int(mark))
 
         nftables_search = [
             [f'iifname "{interface}"','jump VYOS_PBR_UD_smoketest'],
             ['ip daddr 172.16.10.10', 'ip saddr 172.16.20.10', 'meta mark set ' + mark_hex],
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
     def test_pbr_mark_connection(self):
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'connection-mark', conn_mark])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'connection-mark', conn_mark_set])
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
 
         self.cli_commit()
 
         mark_hex = "{0:#010x}".format(int(conn_mark))
         mark_hex_set = "{0:#010x}".format(int(conn_mark_set))
 
         nftables_search = [
             [f'iifname "{interface}"','jump VYOS_PBR_UD_smoketest'],
             ['ip daddr 172.16.10.10', 'ip saddr 172.16.20.10', 'ct mark ' + mark_hex, 'ct mark set ' + mark_hex_set],
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
     def test_pbr_table(self):
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'port', '8888'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'syn'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'not', 'ack'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'table', table_id])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'tcp_udp'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'destination', 'port', '8888'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
         self.cli_set(['policy', 'route6', 'smoketest6', 'interface', interface])
 
         self.cli_commit()
 
         mark_hex = "{0:#010x}".format(table_mark_offset - int(table_id))
 
         # IPv4
 
         nftables_search = [
             [f'iifname "{interface}"', 'jump VYOS_PBR_UD_smoketest'],
             ['tcp flags syn / syn,ack', 'tcp dport 8888', 'meta mark set ' + mark_hex]
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
         # IPv6
 
         nftables6_search = [
             [f'iifname "{interface}"', 'jump VYOS_PBR6_UD_smoketest'],
             ['meta l4proto { tcp, udp }', 'th dport 8888', 'meta mark set ' + mark_hex]
         ]
 
         self.verify_nftables(nftables6_search, 'ip6 vyos_mangle')
 
         # IP rule fwmark -> table
 
         ip_rule_search = [
             ['fwmark ' + hex(table_mark_offset - int(table_id)), 'lookup ' + table_id]
         ]
 
         self.verify_rules(ip_rule_search)
 
 
     def test_pbr_vrf(self):
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'destination', 'port', '8888'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'syn'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'tcp', 'flags', 'not', 'ack'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'set', 'vrf', vrf])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'tcp_udp'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'destination', 'port', '8888'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'set', 'vrf', vrf])
 
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
         self.cli_set(['policy', 'route6', 'smoketest6', 'interface', interface])
 
         self.cli_commit()
 
         mark_hex = "{0:#010x}".format(table_mark_offset - int(vrf_table_id))
 
         # IPv4
 
         nftables_search = [
             [f'iifname "{interface}"', 'jump VYOS_PBR_UD_smoketest'],
             ['tcp flags syn / syn,ack', 'tcp dport 8888', 'meta mark set ' + mark_hex]
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
         # IPv6
 
         nftables6_search = [
             [f'iifname "{interface}"', 'jump VYOS_PBR6_UD_smoketest'],
             ['meta l4proto { tcp, udp }', 'th dport 8888', 'meta mark set ' + mark_hex]
         ]
 
         self.verify_nftables(nftables6_search, 'ip6 vyos_mangle')
 
         # IP rule fwmark -> table
 
         ip_rule_search = [
             ['fwmark ' + hex(table_mark_offset - int(vrf_table_id)), 'lookup ' + vrf]
         ]
 
         self.verify_rules(ip_rule_search)
 
 
     def test_pbr_matching_criteria(self):
         self.cli_set(['policy', 'route', 'smoketest', 'default-log'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'udp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'action', 'drop'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'mark', '2020'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'mark', '2-3000'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '2', 'set', 'table', table_id])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'source', 'address', '198.51.100.0/24'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'state', 'new'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'ttl', 'gt', '2'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'mark', '!456'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '3', 'set', 'table', table_id])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'protocol', 'icmp'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'icmp', 'type-name', 'echo-request'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'packet-length', '128'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'packet-length', '1024-2048'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'packet-type', 'other'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'log'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '4', 'set', 'table', table_id])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '41'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'dscp', '57-59'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'mark', '!456-500'])
         self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'route6', 'smoketest6', 'default-log'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'udp'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'action', 'drop'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'tcp', 'flags', 'syn'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'set', 'table', table_id])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'source', 'address', '2001:db8::0/64'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'protocol', 'tcp'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'destination', 'port', '22'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'state', 'new'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'hop-limit', 'gt', '2'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '3', 'set', 'table', table_id])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'protocol', 'icmpv6'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'icmpv6', 'type', 'echo-request'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'packet-length-exclude', '128'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'packet-length-exclude', '1024-2048'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'packet-type', 'multicast'])
 
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'log'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '4', 'set', 'table', table_id])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'dscp-exclude', '61'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'dscp-exclude', '14-19'])
         self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '5', 'set', 'table', table_id])
 
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface])
         self.cli_set(['policy', 'route', 'smoketest', 'interface', interface_wc])
         self.cli_set(['policy', 'route6', 'smoketest6', 'interface', interface_wc])
 
         self.cli_commit()
 
         mark_hex = "{0:#010x}".format(table_mark_offset - int(table_id))
 
         # IPv4
         nftables_search = [
             ['iifname { "' + interface + '", "' + interface_wc + '" }', 'jump VYOS_PBR_UD_smoketest'],
             ['meta l4proto udp', 'meta mark 0x000007e4', 'drop'],
             ['tcp flags syn / syn,ack', 'meta mark 0x00000002-0x00000bb8', 'meta mark set ' + mark_hex],
             ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark != 0x000001c8', 'meta mark set ' + mark_hex],
             ['log prefix "[ipv4-route-smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex],
             ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark != 0x000001c8-0x000001f4', 'meta mark set ' + mark_hex],
             ['log prefix "[ipv4-smoketest-default]"']
         ]
 
         self.verify_nftables(nftables_search, 'ip vyos_mangle')
 
         # IPv6
         nftables6_search = [
             [f'iifname "{interface_wc}"', 'jump VYOS_PBR6_UD_smoketest'],
             ['meta l4proto udp', 'drop'],
             ['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex],
             ['ct state new', 'tcp dport 22', 'ip6 saddr 2001:db8::/64', 'ip6 hoplimit > 2', 'meta mark set ' + mark_hex],
             ['log prefix "[ipv6-route6-smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex],
             ['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex],
             ['log prefix "[ipv6-smoketest6-default]"']
         ]
 
         self.verify_nftables(nftables6_search, 'ip6 vyos_mangle')
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_babel.py b/smoketest/scripts/cli/test_protocols_babel.py
index fa31722e5..7ecf54600 100755
--- a/smoketest/scripts/cli/test_protocols_babel.py
+++ b/smoketest/scripts/cli/test_protocols_babel.py
@@ -1,219 +1,222 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.ifconfig import Section
 from vyos.frrender import babel_daemon
 from vyos.utils.process import process_named_running
 from vyos.xml_ref import default_value
 
 base_path = ['protocols', 'babel']
 
 class TestProtocolsBABEL(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         cls._interfaces = Section.interfaces('ethernet', vlan=False)
         # call base-classes classmethod
         super(TestProtocolsBABEL, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(babel_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
         cls.cli_delete(cls, ['policy', 'prefix-list'])
         cls.cli_delete(cls, ['policy', 'prefix-list6'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         # always destroy the entire babel configuration to make the processes
         # life as hard as possible
         self.cli_delete(base_path)
         self.cli_delete(['policy', 'prefix-list'])
         self.cli_delete(['policy', 'prefix-list6'])
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(babel_daemon))
 
     def test_01_basic(self):
         diversity_factor = '64'
         resend_delay = '100'
         smoothing_half_life = '400'
 
         self.cli_set(base_path + ['parameters', 'diversity'])
         self.cli_set(base_path + ['parameters', 'diversity-factor', diversity_factor])
         self.cli_set(base_path + ['parameters', 'resend-delay', resend_delay])
         self.cli_set(base_path + ['parameters', 'smoothing-half-life', smoothing_half_life])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router babel', endsection='^exit')
         self.assertIn(f' babel diversity', frrconfig)
         self.assertIn(f' babel diversity-factor {diversity_factor}', frrconfig)
         self.assertIn(f' babel resend-delay {resend_delay}', frrconfig)
         self.assertIn(f' babel smoothing-half-life {smoothing_half_life}', frrconfig)
 
     def test_02_redistribute(self):
         ipv4_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'rip', 'static']
         ipv6_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospfv3', 'ripng', 'static']
 
         self.cli_set(base_path + ['interface', self._interfaces[0], 'enable-timestamps'])
 
         for protocol in ipv4_protos:
             self.cli_set(base_path + ['redistribute', 'ipv4', protocol])
         for protocol in ipv6_protos:
             self.cli_set(base_path + ['redistribute', 'ipv6', protocol])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router babel', endsection='^exit', empty_retry=5)
         for protocol in ipv4_protos:
             self.assertIn(f' redistribute ipv4 {protocol}', frrconfig)
         for protocol in ipv6_protos:
             if protocol == 'ospfv3':
                 protocol = 'ospf6'
             self.assertIn(f' redistribute ipv6 {protocol}', frrconfig)
 
     def test_03_distribute_list(self):
         access_list_in4 = '40'
         access_list_out4 = '50'
         access_list_in4_iface = '44'
         access_list_out4_iface = '55'
         access_list_in6 = 'AL-foo-in6'
         access_list_out6 = 'AL-foo-out6'
 
         prefix_list_in4 = 'PL-foo-in4'
         prefix_list_out4 = 'PL-foo-out4'
         prefix_list_in6 = 'PL-foo-in6'
         prefix_list_out6 = 'PL-foo-out6'
 
         self.cli_set(['policy', 'access-list', access_list_in4])
         self.cli_set(['policy', 'access-list', access_list_out4])
         self.cli_set(['policy', 'access-list6', access_list_in6])
         self.cli_set(['policy', 'access-list6', access_list_out6])
 
         self.cli_set(['policy', 'access-list', f'{access_list_in4_iface}'])
         self.cli_set(['policy', 'access-list', f'{access_list_out4_iface}'])
 
         self.cli_set(['policy', 'prefix-list', prefix_list_in4])
         self.cli_set(['policy', 'prefix-list', prefix_list_out4])
         self.cli_set(['policy', 'prefix-list6', prefix_list_in6])
         self.cli_set(['policy', 'prefix-list6', prefix_list_out6])
 
         self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'in', access_list_in4])
         self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'out', access_list_out4])
         self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'in', access_list_in6])
         self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'out', access_list_out6])
 
         self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'in', prefix_list_in4])
         self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'out', prefix_list_out4])
         self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'in', prefix_list_in6])
         self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'out', prefix_list_out6])
 
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface])
 
             self.cli_set(['policy', 'access-list6', f'{access_list_in6}-{interface}'])
             self.cli_set(['policy', 'access-list6', f'{access_list_out6}-{interface}'])
 
             self.cli_set(['policy', 'prefix-list', f'{prefix_list_in4}-{interface}'])
             self.cli_set(['policy', 'prefix-list', f'{prefix_list_out4}-{interface}'])
             self.cli_set(['policy', 'prefix-list6', f'{prefix_list_in6}-{interface}'])
             self.cli_set(['policy', 'prefix-list6', f'{prefix_list_out6}-{interface}'])
 
             tmp_path = base_path + ['distribute-list', 'ipv4', 'interface', interface]
             self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in4_iface}'])
             self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out4_iface}'])
             self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in4}-{interface}'])
             self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out4}-{interface}'])
 
             tmp_path = base_path + ['distribute-list', 'ipv6', 'interface', interface]
             self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in6}-{interface}'])
             self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out6}-{interface}'])
             self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in6}-{interface}'])
             self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out6}-{interface}'])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router babel', endsection='^exit')
         self.assertIn(f' distribute-list {access_list_in4} in', frrconfig)
         self.assertIn(f' distribute-list {access_list_out4} out', frrconfig)
         self.assertIn(f' ipv6 distribute-list {access_list_in6} in', frrconfig)
         self.assertIn(f' ipv6 distribute-list {access_list_out6} out', frrconfig)
 
         self.assertIn(f' distribute-list prefix {prefix_list_in4} in', frrconfig)
         self.assertIn(f' distribute-list prefix {prefix_list_out4} out', frrconfig)
         self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6} in', frrconfig)
         self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6} out', frrconfig)
 
         for interface in self._interfaces:
             self.assertIn(f' distribute-list {access_list_in4_iface} in {interface}', frrconfig)
             self.assertIn(f' distribute-list {access_list_out4_iface} out {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list {access_list_in6}-{interface} in {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list {access_list_out6}-{interface} out {interface}', frrconfig)
 
             self.assertIn(f' distribute-list prefix {prefix_list_in4}-{interface} in {interface}', frrconfig)
             self.assertIn(f' distribute-list prefix {prefix_list_out4}-{interface} out {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6}-{interface} in {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6}-{interface} out {interface}', frrconfig)
 
     def test_04_interfaces(self):
         def_update_interval = default_value(base_path + ['interface', 'eth0', 'update-interval'])
         channel = '20'
         hello_interval = '1000'
         max_rtt_penalty = '100'
         rtt_decay = '23'
         rtt_max = '119'
         rtt_min = '11'
         rxcost = '40000'
         type = 'wired'
 
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface])
             self.cli_set(base_path + ['interface', interface, 'channel', channel])
             self.cli_set(base_path + ['interface', interface, 'enable-timestamps'])
             self.cli_set(base_path + ['interface', interface, 'hello-interval', hello_interval])
             self.cli_set(base_path + ['interface', interface, 'max-rtt-penalty', max_rtt_penalty])
             self.cli_set(base_path + ['interface', interface, 'rtt-decay', rtt_decay])
             self.cli_set(base_path + ['interface', interface, 'rtt-max', rtt_max])
             self.cli_set(base_path + ['interface', interface, 'rtt-min', rtt_min])
             self.cli_set(base_path + ['interface', interface, 'rxcost', rxcost])
             self.cli_set(base_path + ['interface', interface, 'split-horizon', 'disable'])
             self.cli_set(base_path + ['interface', interface, 'type', type])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router babel', endsection='^exit')
         for interface in self._interfaces:
             self.assertIn(f' network {interface}', frrconfig)
 
             iface_config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f' babel channel {channel}', iface_config)
             self.assertIn(f' babel enable-timestamps', iface_config)
             self.assertIn(f' babel update-interval {def_update_interval}', iface_config)
             self.assertIn(f' babel hello-interval {hello_interval}', iface_config)
             self.assertIn(f' babel rtt-decay {rtt_decay}', iface_config)
             self.assertIn(f' babel rtt-max {rtt_max}', iface_config)
             self.assertIn(f' babel rtt-min {rtt_min}', iface_config)
             self.assertIn(f' babel rxcost {rxcost}', iface_config)
             self.assertIn(f' babel max-rtt-penalty {max_rtt_penalty}', iface_config)
             self.assertIn(f' no babel split-horizon', iface_config)
             self.assertIn(f' babel {type}', iface_config)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py
index f7ef3849f..2205cd9de 100755
--- a/smoketest/scripts/cli/test_protocols_bfd.py
+++ b/smoketest/scripts/cli/test_protocols_bfd.py
@@ -1,238 +1,243 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.frrender import bfd_daemon
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'bfd']
 
 dum_if = 'dum1001'
 vrf_name = 'red'
 peers = {
     '192.0.2.10' : {
         'intv_rx'    : '500',
         'intv_tx'    : '600',
         'multihop'   : '',
         'source_addr': '192.0.2.254',
         'profile'    : 'foo-bar-baz',
         'minimum_ttl': '20',
     },
     '192.0.2.20' : {
         'echo_mode'  : '',
         'intv_echo'  : '100',
         'intv_mult'  : '100',
         'intv_rx'    : '222',
         'intv_tx'    : '333',
         'passive'    : '',
         'shutdown'   : '',
         'profile'    : 'foo',
         'source_intf': dum_if,
     },
     '2001:db8::1000:1' : {
         'source_addr': '2001:db8::1',
         'vrf'        : vrf_name,
     },
     '2001:db8::2000:1' : {
         'source_addr': '2001:db8::1',
         'multihop'   : '',
         'profile'    : 'baz_foo',
     },
 }
 
 profiles = {
     'foo' : {
         'echo_mode'  : '',
         'intv_echo'  : '100',
         'intv_mult'  : '101',
         'intv_rx'    : '222',
         'intv_tx'    : '333',
         'shutdown'   : '',
         'minimum_ttl': '40',
         },
     'foo-bar-baz' : {
         'intv_mult'  : '4',
         'intv_rx'    : '400',
         'intv_tx'    : '400',
         },
     'baz_foo' : {
         'intv_mult'  : '102',
         'intv_rx'    : '444',
         'passive'    : '',
         },
 }
 
 class TestProtocolsBFD(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsBFD, cls).setUpClass()
 
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(bfd_daemon)
 
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
+
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(bfd_daemon))
 
     def test_bfd_peer(self):
         self.cli_set(['vrf', 'name', vrf_name, 'table', '1000'])
 
         for peer, peer_config in peers.items():
             if 'echo_mode' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'echo-mode'])
             if 'intv_echo' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'echo-interval', peer_config["intv_echo"]])
             if 'intv_mult' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'multiplier', peer_config["intv_mult"]])
             if 'intv_rx' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'receive', peer_config["intv_rx"]])
             if 'intv_tx' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'interval', 'transmit', peer_config["intv_tx"]])
             if 'minimum_ttl' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'minimum-ttl', peer_config["minimum_ttl"]])
             if 'multihop' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'multihop'])
             if 'passive' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'passive'])
             if 'shutdown' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'shutdown'])
             if 'source_addr' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
             if 'source_intf' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
             if 'vrf' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'vrf', peer_config["vrf"]])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig('bfd', endsection='^exit')
         for peer, peer_config in peers.items():
             tmp = f'peer {peer}'
             if 'multihop' in peer_config:
                 tmp += f' multihop'
             if 'source_addr' in peer_config:
                 tmp += f' local-address {peer_config["source_addr"]}'
             if 'source_intf' in peer_config:
                 tmp += f' interface {peer_config["source_intf"]}'
             if 'vrf' in peer_config:
                 tmp += f' vrf {peer_config["vrf"]}'
 
             self.assertIn(tmp, frrconfig)
             peerconfig = self.getFRRconfig('bfd', endsection='^exit', substring=f' peer {peer}',
                                            endsubsection='^ exit')
             if 'echo_mode' in peer_config:
                 self.assertIn(f'echo-mode', peerconfig)
             if 'intv_echo' in peer_config:
                 self.assertIn(f'echo receive-interval {peer_config["intv_echo"]}', peerconfig)
                 self.assertIn(f'echo transmit-interval {peer_config["intv_echo"]}', peerconfig)
             if 'intv_mult' in peer_config:
                 self.assertIn(f'detect-multiplier {peer_config["intv_mult"]}', peerconfig)
             if 'intv_rx' in peer_config:
                 self.assertIn(f'receive-interval {peer_config["intv_rx"]}', peerconfig)
             if 'intv_tx' in peer_config:
                 self.assertIn(f'transmit-interval {peer_config["intv_tx"]}', peerconfig)
             if 'minimum_ttl' in peer_config:
                 self.assertIn(f'minimum-ttl {peer_config["minimum_ttl"]}', peerconfig)
             if 'passive' in peer_config:
                 self.assertIn(f'passive-mode', peerconfig)
             if 'shutdown' in peer_config:
                 self.assertIn(f'shutdown', peerconfig)
             else:
                 self.assertNotIn(f'shutdown', peerconfig)
 
         self.cli_delete(['vrf', 'name', vrf_name])
 
     def test_bfd_profile(self):
         for profile, profile_config in profiles.items():
             if 'echo_mode' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'echo-mode'])
             if 'intv_echo' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'interval', 'echo-interval', profile_config["intv_echo"]])
             if 'intv_mult' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'interval', 'multiplier', profile_config["intv_mult"]])
             if 'intv_rx' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'interval', 'receive', profile_config["intv_rx"]])
             if 'intv_tx' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'interval', 'transmit', profile_config["intv_tx"]])
             if 'minimum_ttl' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'minimum-ttl', profile_config["minimum_ttl"]])
             if 'passive' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'passive'])
             if 'shutdown' in profile_config:
                 self.cli_set(base_path + ['profile', profile, 'shutdown'])
 
         for peer, peer_config in peers.items():
             if 'profile' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'profile', peer_config["profile"] + 'wrong'])
             if 'source_addr' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
             if 'source_intf' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
 
         # BFD profile does not exist!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         for peer, peer_config in peers.items():
             if 'profile' in peer_config:
                 self.cli_set(base_path + ['peer', peer, 'profile', peer_config["profile"]])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         for profile, profile_config in profiles.items():
             config = self.getFRRconfig('bfd', endsection='^exit',
                                        substring=f' profile {profile}', endsubsection='^ exit',)
             if 'echo_mode' in profile_config:
                 self.assertIn(f' echo-mode', config)
             if 'intv_echo' in profile_config:
                 self.assertIn(f' echo receive-interval {profile_config["intv_echo"]}', config)
                 self.assertIn(f' echo transmit-interval {profile_config["intv_echo"]}', config)
             if 'intv_mult' in profile_config:
                 self.assertIn(f' detect-multiplier {profile_config["intv_mult"]}', config)
             if 'intv_rx' in profile_config:
                 self.assertIn(f' receive-interval {profile_config["intv_rx"]}', config)
             if 'intv_tx' in profile_config:
                 self.assertIn(f' transmit-interval {profile_config["intv_tx"]}', config)
             if 'minimum_ttl' in profile_config:
                 self.assertIn(f' minimum-ttl {profile_config["minimum_ttl"]}', config)
             if 'passive' in profile_config:
                 self.assertIn(f' passive-mode', config)
             if 'shutdown' in profile_config:
                 self.assertIn(f' shutdown', config)
             else:
                 self.assertNotIn(f'shutdown', config)
 
         for peer, peer_config in peers.items():
             peerconfig = self.getFRRconfig('bfd', endsection='^exit',
                                            substring=f' peer {peer}', endsubsection='^ exit')
             if 'profile' in peer_config:
                 self.assertIn(f' profile {peer_config["profile"]}', peerconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index e5c8486f8..761eb8bfe 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -1,1432 +1,1436 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from time import sleep
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.ifconfig import Section
 from vyos.configsession import ConfigSessionError
 from vyos.template import is_ipv6
 from vyos.utils.process import process_named_running
 from vyos.utils.process import cmd
 from vyos.frrender import bgp_daemon
 
 ASN = '64512'
 base_path = ['protocols', 'bgp']
 
 route_map_in = 'foo-map-in'
 route_map_out = 'foo-map-out'
 prefix_list_in = 'pfx-foo-in'
 prefix_list_out = 'pfx-foo-out'
 prefix_list_in6 = 'pfx-foo-in6'
 prefix_list_out6 = 'pfx-foo-out6'
 bfd_profile = 'foo-bar-baz'
 
 import_afi = 'ipv4-unicast'
 import_vrf = 'red'
 import_rd = ASN + ':100'
 import_vrf_base = ['vrf', 'name']
 neighbor_config = {
     '192.0.2.1' : {
         'bfd'              : '',
         'cap_dynamic'      : '',
         'cap_ext_next'     : '',
         'cap_ext_sver'     : '',
         'remote_as'        : '100',
         'adv_interv'       : '400',
         'passive'          : '',
         'password'         : 'VyOS-Secure123',
         'shutdown'         : '',
         'cap_over'         : '',
         'ttl_security'     : '5',
         'system_as'        : '300',
         'route_map_in'     : route_map_in,
         'route_map_out'    : route_map_out,
         'no_send_comm_ext' : '',
         'addpath_all'      : '',
         'p_attr_discard'   : ['10', '20', '30', '40', '50'],
         },
     '192.0.2.2' : {
         'bfd_profile'      : bfd_profile,
         'remote_as'        : '200',
         'shutdown'         : '',
         'no_cap_nego'      : '',
         'port'             : '667',
         'cap_strict'       : '',
         'advertise_map'    : route_map_in,
         'non_exist_map'    : route_map_out,
         'pfx_list_in'      : prefix_list_in,
         'pfx_list_out'     : prefix_list_out,
         'no_send_comm_std' : '',
         'local_role'       : 'rs-client',
         'p_attr_taw'       : '200',
         },
     '192.0.2.3' : {
         'advertise_map'    : route_map_in,
         'description'      : 'foo bar baz',
         'remote_as'        : '200',
         'passive'          : '',
         'multi_hop'        : '5',
         'update_src'       : 'lo',
         'peer_group'       : 'foo',
         'graceful_rst'     : '',
         },
     '2001:db8::1' : {
         'advertise_map'    : route_map_in,
         'exist_map'        : route_map_out,
         'cap_dynamic'      : '',
         'cap_ext_next'     : '',
         'cap_ext_sver'     : '',
         'remote_as'        : '123',
         'adv_interv'       : '400',
         'passive'          : '',
         'password'         : 'VyOS-Secure123',
         'shutdown'         : '',
         'cap_over'         : '',
         'ttl_security'     : '5',
         'system_as'        : '300',
         'solo'             : '',
         'route_map_in'     : route_map_in,
         'route_map_out'    : route_map_out,
         'no_send_comm_std' : '',
         'addpath_per_as'   : '',
         'peer_group'       : 'foo-bar',
         'local_role'       : 'customer',
         'local_role_strict': '',
         },
     '2001:db8::2' : {
         'remote_as'        : '456',
         'shutdown'         : '',
         'no_cap_nego'      : '',
         'port'             : '667',
         'cap_strict'       : '',
         'pfx_list_in'      : prefix_list_in6,
         'pfx_list_out'     : prefix_list_out6,
         'no_send_comm_ext' : '',
         'peer_group'       : 'foo-bar_baz',
         'graceful_rst_hlp' : '',
         'disable_conn_chk' : '',
         },
 }
 
 peer_group_config = {
     'foo' : {
         'advertise_map'    : route_map_in,
         'exist_map'        : route_map_out,
         'bfd'              : '',
         'remote_as'        : '100',
         'passive'          : '',
         'password'         : 'VyOS-Secure123',
         'shutdown'         : '',
         'cap_over'         : '',
         'ttl_security'     : '5',
         'disable_conn_chk' : '',
         'p_attr_discard'   : ['100', '150', '200'],
         },
     'bar' : {
         'remote_as'        : '111',
         'graceful_rst_no'  : '',
         'port'             : '667',
         'p_attr_taw'       : '126',
         },
     'foo-bar' : {
         'advertise_map'    : route_map_in,
         'description'      : 'foo peer bar group',
         'remote_as'        : '200',
         'shutdown'         : '',
         'no_cap_nego'      : '',
         'system_as'        : '300',
         'pfx_list_in'      : prefix_list_in,
         'pfx_list_out'     : prefix_list_out,
         'no_send_comm_ext' : '',
         },
     'foo-bar_baz' : {
         'advertise_map'    : route_map_in,
         'non_exist_map'    : route_map_out,
         'bfd_profile'      : bfd_profile,
         'cap_dynamic'      : '',
         'cap_ext_next'     : '',
         'remote_as'        : '200',
         'passive'          : '',
         'multi_hop'        : '5',
         'update_src'       : 'lo',
         'route_map_in'     : route_map_in,
         'route_map_out'    : route_map_out,
         'local_role'       : 'peer',
         'local_role_strict': '',
         },
 }
 class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsBGP, cls).setUpClass()
 
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(bgp_daemon)
 
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
         cls.cli_delete(cls, ['policy', 'route-map'])
         cls.cli_delete(cls, ['policy', 'prefix-list'])
         cls.cli_delete(cls, ['policy', 'prefix-list6'])
         cls.cli_delete(cls, ['vrf'])
 
         cls.cli_set(cls, ['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '10', 'prefix', '192.0.2.0/25'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25'])
 
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64'])
 
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
+
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['policy', 'route-map'])
         cls.cli_delete(cls, ['policy', 'prefix-list'])
         cls.cli_delete(cls, ['policy', 'prefix-list6'])
 
     def setUp(self):
         self.cli_set(base_path + ['system-as', ASN])
 
     def tearDown(self):
         # cleanup any possible VRF mess
         self.cli_delete(['vrf'])
         # always destrox the entire bgpd configuration to make the processes
         # life as hard as possible
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router bgp', endsection='^exit')
         self.assertNotIn(f'router bgp', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(bgp_daemon))
 
     def create_bgp_instances_for_import_test(self):
         table = '1000'
         self.cli_set(import_vrf_base + [import_vrf, 'table', table])
         self.cli_set(import_vrf_base + [import_vrf, 'protocols', 'bgp', 'system-as', ASN])
 
     def verify_frr_config(self, peer, peer_config, frrconfig):
         # recurring patterns to verify for both a simple neighbor and a peer-group
         if 'bfd' in peer_config:
             self.assertIn(f' neighbor {peer} bfd', frrconfig)
         if 'bfd_profile' in peer_config:
             self.assertIn(f' neighbor {peer} bfd profile {peer_config["bfd_profile"]}', frrconfig)
             self.assertIn(f' neighbor {peer} bfd check-control-plane-failure', frrconfig)
         if 'cap_dynamic' in peer_config:
             self.assertIn(f' neighbor {peer} capability dynamic', frrconfig)
         if 'cap_ext_next' in peer_config:
             self.assertIn(f' neighbor {peer} capability extended-nexthop', frrconfig)
         if 'cap_ext_sver' in peer_config:
             self.assertIn(f' neighbor {peer} capability software-version', frrconfig)
         if 'description' in peer_config:
             self.assertIn(f' neighbor {peer} description {peer_config["description"]}', frrconfig)
         if 'no_cap_nego' in peer_config:
             self.assertIn(f' neighbor {peer} dont-capability-negotiate', frrconfig)
         if 'multi_hop' in peer_config:
             self.assertIn(f' neighbor {peer} ebgp-multihop {peer_config["multi_hop"]}', frrconfig)
         if 'local_as' in peer_config:
             self.assertIn(f' neighbor {peer} local-as {peer_config["local_as"]} no-prepend replace-as', frrconfig)
         if 'local_role' in peer_config:
             tmp = f' neighbor {peer} local-role {peer_config["local_role"]}'
             if 'local_role_strict' in peer_config:
                 tmp += ' strict'
             self.assertIn(tmp, frrconfig)
         if 'cap_over' in peer_config:
             self.assertIn(f' neighbor {peer} override-capability', frrconfig)
         if 'passive' in peer_config:
             self.assertIn(f' neighbor {peer} passive', frrconfig)
         if 'password' in peer_config:
             self.assertIn(f' neighbor {peer} password {peer_config["password"]}', frrconfig)
         if 'port' in peer_config:
             self.assertIn(f' neighbor {peer} port {peer_config["port"]}', frrconfig)
         if 'remote_as' in peer_config:
             self.assertIn(f' neighbor {peer} remote-as {peer_config["remote_as"]}', frrconfig)
         if 'solo' in peer_config:
             self.assertIn(f' neighbor {peer} solo', frrconfig)
         if 'shutdown' in peer_config:
             self.assertIn(f' neighbor {peer} shutdown', frrconfig)
         if 'ttl_security' in peer_config:
             self.assertIn(f' neighbor {peer} ttl-security hops {peer_config["ttl_security"]}', frrconfig)
         if 'update_src' in peer_config:
             self.assertIn(f' neighbor {peer} update-source {peer_config["update_src"]}', frrconfig)
         if 'route_map_in' in peer_config:
             self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_in"]} in', frrconfig)
         if 'route_map_out' in peer_config:
             self.assertIn(f' neighbor {peer} route-map {peer_config["route_map_out"]} out', frrconfig)
         if 'pfx_list_in' in peer_config:
             self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_in"]} in', frrconfig)
         if 'pfx_list_out' in peer_config:
             self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_out"]} out', frrconfig)
         if 'no_send_comm_std' in peer_config:
             self.assertIn(f' no neighbor {peer} send-community', frrconfig)
         if 'no_send_comm_ext' in peer_config:
             self.assertIn(f' no neighbor {peer} send-community extended', frrconfig)
         if 'addpath_all' in peer_config:
             self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig)
         if 'p_attr_discard' in peer_config:
             tmp = ' '.join(peer_config["p_attr_discard"])
             self.assertIn(f' neighbor {peer} path-attribute discard {tmp}', frrconfig)
         if 'p_attr_taw' in peer_config:
             self.assertIn(f' neighbor {peer} path-attribute treat-as-withdraw {peer_config["p_attr_taw"]}', frrconfig)
         if 'addpath_per_as' in peer_config:
             self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig)
         if 'advertise_map' in peer_config:
             base = f' neighbor {peer} advertise-map {peer_config["advertise_map"]}'
             if 'exist_map' in peer_config:
                 base = f'{base} exist-map {peer_config["exist_map"]}'
             if 'non_exist_map' in peer_config:
                 base = f'{base} non-exist-map {peer_config["non_exist_map"]}'
             self.assertIn(base, frrconfig)
         if 'graceful_rst' in peer_config:
             self.assertIn(f' neighbor {peer} graceful-restart', frrconfig)
         if 'graceful_rst_no' in peer_config:
             self.assertIn(f' neighbor {peer} graceful-restart-disable', frrconfig)
         if 'graceful_rst_hlp' in peer_config:
             self.assertIn(f' neighbor {peer} graceful-restart-helper', frrconfig)
         if 'disable_conn_chk' in peer_config:
             self.assertIn(f' neighbor {peer} disable-connected-check', frrconfig)
 
     def test_bgp_01_simple(self):
         router_id = '127.0.0.1'
         local_pref = '500'
         stalepath_time = '60'
         max_path_v4 = '2'
         max_path_v4ibgp = '4'
         max_path_v6 = '8'
         max_path_v6ibgp = '16'
         cond_adv_timer = '30'
         min_hold_time = '2'
         tcp_keepalive_idle = '66'
         tcp_keepalive_interval = '77'
         tcp_keepalive_probes = '22'
 
         self.cli_set(base_path + ['parameters', 'allow-martian-nexthop'])
         self.cli_set(base_path + ['parameters', 'disable-ebgp-connected-route-check'])
         self.cli_set(base_path + ['parameters', 'no-hard-administrative-reset'])
         self.cli_set(base_path + ['parameters', 'log-neighbor-changes'])
         self.cli_set(base_path + ['parameters', 'labeled-unicast', 'explicit-null'])
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
 
         # System AS number MUST be defined - as this is set in setUp() we remove
         # this once for testing of the proper error
         self.cli_delete(base_path + ['system-as'])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(base_path + ['system-as', ASN])
 
         # Default local preference (higher = more preferred, default value is 100)
         self.cli_set(base_path + ['parameters', 'default', 'local-pref', local_pref])
         self.cli_set(base_path + ['parameters', 'graceful-restart', 'stalepath-time', stalepath_time])
         self.cli_set(base_path + ['parameters', 'graceful-shutdown'])
         self.cli_set(base_path + ['parameters', 'ebgp-requires-policy'])
 
         self.cli_set(base_path + ['parameters', 'bestpath', 'as-path', 'multipath-relax'])
         self.cli_set(base_path + ['parameters', 'bestpath', 'bandwidth', 'default-weight-for-missing'])
         self.cli_set(base_path + ['parameters', 'bestpath', 'compare-routerid'])
         self.cli_set(base_path + ['parameters', 'bestpath', 'peer-type', 'multipath-relax'])
 
         self.cli_set(base_path + ['parameters', 'conditional-advertisement', 'timer', cond_adv_timer])
         self.cli_set(base_path + ['parameters', 'fast-convergence'])
         self.cli_set(base_path + ['parameters', 'minimum-holdtime', min_hold_time])
         self.cli_set(base_path + ['parameters', 'no-suppress-duplicates'])
         self.cli_set(base_path + ['parameters', 'reject-as-sets'])
         self.cli_set(base_path + ['parameters', 'route-reflector-allow-outbound-policy'])
         self.cli_set(base_path + ['parameters', 'shutdown'])
         self.cli_set(base_path + ['parameters', 'suppress-fib-pending'])
         self.cli_set(base_path + ['parameters', 'tcp-keepalive', 'idle', tcp_keepalive_idle])
         self.cli_set(base_path + ['parameters', 'tcp-keepalive', 'interval', tcp_keepalive_interval])
         self.cli_set(base_path + ['parameters', 'tcp-keepalive', 'probes', tcp_keepalive_probes])
 
         # AFI maximum path support
         self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4])
         self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp])
         self.cli_set(base_path + ['address-family', 'ipv4-labeled-unicast', 'maximum-paths', 'ebgp', max_path_v4])
         self.cli_set(base_path + ['address-family', 'ipv4-labeled-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp])
         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])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' bgp router-id {router_id}', frrconfig)
         self.assertIn(f' bgp allow-martian-nexthop', frrconfig)
         self.assertIn(f' bgp disable-ebgp-connected-route-check', frrconfig)
         self.assertIn(f' bgp log-neighbor-changes', frrconfig)
         self.assertIn(f' bgp default local-preference {local_pref}', frrconfig)
         self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig)
         self.assertIn(f' bgp fast-convergence', frrconfig)
         self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig)
         self.assertIn(f' bgp graceful-shutdown', frrconfig)
         self.assertIn(f' no bgp hard-administrative-reset', frrconfig)
         self.assertIn(f' bgp labeled-unicast explicit-null', frrconfig)
         self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig)
         self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig)
         self.assertIn(f' bgp bestpath compare-routerid', frrconfig)
         self.assertIn(f' bgp bestpath peer-type multipath-relax', frrconfig)
         self.assertIn(f' bgp minimum-holdtime {min_hold_time}', frrconfig)
         self.assertIn(f' bgp reject-as-sets', frrconfig)
         self.assertIn(f' bgp route-reflector allow-outbound-policy', frrconfig)
         self.assertIn(f' bgp shutdown', frrconfig)
         self.assertIn(f' bgp suppress-fib-pending', frrconfig)
         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)
 
         afiv4_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv4 unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  maximum-paths {max_path_v4}', afiv4_config)
         self.assertIn(f'  maximum-paths ibgp {max_path_v4ibgp}', afiv4_config)
 
         afiv4_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv4 labeled-unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  maximum-paths {max_path_v4}', afiv4_config)
         self.assertIn(f'  maximum-paths ibgp {max_path_v4ibgp}', afiv4_config)
 
         afiv6_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv6 unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  maximum-paths {max_path_v6}', afiv6_config)
         self.assertIn(f'  maximum-paths ibgp {max_path_v6ibgp}', afiv6_config)
 
     def test_bgp_02_neighbors(self):
         # Test out individual neighbor configuration items, not all of them are
         # also available to a peer-group!
         self.cli_set(base_path + ['parameters', 'deterministic-med'])
 
         for peer, peer_config in neighbor_config.items():
             afi = 'ipv4-unicast'
             if is_ipv6(peer):
                 afi = 'ipv6-unicast'
 
             if 'adv_interv' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'advertisement-interval', peer_config["adv_interv"]])
             if 'bfd' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'bfd'])
             if 'bfd_profile' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'bfd', 'profile', peer_config["bfd_profile"]])
                 self.cli_set(base_path + ['neighbor', peer, 'bfd', 'check-control-plane-failure'])
             if 'cap_dynamic' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'capability', 'dynamic'])
             if 'cap_ext_next' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'capability', 'extended-nexthop'])
             if 'cap_ext_sver' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'capability', 'software-version'])
             if 'description' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'description', peer_config["description"]])
             if 'no_cap_nego' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'disable-capability-negotiation'])
             if 'multi_hop' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'ebgp-multihop', peer_config["multi_hop"]])
             if 'local_as' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'local-as', peer_config["local_as"], 'no-prepend', 'replace-as'])
             if 'local_role' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'local-role', peer_config["local_role"]])
                 if 'local_role_strict' in peer_config:
                     self.cli_set(base_path + ['neighbor', peer, 'local-role', peer_config["local_role"], 'strict'])
             if 'cap_over' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'override-capability'])
             if 'passive' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'passive'])
             if 'password' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'password', peer_config["password"]])
             if 'port' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'port', peer_config["port"]])
             if 'remote_as' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'remote-as', peer_config["remote_as"]])
             if 'cap_strict' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'strict-capability-match'])
             if 'shutdown' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'shutdown'])
             if 'solo' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'solo'])
             if 'ttl_security' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'ttl-security', 'hops', peer_config["ttl_security"]])
             if 'update_src' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'update-source', peer_config["update_src"]])
             if 'p_attr_discard' in peer_config:
                 for attribute in peer_config['p_attr_discard']:
                     self.cli_set(base_path + ['neighbor', peer, 'path-attribute', 'discard', attribute])
             if 'p_attr_taw' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'path-attribute', 'treat-as-withdraw', peer_config["p_attr_taw"]])
             if 'route_map_in' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'import', peer_config["route_map_in"]])
             if 'route_map_out' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'export', peer_config["route_map_out"]])
             if 'pfx_list_in' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'import', peer_config["pfx_list_in"]])
             if 'pfx_list_out' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'export', peer_config["pfx_list_out"]])
             if 'no_send_comm_std' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'standard'])
             if 'no_send_comm_ext' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'extended'])
             if 'addpath_all' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-all'])
             if 'addpath_per_as' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as'])
             if 'graceful_rst' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'enable'])
             if 'graceful_rst_no' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'disable'])
             if 'graceful_rst_hlp' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'graceful-restart', 'restart-helper'])
             if 'disable_conn_chk' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'disable-connected-check'])
 
             # Conditional advertisement
             if 'advertise_map' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'advertise-map', peer_config["advertise_map"]])
                 # Either exist-map or non-exist-map needs to be specified
                 if 'exist_map' not in peer_config and 'non_exist_map' not in peer_config:
                     with self.assertRaises(ConfigSessionError):
                         self.cli_commit()
                     self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', route_map_in])
 
                 if 'exist_map' in peer_config:
                     self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'exist-map', peer_config["exist_map"]])
                 if 'non_exist_map' in peer_config:
                     self.cli_set(base_path + ['neighbor', peer, 'address-family', afi, 'conditionally-advertise', 'non-exist-map', peer_config["non_exist_map"]])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
 
         for peer, peer_config in neighbor_config.items():
             if 'adv_interv' in peer_config:
                 self.assertIn(f' neighbor {peer} advertisement-interval {peer_config["adv_interv"]}', frrconfig)
             if 'cap_strict' in peer_config:
                 self.assertIn(f' neighbor {peer} strict-capability-match', frrconfig)
 
             self.verify_frr_config(peer, peer_config, frrconfig)
 
     def test_bgp_03_peer_groups(self):
         # Test out individual peer-group configuration items
         for peer_group, config in peer_group_config.items():
             if 'bfd' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'bfd'])
             if 'bfd_profile' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'bfd', 'profile', config["bfd_profile"]])
                 self.cli_set(base_path + ['peer-group', peer_group, 'bfd', 'check-control-plane-failure'])
             if 'cap_dynamic' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'dynamic'])
             if 'cap_ext_next' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'extended-nexthop'])
             if 'cap_ext_sver' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'capability', 'software-version'])
             if 'description' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'description', config["description"]])
             if 'no_cap_nego' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'disable-capability-negotiation'])
             if 'multi_hop' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'ebgp-multihop', config["multi_hop"]])
             if 'local_as' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'local-as', config["local_as"], 'no-prepend', 'replace-as'])
             if 'local_role' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'local-role', config["local_role"]])
                 if 'local_role_strict' in config:
                     self.cli_set(base_path + ['peer-group', peer_group, 'local-role', config["local_role"], 'strict'])
             if 'cap_over' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'override-capability'])
             if 'passive' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'passive'])
             if 'password' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'password', config["password"]])
             if 'port' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'port', config["port"]])
             if 'remote_as' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'remote-as', config["remote_as"]])
             if 'shutdown' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'shutdown'])
             if 'ttl_security' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'ttl-security', 'hops', config["ttl_security"]])
             if 'update_src' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'update-source', config["update_src"]])
             if 'route_map_in' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]])
             if 'route_map_out' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]])
             if 'pfx_list_in' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]])
             if 'pfx_list_out' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]])
             if 'no_send_comm_std' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'standard'])
             if 'no_send_comm_ext' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'extended'])
             if 'addpath_all' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-all'])
             if 'addpath_per_as' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as'])
             if 'graceful_rst' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'enable'])
             if 'graceful_rst_no' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'disable'])
             if 'graceful_rst_hlp' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'graceful-restart', 'restart-helper'])
             if 'disable_conn_chk' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'disable-connected-check'])
             if 'p_attr_discard' in config:
                 for attribute in config['p_attr_discard']:
                     self.cli_set(base_path + ['peer-group', peer_group, 'path-attribute', 'discard', attribute])
             if 'p_attr_taw' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'path-attribute', 'treat-as-withdraw', config["p_attr_taw"]])
 
             # Conditional advertisement
             if 'advertise_map' in config:
                 self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'advertise-map', config["advertise_map"]])
                 # Either exist-map or non-exist-map needs to be specified
                 if 'exist_map' not in config and 'non_exist_map' not in config:
                     with self.assertRaises(ConfigSessionError):
                         self.cli_commit()
                     self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', route_map_in])
 
                 if 'exist_map' in config:
                     self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'exist-map', config["exist_map"]])
                 if 'non_exist_map' in config:
                     self.cli_set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'conditionally-advertise', 'non-exist-map', config["non_exist_map"]])
 
         for peer, peer_config in neighbor_config.items():
             if 'peer_group' in peer_config:
                 self.cli_set(base_path + ['neighbor', peer, 'peer-group', peer_config['peer_group']])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
 
         for peer, peer_config in peer_group_config.items():
             self.assertIn(f' neighbor {peer_group} peer-group', frrconfig)
             self.verify_frr_config(peer, peer_config, frrconfig)
 
         for peer, peer_config in neighbor_config.items():
             if 'peer_group' in peer_config:
                 self.assertIn(f' neighbor {peer} peer-group {peer_config["peer_group"]}', frrconfig)
 
     def test_bgp_04_afi_ipv4(self):
         networks = {
             '10.0.0.0/8' : {
                 'as_set' : '',
                 'summary_only' : '',
                 'route_map' : route_map_in,
                 },
             '100.64.0.0/10' : {
                 'as_set' : '',
                 },
             '192.168.0.0/16' : {
                 'summary_only' : '',
                 },
         }
 
         # We want to redistribute ...
         redistributes = ['connected', 'isis', 'kernel', 'ospf', 'rip', 'static']
         for redistribute in redistributes:
             self.cli_set(base_path + ['address-family', 'ipv4-unicast',
                                           'redistribute', redistribute])
 
         for network, network_config in networks.items():
             self.cli_set(base_path + ['address-family', 'ipv4-unicast',
                                           'network', network])
             if 'as_set' in network_config:
                 self.cli_set(base_path + ['address-family', 'ipv4-unicast',
                                               'aggregate-address', network, 'as-set'])
             if 'summary_only' in network_config:
                 self.cli_set(base_path + ['address-family', 'ipv4-unicast',
                                               'aggregate-address', network, 'summary-only'])
             if 'route_map' in network_config:
                 self.cli_set(base_path + ['address-family', 'ipv4-unicast',
                                               'aggregate-address', network, 'route-map', network_config['route_map']])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' address-family ipv4 unicast', frrconfig)
 
         for redistribute in redistributes:
             self.assertIn(f' redistribute {redistribute}', frrconfig)
 
         for network, network_config in networks.items():
             self.assertIn(f' network {network}', frrconfig)
             command = f'aggregate-address {network}'
             if 'as_set' in network_config:
                 command = f'{command} as-set'
             if 'summary_only' in network_config:
                 command = f'{command} summary-only'
             if 'route_map' in network_config:
                 command = f'{command} route-map {network_config["route_map"]}'
             self.assertIn(command, frrconfig)
 
     def test_bgp_05_afi_ipv6(self):
         networks = {
             '2001:db8:100::/48' : {
             },
             '2001:db8:200::/48' : {
             },
             '2001:db8:300::/48' : {
                 'summary_only' : '',
             },
         }
 
         # We want to redistribute ...
         redistributes = ['connected', 'kernel', 'ospfv3', 'ripng', 'static']
         for redistribute in redistributes:
             self.cli_set(base_path + ['address-family', 'ipv6-unicast',
                                           'redistribute', redistribute])
 
         for network, network_config in networks.items():
             self.cli_set(base_path + ['address-family', 'ipv6-unicast',
                                           'network', network])
             if 'summary_only' in network_config:
                 self.cli_set(base_path + ['address-family', 'ipv6-unicast',
                                               'aggregate-address', network, 'summary-only'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' address-family ipv6 unicast', frrconfig)
         # T2100: By default ebgp-requires-policy is disabled to keep VyOS
         # 1.3 and 1.2 backwards compatibility
         self.assertIn(f' no bgp ebgp-requires-policy', frrconfig)
 
         for redistribute in redistributes:
             # FRR calls this OSPF6
             if redistribute == 'ospfv3':
                 redistribute = 'ospf6'
             self.assertIn(f' redistribute {redistribute}', frrconfig)
 
         for network, network_config in networks.items():
             self.assertIn(f' network {network}', frrconfig)
             if 'as_set' in network_config:
                 self.assertIn(f' aggregate-address {network} summary-only', frrconfig)
 
     def test_bgp_06_listen_range(self):
         # Implemented via T1875
         limit = '64'
         listen_ranges = ['192.0.2.0/25', '192.0.2.128/25']
         peer_group = 'listenfoobar'
 
         self.cli_set(base_path + ['listen', 'limit', limit])
 
         for prefix in listen_ranges:
             self.cli_set(base_path + ['listen', 'range', prefix])
             # check validate() - peer-group must be defined for range/prefix
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
             self.cli_set(base_path + ['listen', 'range', prefix, 'peer-group', peer_group])
 
         # check validate() - peer-group does yet not exist!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(base_path + ['peer-group', peer_group, 'remote-as', ASN])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {peer_group} peer-group', frrconfig)
         self.assertIn(f' neighbor {peer_group} remote-as {ASN}', frrconfig)
         self.assertIn(f' bgp listen limit {limit}', frrconfig)
         for prefix in listen_ranges:
             self.assertIn(f' bgp listen range {prefix} peer-group {peer_group}', frrconfig)
 
     def test_bgp_07_l2vpn_evpn(self):
         vnis = ['10010', '10020', '10030']
         soo = '1.2.3.4:10000'
         evi_limit = '1000'
         route_targets = ['1.1.1.1:100', '1.1.1.1:200', '1.1.1.1:300']
 
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-all-vni'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-default-gw'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-svi-ip'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'flooding', 'disable'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'default-originate', 'ipv4'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'default-originate', 'ipv6'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'disable-ead-evi-rx'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'disable-ead-evi-tx'])
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'mac-vrf', 'soo', soo])
         for vni in vnis:
             self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-default-gw'])
             self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-svi-ip'])
 
         self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'ead-es-frag', 'evi-limit', evi_limit])
         for route_target in route_targets:
             self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'ead-es-route-target', 'export', route_target])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' address-family l2vpn evpn', frrconfig)
         self.assertIn(f'  advertise-all-vni', frrconfig)
         self.assertIn(f'  advertise-default-gw', frrconfig)
         self.assertIn(f'  advertise-svi-ip', frrconfig)
         self.assertIn(f'  default-originate ipv4', frrconfig)
         self.assertIn(f'  default-originate ipv6', frrconfig)
         self.assertIn(f'  disable-ead-evi-rx', frrconfig)
         self.assertIn(f'  disable-ead-evi-tx', frrconfig)
         self.assertIn(f'  flooding disable', frrconfig)
         self.assertIn(f'  mac-vrf soo {soo}', frrconfig)
         for vni in vnis:
             vniconfig = self.getFRRconfig(f'  vni {vni}', endsection='^  exit-vni')
             self.assertIn(f'vni {vni}', vniconfig)
             self.assertIn(f'   advertise-default-gw', vniconfig)
             self.assertIn(f'   advertise-svi-ip', vniconfig)
         self.assertIn(f'  ead-es-frag evi-limit {evi_limit}', frrconfig)
         for route_target in route_targets:
             self.assertIn(f'  ead-es-route-target export {route_target}', frrconfig)
 
 
     def test_bgp_09_distance_and_flowspec(self):
         distance_external = '25'
         distance_internal = '30'
         distance_local = '35'
         distance_v4_prefix = '169.254.0.0/32'
         distance_v6_prefix = '2001::/128'
         distance_prefix_value = '110'
         distance_families = ['ipv4-unicast', 'ipv6-unicast','ipv4-multicast', 'ipv6-multicast']
         verify_families = ['ipv4 unicast', 'ipv6 unicast','ipv4 multicast', 'ipv6 multicast']
         flowspec_families = ['address-family ipv4 flowspec', 'address-family ipv6 flowspec']
         flowspec_int = 'lo'
 
         # Per family distance support
         for family in distance_families:
             self.cli_set(base_path + ['address-family', family, 'distance', 'external', distance_external])
             self.cli_set(base_path + ['address-family', family, 'distance', 'internal', distance_internal])
             self.cli_set(base_path + ['address-family', family, 'distance', 'local', distance_local])
             if 'ipv4' in family:
                 self.cli_set(base_path + ['address-family', family, 'distance',
                                           'prefix', distance_v4_prefix, 'distance', distance_prefix_value])
             if 'ipv6' in family:
                 self.cli_set(base_path + ['address-family', family, 'distance',
                                           'prefix', distance_v6_prefix, 'distance', distance_prefix_value])
 
         # IPv4 flowspec interface check
         self.cli_set(base_path + ['address-family', 'ipv4-flowspec', 'local-install', 'interface', flowspec_int])
 
         # IPv6 flowspec interface check
         self.cli_set(base_path + ['address-family', 'ipv6-flowspec', 'local-install', 'interface', flowspec_int])
 
         # Commit changes
         self.cli_commit()
 
         # Verify FRR distances configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         for family in verify_families:
             self.assertIn(f'address-family {family}', frrconfig)
             self.assertIn(f'distance bgp {distance_external} {distance_internal} {distance_local}', frrconfig)
             if 'ipv4' in family:
                 self.assertIn(f'distance {distance_prefix_value} {distance_v4_prefix}', frrconfig)
             if 'ipv6' in family:
                 self.assertIn(f'distance {distance_prefix_value} {distance_v6_prefix}', frrconfig)
 
         # Verify FRR flowspec configuration
         for family in flowspec_families:
             self.assertIn(f'{family}', frrconfig)
             self.assertIn(f'local-install {flowspec_int}', frrconfig)
 
     def test_bgp_10_vrf_simple(self):
         router_id = '127.0.0.3'
         vrfs = ['red', 'green', 'blue']
 
         # It is safe to assume that when the basic VRF test works, all
         # other BGP related features work, as we entirely inherit the CLI
         # templates and Jinja2 FRR template.
         table = '1000'
 
         # testing only one AFI is sufficient as it's generic code
         for vrf in vrfs:
             vrf_base = ['vrf', 'name', vrf]
             self.cli_set(vrf_base + ['table', table])
             self.cli_set(vrf_base + ['protocols', 'bgp', 'system-as', ASN])
             self.cli_set(vrf_base + ['protocols', 'bgp', 'parameters', 'router-id', router_id])
             table = str(int(table) + 1000)
 
             # import VRF routes do main RIB
             self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'import', 'vrf', vrf])
 
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' address-family ipv6 unicast', frrconfig)
 
         for vrf in vrfs:
             self.assertIn(f'  import vrf {vrf}', frrconfig)
 
             # Verify FRR bgpd configuration
             frr_vrf_config = self.getFRRconfig(f'router bgp {ASN} vrf {vrf}', endsection='^exit')
             self.assertIn(f'router bgp {ASN} vrf {vrf}', frr_vrf_config)
             self.assertIn(f' bgp router-id {router_id}', frr_vrf_config)
 
     def test_bgp_11_confederation(self):
         router_id = '127.10.10.2'
         confed_id = str(int(ASN) + 1)
         confed_asns = '10 20 30 40'
 
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
         self.cli_set(base_path + ['parameters', 'confederation', 'identifier', confed_id])
         for asn in confed_asns.split():
             self.cli_set(base_path + ['parameters', 'confederation', 'peers', asn])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' bgp router-id {router_id}', frrconfig)
         self.assertIn(f' bgp confederation identifier {confed_id}', frrconfig)
         self.assertIn(f' bgp confederation peers {confed_asns}', frrconfig)
 
     def test_bgp_12_v6_link_local(self):
         remote_asn = str(int(ASN) + 10)
         interface = 'eth0'
 
         self.cli_set(base_path + ['neighbor', interface, 'address-family', 'ipv6-unicast'])
         self.cli_set(base_path + ['neighbor', interface, 'interface', 'v6only', 'remote-as', remote_asn])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {interface} interface v6only remote-as {remote_asn}', frrconfig)
         self.assertIn(f' address-family ipv6 unicast', frrconfig)
         self.assertIn(f'  neighbor {interface} activate', frrconfig)
         self.assertIn(f' exit-address-family', frrconfig)
 
     def test_bgp_13_vpn(self):
         remote_asn = str(int(ASN) + 150)
         neighbor = '192.0.2.55'
         vrf_name = 'red'
         label = 'auto'
         rd = f'{neighbor}:{ASN}'
         rt_export = f'{neighbor}:1002 1.2.3.4:567'
         rt_import = f'{neighbor}:1003 500:100'
 
         # testing only one AFI is sufficient as it's generic code
         for afi in ['ipv4-unicast', 'ipv6-unicast']:
             self.cli_set(base_path + ['address-family', afi, 'export', 'vpn'])
             self.cli_set(base_path + ['address-family', afi, 'import', 'vpn'])
             self.cli_set(base_path + ['address-family', afi, 'label', 'vpn', 'export', label])
             self.cli_set(base_path + ['address-family', afi, 'label', 'vpn', 'allocation-mode', 'per-nexthop'])
             self.cli_set(base_path + ['address-family', afi, 'rd', 'vpn', 'export', rd])
             self.cli_set(base_path + ['address-family', afi, 'route-map', 'vpn', 'export', route_map_out])
             self.cli_set(base_path + ['address-family', afi, 'route-map', 'vpn', 'import', route_map_in])
             self.cli_set(base_path + ['address-family', afi, 'route-target', 'vpn', 'export', rt_export])
             self.cli_set(base_path + ['address-family', afi, 'route-target', 'vpn', 'import', rt_import])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
 
         for afi in ['ipv4', 'ipv6']:
             afi_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                            substring=f' address-family {afi} unicast',
                                            endsubsection='^ exit-address-family')
             self.assertIn(f'address-family {afi} unicast', afi_config)
             self.assertIn(f'  export vpn', afi_config)
             self.assertIn(f'  import vpn', afi_config)
             self.assertIn(f'  label vpn export {label}', afi_config)
             self.assertIn(f'  label vpn export allocation-mode per-nexthop', afi_config)
             self.assertIn(f'  rd vpn export {rd}', afi_config)
             self.assertIn(f'  route-map vpn export {route_map_out}', afi_config)
             self.assertIn(f'  route-map vpn import {route_map_in}', afi_config)
             self.assertIn(f'  rt vpn export {rt_export}', afi_config)
             self.assertIn(f'  rt vpn import {rt_import}', afi_config)
             self.assertIn(f' exit-address-family', afi_config)
 
     def test_bgp_14_remote_as_peer_group_override(self):
         # Peer-group member cannot override remote-as of peer-group
         remote_asn = str(int(ASN) + 150)
         neighbor = '192.0.2.1'
         peer_group = 'bar'
         interface = 'eth0'
 
         self.cli_set(base_path + ['neighbor', neighbor, 'remote-as', remote_asn])
         self.cli_set(base_path + ['neighbor', neighbor, 'peer-group', peer_group])
         self.cli_set(base_path + ['peer-group', peer_group, 'remote-as', remote_asn])
 
         # Peer-group member cannot override remote-as of peer-group
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['neighbor', neighbor, 'remote-as'])
 
         # re-test with interface based peer-group
         self.cli_set(base_path + ['neighbor', interface, 'interface', 'peer-group', peer_group])
         self.cli_set(base_path + ['neighbor', interface, 'interface', 'remote-as', 'external'])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['neighbor', interface, 'interface', 'remote-as'])
 
         # re-test with interface based v6only peer-group
         self.cli_set(base_path + ['neighbor', interface, 'interface', 'v6only', 'peer-group', peer_group])
         self.cli_set(base_path + ['neighbor', interface, 'interface', 'v6only', 'remote-as', 'external'])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['neighbor', interface, 'interface', 'v6only', 'remote-as'])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {neighbor} peer-group {peer_group}', frrconfig)
         self.assertIn(f' neighbor {peer_group} peer-group', frrconfig)
         self.assertIn(f' neighbor {peer_group} remote-as {remote_asn}', frrconfig)
 
     def test_bgp_15_local_as_ebgp(self):
         # https://vyos.dev/T4560
         # local-as allowed only for ebgp peers
 
         neighbor = '192.0.2.99'
         remote_asn = '500'
         local_asn = '400'
 
         self.cli_set(base_path + ['neighbor', neighbor, 'remote-as', ASN])
         self.cli_set(base_path + ['neighbor', neighbor, 'local-as', local_asn])
 
         # check validate() - local-as allowed only for ebgp peers
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['neighbor', neighbor, 'remote-as', remote_asn])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {neighbor} remote-as {remote_asn}', frrconfig)
         self.assertIn(f' neighbor {neighbor} local-as {local_asn}', frrconfig)
 
     def test_bgp_16_import_rd_rt_compatibility(self):
         # Verify if import vrf and rd vpn export
         # exist in the same address family
         self.create_bgp_instances_for_import_test()
         self.cli_set(
             base_path + ['address-family', import_afi, 'import', 'vrf',
                          import_vrf])
         self.cli_set(
             base_path + ['address-family', import_afi, 'rd', 'vpn', 'export',
                          import_rd])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_17_import_rd_rt_compatibility(self):
         # Verify if vrf that is in import vrf list contains rd vpn export
         self.create_bgp_instances_for_import_test()
         self.cli_set(
             base_path + ['address-family', import_afi, 'import', 'vrf',
                          import_vrf])
         self.cli_commit()
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         frrconfig_vrf = self.getFRRconfig(f'router bgp {ASN} vrf {import_vrf}', endsection='^exit')
 
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f'address-family ipv4 unicast', frrconfig)
         self.assertIn(f'  import vrf {import_vrf}', frrconfig)
         self.assertIn(f'router bgp {ASN} vrf {import_vrf}', frrconfig_vrf)
 
         self.cli_set(
             import_vrf_base + [import_vrf] + base_path + ['address-family',
                                                           import_afi, 'rd',
                                                           'vpn', 'export',
                                                           import_rd])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_18_deleting_import_vrf(self):
         # Verify deleting vrf that is in import vrf list
         self.create_bgp_instances_for_import_test()
         self.cli_set(
             base_path + ['address-family', import_afi, 'import', 'vrf',
                          import_vrf])
         self.cli_commit()
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         frrconfig_vrf = self.getFRRconfig(f'router bgp {ASN} vrf {import_vrf}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f'address-family ipv4 unicast', frrconfig)
         self.assertIn(f'  import vrf {import_vrf}', frrconfig)
         self.assertIn(f'router bgp {ASN} vrf {import_vrf}', frrconfig_vrf)
         self.cli_delete(import_vrf_base + [import_vrf])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_19_deleting_default_vrf(self):
         # Verify deleting existent vrf default if other vrfs were created
         self.create_bgp_instances_for_import_test()
         self.cli_commit()
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         frrconfig_vrf = self.getFRRconfig(f'router bgp {ASN} vrf {import_vrf}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f'router bgp {ASN} vrf {import_vrf}', frrconfig_vrf)
         self.cli_delete(base_path)
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_20_import_rd_rt_compatibility(self):
         # Verify if vrf that has rd vpn export is in import vrf of other vrfs
         self.create_bgp_instances_for_import_test()
         self.cli_set(
             import_vrf_base + [import_vrf] + base_path + ['address-family',
                                                           import_afi, 'rd',
                                                           'vpn', 'export',
                                                           import_rd])
         self.cli_commit()
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         frrconfig_vrf = self.getFRRconfig(f'router bgp {ASN} vrf {import_vrf}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f'router bgp {ASN} vrf {import_vrf}', frrconfig_vrf)
         self.assertIn(f'address-family ipv4 unicast', frrconfig_vrf)
         self.assertIn(f'  rd vpn export {import_rd}', frrconfig_vrf)
 
         self.cli_set(
             base_path + ['address-family', import_afi, 'import', 'vrf',
                          import_vrf])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_21_import_unspecified_vrf(self):
         # Verify if vrf that is in import is unspecified
         self.create_bgp_instances_for_import_test()
         self.cli_set(
             base_path + ['address-family', import_afi, 'import', 'vrf',
                          'test'])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_bgp_22_interface_mpls_forwarding(self):
         interfaces = Section.interfaces('ethernet', vlan=False)
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'mpls', 'forwarding'])
 
         self.cli_commit()
 
         for interface in interfaces:
             frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', frrconfig)
             self.assertIn(f' mpls bgp forwarding', frrconfig)
 
     def test_bgp_23_vrf_interface_mpls_forwarding(self):
         self.create_bgp_instances_for_import_test()
         interfaces = Section.interfaces('ethernet', vlan=False)
         for interface in interfaces:
             self.cli_set(['interfaces', 'ethernet', interface, 'vrf', import_vrf])
             self.cli_set(import_vrf_base + [import_vrf] + base_path + ['interface', interface, 'mpls', 'forwarding'])
 
         self.cli_commit()
 
         for interface in interfaces:
             frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', frrconfig)
             self.assertIn(f' mpls bgp forwarding', frrconfig)
             self.cli_delete(['interfaces', 'ethernet', interface, 'vrf'])
 
     def test_bgp_24_srv6_sid(self):
         locator_name = 'VyOS_foo'
         sid = 'auto'
         nexthop_ipv4 = '192.0.0.1'
         nexthop_ipv6 = '2001:db8:100:200::2'
 
         self.cli_set(base_path + ['srv6', 'locator', locator_name])
         self.cli_set(base_path + ['sid', 'vpn', 'per-vrf', 'export', sid])
         self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid])
         # verify() - SID per VRF and SID per address-family are mutually exclusive!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['address-family', 'ipv4-unicast', 'sid'])
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' segment-routing srv6', frrconfig)
         self.assertIn(f'  locator {locator_name}', frrconfig)
         self.assertIn(f' sid vpn per-vrf export {sid}', frrconfig)
 
         # Now test AFI SID
         self.cli_delete(base_path + ['sid'])
         self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid])
         self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv4])
         self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'sid', 'vpn', 'export', sid])
         self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv6])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' segment-routing srv6', frrconfig)
         self.assertIn(f'  locator {locator_name}', frrconfig)
 
         afiv4_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv4 unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f' sid vpn export {sid}', afiv4_config)
         self.assertIn(f' nexthop vpn export {nexthop_ipv4}', afiv4_config)
 
         afiv6_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv6 unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f' sid vpn export {sid}', afiv6_config)
         self.assertIn(f' nexthop vpn export {nexthop_ipv6}', afiv6_config)
 
     def test_bgp_25_ipv4_labeled_unicast_peer_group(self):
         pg_ipv4 = 'foo4'
         ipv4_max_prefix = '20'
         ipv4_prefix = '192.0.2.0/24'
 
         self.cli_set(base_path + ['listen', 'range', ipv4_prefix, 'peer-group', pg_ipv4])
         self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv4-explicit-null'])
         self.cli_set(base_path + ['peer-group', pg_ipv4, 'address-family', 'ipv4-labeled-unicast', 'maximum-prefix', ipv4_max_prefix])
         self.cli_set(base_path + ['peer-group', pg_ipv4, 'remote-as', 'external'])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {pg_ipv4} peer-group', frrconfig)
         self.assertIn(f' neighbor {pg_ipv4} remote-as external', frrconfig)
         self.assertIn(f' bgp listen range {ipv4_prefix} peer-group {pg_ipv4}', frrconfig)
         self.assertIn(f' bgp labeled-unicast ipv4-explicit-null', frrconfig)
 
         afiv4_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv4 labeled-unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  neighbor {pg_ipv4} activate', afiv4_config)
         self.assertIn(f'  neighbor {pg_ipv4} maximum-prefix {ipv4_max_prefix}', afiv4_config)
 
     def test_bgp_26_ipv6_labeled_unicast_peer_group(self):
         pg_ipv6 = 'foo6'
         ipv6_max_prefix = '200'
         ipv6_prefix = '2001:db8:1000::/64'
 
         self.cli_set(base_path + ['listen', 'range', ipv6_prefix, 'peer-group', pg_ipv6])
         self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv6-explicit-null'])
 
         self.cli_set(base_path + ['peer-group', pg_ipv6, 'address-family', 'ipv6-labeled-unicast', 'maximum-prefix', ipv6_max_prefix])
         self.cli_set(base_path + ['peer-group', pg_ipv6, 'remote-as', 'external'])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'router bgp {ASN}', frrconfig)
         self.assertIn(f' neighbor {pg_ipv6} peer-group', frrconfig)
         self.assertIn(f' neighbor {pg_ipv6} remote-as external', frrconfig)
         self.assertIn(f' bgp listen range {ipv6_prefix} peer-group {pg_ipv6}', frrconfig)
         self.assertIn(f' bgp labeled-unicast ipv6-explicit-null', frrconfig)
 
         afiv6_config = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                          substring=' address-family ipv6 labeled-unicast',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  neighbor {pg_ipv6} activate', afiv6_config)
         self.assertIn(f'  neighbor {pg_ipv6} maximum-prefix {ipv6_max_prefix}', afiv6_config)
 
     def test_bgp_27_route_reflector_client(self):
         self.cli_set(base_path + ['peer-group', 'peer1', 'address-family', 'l2vpn-evpn', 'route-reflector-client'])
         with self.assertRaises(ConfigSessionError) as e:
             self.cli_commit()
 
         self.cli_set(base_path + ['peer-group', 'peer1', 'remote-as', 'internal'])
         self.cli_commit()
 
         conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit',
                                  substring=' address-family l2vpn evpn', endsubsection='^ exit-address-family')
 
         self.assertIn('neighbor peer1 route-reflector-client', conf)
 
     def test_bgp_28_peer_group_member_all_internal_or_external(self):
         def _common_config_check(conf, include_ras=True):
             if include_ras:
                 self.assertIn(f'neighbor {int_neighbors[0]} remote-as {ASN}', conf)
                 self.assertIn(f'neighbor {int_neighbors[1]} remote-as {ASN}', conf)
                 self.assertIn(f'neighbor {ext_neighbors[0]} remote-as {int(ASN) + 1}',conf)
 
             self.assertIn(f'neighbor {int_neighbors[0]} peer-group {int_pg_name}', conf)
             self.assertIn(f'neighbor {int_neighbors[1]} peer-group {int_pg_name}', conf)
             self.assertIn(f'neighbor {ext_neighbors[0]} peer-group {ext_pg_name}', conf)
 
         int_neighbors = ['192.0.2.2', '192.0.2.3']
         ext_neighbors = ['192.122.2.2', '192.122.2.3']
         int_pg_name, ext_pg_name = 'SMOKETESTINT', 'SMOKETESTEXT'
 
         self.cli_set(base_path + ['neighbor', int_neighbors[0], 'peer-group', int_pg_name])
         self.cli_set(base_path + ['neighbor', int_neighbors[0], 'remote-as', ASN])
         self.cli_set(base_path + ['peer-group', int_pg_name, 'address-family', 'ipv4-unicast'])
         self.cli_set(base_path + ['neighbor', ext_neighbors[0], 'peer-group', ext_pg_name])
         self.cli_set(base_path + ['neighbor', ext_neighbors[0], 'remote-as', f'{int(ASN) + 1}'])
         self.cli_set(base_path + ['peer-group', ext_pg_name, 'address-family', 'ipv4-unicast'])
         self.cli_commit()
 
         # test add external remote-as to internal group
         self.cli_set(base_path + ['neighbor', int_neighbors[1], 'peer-group', int_pg_name])
         self.cli_set(base_path + ['neighbor', int_neighbors[1], 'remote-as', f'{int(ASN) + 1}'])
 
         with self.assertRaises(ConfigSessionError) as e:
             self.cli_commit()
         # self.assertIn('\nPeer-group members must be all internal or all external\n', str(e.exception))
 
         # test add internal remote-as to internal group
         self.cli_set(base_path + ['neighbor', int_neighbors[1], 'remote-as', ASN])
         self.cli_commit()
 
         conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         _common_config_check(conf)
 
         # test add internal remote-as to external group
         self.cli_set(base_path + ['neighbor', ext_neighbors[1], 'peer-group', ext_pg_name])
         self.cli_set(base_path + ['neighbor', ext_neighbors[1], 'remote-as', ASN])
 
         with self.assertRaises(ConfigSessionError) as e:
             self.cli_commit()
         # self.assertIn('\nPeer-group members must be all internal or all external\n', str(e.exception))
 
         # test add external remote-as to external group
         self.cli_set(base_path + ['neighbor', ext_neighbors[1], 'remote-as', f'{int(ASN) + 2}'])
         self.cli_commit()
 
         conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         _common_config_check(conf)
         self.assertIn(f'neighbor {ext_neighbors[1]} remote-as {int(ASN) + 2}', conf)
         self.assertIn(f'neighbor {ext_neighbors[1]} peer-group {ext_pg_name}', conf)
 
         # test named remote-as
         self.cli_set(base_path + ['neighbor', int_neighbors[0], 'remote-as', 'internal'])
         self.cli_set(base_path + ['neighbor', int_neighbors[1], 'remote-as', 'internal'])
         self.cli_set(base_path + ['neighbor', ext_neighbors[0], 'remote-as', 'external'])
         self.cli_set(base_path + ['neighbor', ext_neighbors[1], 'remote-as', 'external'])
         self.cli_commit()
 
         conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         _common_config_check(conf, include_ras=False)
 
         self.assertIn(f'neighbor {int_neighbors[0]} remote-as internal', conf)
         self.assertIn(f'neighbor {int_neighbors[1]} remote-as internal', conf)
         self.assertIn(f'neighbor {ext_neighbors[0]} remote-as external', conf)
         self.assertIn(f'neighbor {ext_neighbors[1]} remote-as external', conf)
         self.assertIn(f'neighbor {ext_neighbors[1]} peer-group {ext_pg_name}', conf)
 
     def test_bgp_29_peer_group_remote_as_equal_local_as(self):
         self.cli_set(base_path + ['system-as', ASN])
         self.cli_set(base_path + ['peer-group', 'OVERLAY', 'local-as', f'{int(ASN) + 1}'])
         self.cli_set(base_path + ['peer-group', 'OVERLAY', 'remote-as', f'{int(ASN) + 1}'])
         self.cli_set(base_path + ['peer-group', 'OVERLAY', 'address-family', 'l2vpn-evpn'])
 
         self.cli_set(base_path + ['peer-group', 'UNDERLAY', 'address-family', 'ipv4-unicast'])
 
         self.cli_set(base_path + ['neighbor', '10.177.70.62', 'peer-group', 'UNDERLAY'])
         self.cli_set(base_path + ['neighbor', '10.177.70.62', 'remote-as', 'external'])
 
         self.cli_set(base_path + ['neighbor', '10.177.75.1', 'peer-group', 'OVERLAY'])
         self.cli_set(base_path + ['neighbor', '10.177.75.2', 'peer-group', 'OVERLAY'])
 
         self.cli_commit()
 
         conf = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
 
         self.assertIn(f'neighbor OVERLAY remote-as {int(ASN) + 1}', conf)
         self.assertIn(f'neighbor OVERLAY local-as {int(ASN) + 1}', conf)
 
     def test_bgp_99_bmp(self):
         target_name = 'instance-bmp'
         target_address = '127.0.0.1'
         target_port = '5000'
         min_retry = '1024'
         max_retry = '2048'
         monitor_ipv4 = 'pre-policy'
         monitor_ipv6 = 'pre-policy'
         mirror_buffer = '32000000'
         bmp_path = base_path + ['bmp']
         target_path = bmp_path + ['target', target_name]
 
         # by default the 'bmp' module not loaded for the bgpd expect Error
         self.cli_set(bmp_path)
         if not process_named_running('bgpd', 'bmp'):
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
         # add required 'bmp' module to bgpd and restart bgpd
         self.cli_delete(bmp_path)
         self.cli_set(['system', 'frr', 'bmp'])
         self.cli_commit()
 
         # restart bgpd to apply "-M bmp" and update PID
         cmd(f'sudo kill -9 {self.daemon_pid}')
         # let the bgpd process recover
         sleep(10)
         # update daemon PID - this was a planned daemon restart
         self.daemon_pid = process_named_running(bgp_daemon)
 
         # set bmp config but not set address
         self.cli_set(target_path + ['port', target_port])
         # address is not set, expect Error
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         # config other bmp options
         self.cli_set(target_path + ['address', target_address])
         self.cli_set(bmp_path + ['mirror-buffer-limit', mirror_buffer])
         self.cli_set(target_path + ['port', target_port])
         self.cli_set(target_path + ['min-retry', min_retry])
         self.cli_set(target_path + ['max-retry', max_retry])
         self.cli_set(target_path + ['mirror'])
         self.cli_set(target_path + ['monitor', 'ipv4-unicast', monitor_ipv4])
         self.cli_set(target_path + ['monitor', 'ipv6-unicast', monitor_ipv6])
         self.cli_commit()
 
         # Verify bgpd bmp configuration
         frrconfig = self.getFRRconfig(f'router bgp {ASN}', endsection='^exit')
         self.assertIn(f'bmp mirror buffer-limit {mirror_buffer}', frrconfig)
         self.assertIn(f'bmp targets {target_name}', frrconfig)
         self.assertIn(f'bmp mirror', frrconfig)
         self.assertIn(f'bmp monitor ipv4 unicast {monitor_ipv4}', frrconfig)
         self.assertIn(f'bmp monitor ipv6 unicast {monitor_ipv6}', frrconfig)
         self.assertIn(f'bmp connect {target_address} port {target_port} min-retry {min_retry} max-retry {max_retry}', frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
index 92d6ef2a7..598250d28 100755
--- a/smoketest/scripts/cli/test_protocols_isis.py
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -1,415 +1,419 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.utils.process import process_named_running
 from vyos.frrender import isis_daemon
 
 base_path = ['protocols', 'isis']
 domain = 'VyOS'
 net = '49.0001.1921.6800.1002.00'
 
 class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         cls._interfaces = Section.interfaces('ethernet')
         # call base-classes classmethod
         super(TestProtocolsISIS, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(isis_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
         cls.cli_delete(cls, ['vrf'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         # cleanup any possible VRF mess
         self.cli_delete(['vrf'])
         # always destrox the entire isisd configuration to make the processes
         # life as hard as possible
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(isis_daemon))
 
     def test_isis_01_redistribute(self):
         prefix_list = 'EXPORT-ISIS'
         route_map = 'EXPORT-ISIS'
         rule = '10'
         metric_style = 'transition'
 
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'action', 'permit'])
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'prefix', '203.0.113.0/24'])
         self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit'])
         self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list])
 
         self.cli_set(base_path)
 
         # verify() - net id and interface are mandatory
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['net', net])
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         self.cli_set(base_path + ['redistribute', 'ipv4', 'connected'])
         # verify() - Redistribute level-1 or level-2 should be specified
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map])
         self.cli_set(base_path + ['metric-style', metric_style])
         self.cli_set(base_path + ['log-adjacency-changes'])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' metric-style {metric_style}', tmp)
         self.assertIn(f' log-adjacency-changes', tmp)
         self.assertIn(f' redistribute ipv4 connected level-2 route-map {route_map}', tmp)
 
         for interface in self._interfaces:
             tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f' ip router isis {domain}', tmp)
             self.assertIn(f' ipv6 router isis {domain}', tmp)
 
         self.cli_delete(['policy', 'route-map', route_map])
         self.cli_delete(['policy', 'prefix-list', prefix_list])
 
     def test_isis_02_vrfs(self):
         vrfs = ['red', 'green', 'blue']
         # It is safe to assume that when the basic VRF test works, all other
         # IS-IS related features work, as we entirely inherit the CLI templates
         # and Jinja2 FRR template.
         table = '1000'
         vrf = 'red'
         vrf_base = ['vrf', 'name', vrf]
         vrf_iface = 'eth1'
         self.cli_set(vrf_base + ['table', table])
         self.cli_set(vrf_base + ['protocols', 'isis', 'net', net])
         self.cli_set(vrf_base + ['protocols', 'isis', 'interface', vrf_iface])
         self.cli_set(vrf_base + ['protocols', 'isis', 'advertise-high-metrics'])
         self.cli_set(vrf_base + ['protocols', 'isis', 'advertise-passive-only'])
         self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
 
         # Also set a default VRF IS-IS config
         self.cli_set(base_path + ['net', net])
         self.cli_set(base_path + ['interface', 'eth0'])
         self.cli_commit()
 
         # Verify FRR isisd configuration
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f'router isis {domain}', tmp)
         self.assertIn(f' net {net}', tmp)
 
         tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}', endsection='^exit')
         self.assertIn(f'router isis {domain} vrf {vrf}', tmp)
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' advertise-high-metrics', tmp)
         self.assertIn(f' advertise-passive-only', tmp)
 
         self.cli_delete(['vrf', 'name', vrf])
         self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
 
     def test_isis_04_default_information(self):
         metric = '50'
         route_map = 'default-foo-'
 
         self.cli_set(base_path + ['net', net])
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         for afi in ['ipv4', 'ipv6']:
             for level in ['level-1', 'level-2']:
                 self.cli_set(base_path + ['default-information', 'originate', afi, level, 'always'])
                 self.cli_set(base_path + ['default-information', 'originate', afi, level, 'metric', metric])
                 self.cli_set(base_path + ['default-information', 'originate', afi, level, 'route-map', route_map + level + afi])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
 
         for afi in ['ipv4', 'ipv6']:
             for level in ['level-1', 'level-2']:
                 route_map_name = route_map + level + afi
                 self.assertIn(f' default-information originate {afi} {level} always route-map {route_map_name} metric {metric}', tmp)
 
     def test_isis_05_password(self):
         password = 'foo'
 
         self.cli_set(base_path + ['net', net])
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface, 'password', 'plaintext-password', f'{password}-{interface}'])
 
         self.cli_set(base_path + ['area-password', 'plaintext-password', password])
         self.cli_set(base_path + ['area-password', 'md5', password])
         self.cli_set(base_path + ['domain-password', 'plaintext-password', password])
         self.cli_set(base_path + ['domain-password', 'md5', password])
 
         # verify() - can not use both md5 and plaintext-password for area-password
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['area-password', 'md5', password])
 
         # verify() - can not use both md5 and plaintext-password for domain-password
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['domain-password', 'md5', password])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' domain-password clear {password}', tmp)
         self.assertIn(f' area-password clear {password}', tmp)
 
         for interface in self._interfaces:
             tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f' isis password clear {password}-{interface}', tmp)
 
     def test_isis_06_spf_delay_bfd(self):
         network = 'point-to-point'
         holddown = '10'
         init_delay = '50'
         long_delay = '200'
         short_delay = '100'
         time_to_learn = '75'
         bfd_profile = 'isis-bfd'
 
         self.cli_set(base_path + ['net', net])
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface, 'network', network])
             self.cli_set(base_path + ['interface', interface, 'bfd', 'profile', bfd_profile])
 
         self.cli_set(base_path + ['spf-delay-ietf', 'holddown', holddown])
         # verify() - All types of spf-delay must be configured
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['spf-delay-ietf', 'init-delay', init_delay])
         # verify() - All types of spf-delay must be configured
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['spf-delay-ietf', 'long-delay', long_delay])
         # verify() - All types of spf-delay must be configured
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_set(base_path + ['spf-delay-ietf', 'short-delay', short_delay])
         # verify() - All types of spf-delay must be configured
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(base_path + ['spf-delay-ietf', 'time-to-learn', time_to_learn])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' spf-delay-ietf init-delay {init_delay} short-delay {short_delay} long-delay {long_delay} holddown {holddown} time-to-learn {time_to_learn}', tmp)
 
         for interface in self._interfaces:
             tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f' ip router isis {domain}', tmp)
             self.assertIn(f' ipv6 router isis {domain}', tmp)
             self.assertIn(f' isis network {network}', tmp)
             self.assertIn(f' isis bfd', tmp)
             self.assertIn(f' isis bfd profile {bfd_profile}', tmp)
 
     def test_isis_07_segment_routing_configuration(self):
         global_block_low = "300"
         global_block_high = "399"
         local_block_low = "400"
         local_block_high = "499"
         maximum_stack_size = '5'
         prefix_one = '192.168.0.1/32'
         prefix_two = '192.168.0.2/32'
         prefix_three = '192.168.0.3/32'
         prefix_four = '192.168.0.4/32'
         prefix_one_value = '1'
         prefix_two_value = '2'
         prefix_three_value = '60000'
         prefix_four_value = '65000'
 
         self.cli_set(base_path + ['net', net])
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         self.cli_set(base_path + ['segment-routing', 'maximum-label-depth', maximum_stack_size])
         self.cli_set(base_path + ['segment-routing', 'global-block', 'low-label-value', global_block_low])
         self.cli_set(base_path + ['segment-routing', 'global-block', 'high-label-value', global_block_high])
         self.cli_set(base_path + ['segment-routing', 'local-block', 'low-label-value', local_block_low])
         self.cli_set(base_path + ['segment-routing', 'local-block', 'high-label-value', local_block_high])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_one, 'index', 'value', prefix_one_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_one, 'index', 'explicit-null'])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_two, 'index', 'value', prefix_two_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_two, 'index', 'no-php-flag'])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_three, 'absolute', 'value',  prefix_three_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_three, 'absolute', 'explicit-null'])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_four, 'absolute', 'value', prefix_four_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_four, 'absolute', 'no-php-flag'])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' segment-routing on', tmp)
         self.assertIn(f' segment-routing global-block {global_block_low} {global_block_high} local-block {local_block_low} {local_block_high}', tmp)
         self.assertIn(f' segment-routing node-msd {maximum_stack_size}', tmp)
         self.assertIn(f' segment-routing prefix {prefix_one} index {prefix_one_value} explicit-null', tmp)
         self.assertIn(f' segment-routing prefix {prefix_two} index {prefix_two_value} no-php-flag', tmp)
         self.assertIn(f' segment-routing prefix {prefix_three} absolute {prefix_three_value} explicit-null', tmp)
         self.assertIn(f' segment-routing prefix {prefix_four} absolute {prefix_four_value} no-php-flag', tmp)
 
     def test_isis_08_ldp_sync(self):
         holddown = "500"
         interface = 'lo'
 
         self.cli_set(base_path + ['net', net])
         self.cli_set(base_path + ['interface', interface])
         self.cli_set(base_path + ['ldp-sync', 'holddown', holddown])
 
         # Commit main ISIS changes
         self.cli_commit()
 
         # Verify main ISIS changes
         tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' mpls ldp-sync', tmp)
         self.assertIn(f' mpls ldp-sync holddown {holddown}', tmp)
 
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface, 'ldp-sync', 'holddown', holddown])
 
         # Commit interface changes for holddown
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify interface changes for holddown
             tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', tmp)
             self.assertIn(f' ip router isis {domain}', tmp)
             self.assertIn(f' ipv6 router isis {domain}', tmp)
             self.assertIn(f' isis mpls ldp-sync holddown {holddown}', tmp)
 
         for interface in self._interfaces:
             self.cli_set(base_path + ['interface', interface, 'ldp-sync', 'disable'])
 
         # Commit interface changes for disable
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify interface changes for disable
             tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', tmp)
             self.assertIn(f' ip router isis {domain}', tmp)
             self.assertIn(f' ipv6 router isis {domain}', tmp)
             self.assertIn(f' no isis mpls ldp-sync', tmp)
 
     def test_isis_09_lfa(self):
         prefix_list = 'lfa-prefix-list-test-1'
         prefix_list_address = '192.168.255.255/32'
         interface = 'lo'
 
         self.cli_set(base_path + ['net', net])
         self.cli_set(base_path + ['interface', interface])
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '1', 'action', 'permit'])
         self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', '1', 'prefix', prefix_list_address])
 
         # Commit main ISIS changes
         self.cli_commit()
 
         # Add remote portion of LFA with prefix list with validation
         for level in ['level-1', 'level-2']:
             self.cli_set(base_path + ['fast-reroute', 'lfa', 'remote', 'prefix-list', prefix_list, level])
             self.cli_commit()
             tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
             self.assertIn(f' net {net}', tmp)
             self.assertIn(f' fast-reroute remote-lfa prefix-list {prefix_list} {level}', tmp)
             self.cli_delete(base_path + ['fast-reroute'])
             self.cli_commit()
 
         # Add local portion of LFA load-sharing portion with validation
         for level in ['level-1', 'level-2']:
             self.cli_set(base_path + ['fast-reroute', 'lfa', 'local', 'load-sharing', 'disable', level])
             self.cli_commit()
             tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
             self.assertIn(f' net {net}', tmp)
             self.assertIn(f' fast-reroute load-sharing disable {level}', tmp)
             self.cli_delete(base_path + ['fast-reroute'])
             self.cli_commit()
 
         # Add local portion of LFA priority-limit portion with validation
         for priority in ['critical', 'high', 'medium']:
             for level in ['level-1', 'level-2']:
                 self.cli_set(base_path + ['fast-reroute', 'lfa', 'local', 'priority-limit', priority, level])
                 self.cli_commit()
                 tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
                 self.assertIn(f' net {net}', tmp)
                 self.assertIn(f' fast-reroute priority-limit {priority} {level}', tmp)
                 self.cli_delete(base_path + ['fast-reroute'])
                 self.cli_commit()
 
         # Add local portion of LFA tiebreaker portion with validation
         index = '100'
         for tiebreaker in ['downstream','lowest-backup-metric','node-protecting']:
             for level in ['level-1', 'level-2']:
                 self.cli_set(base_path + ['fast-reroute', 'lfa', 'local', 'tiebreaker', tiebreaker, 'index', index, level])
                 self.cli_commit()
                 tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
                 self.assertIn(f' net {net}', tmp)
                 self.assertIn(f' fast-reroute lfa tiebreaker {tiebreaker} index {index} {level}', tmp)
                 self.cli_delete(base_path + ['fast-reroute'])
                 self.cli_commit()
 
         # Clean up and remove prefix list
         self.cli_delete(['policy', 'prefix-list', prefix_list])
         self.cli_commit()
 
     def test_isis_10_topology(self):
         topologies = ['ipv4-multicast', 'ipv4-mgmt', 'ipv6-unicast', 'ipv6-multicast', 'ipv6-mgmt']
         interface = 'lo'
 
         # Set a basic IS-IS config
         self.cli_set(base_path + ['net', net])
         self.cli_set(base_path + ['interface', interface])
         for topology in topologies:
             self.cli_set(base_path + ['topology', topology])
             self.cli_commit()
             tmp = self.getFRRconfig(f'router isis {domain}', endsection='^exit')
             self.assertIn(f' net {net}', tmp)
             self.assertIn(f' topology {topology}', tmp)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_mpls.py b/smoketest/scripts/cli/test_protocols_mpls.py
index 9d8417851..654f2f099 100755
--- a/smoketest/scripts/cli/test_protocols_mpls.py
+++ b/smoketest/scripts/cli/test_protocols_mpls.py
@@ -1,122 +1,125 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.frrender import ldpd_daemon
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'mpls', 'ldp']
 
 peers = {
     '192.0.2.10' : {
         'intv_rx'    : '500',
         'intv_tx'    : '600',
         'multihop'   : '',
         'source_addr': '192.0.2.254',
         },
     '192.0.2.20' : {
         'echo_mode'  : '',
         'intv_echo'  : '100',
         'intv_mult'  : '100',
         'intv_rx'    : '222',
         'intv_tx'    : '333',
         'passive'    : '',
         'shutdown'   : '',
         },
     '2001:db8::a' : {
         'source_addr': '2001:db8::1',
         },
     '2001:db8::b' : {
         'source_addr': '2001:db8::1',
         'multihop'   : '',
         },
 }
 
 profiles = {
     'foo' : {
         'echo_mode'  : '',
         'intv_echo'  : '100',
         'intv_mult'  : '101',
         'intv_rx'    : '222',
         'intv_tx'    : '333',
         'shutdown'   : '',
         },
     'bar' : {
         'intv_mult'  : '102',
         'intv_rx'    : '444',
         'passive'    : '',
         },
 }
 
 class TestProtocolsMPLS(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsMPLS, cls).setUpClass()
 
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(ldpd_daemon)
-
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(ldpd_daemon))
 
     def test_mpls_basic(self):
         router_id = '1.2.3.4'
         transport_ipv4_addr = '5.6.7.8'
         interfaces = Section.interfaces('ethernet')
 
         self.cli_set(base_path + ['router-id', router_id])
 
         # At least one LDP interface must be configured
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         # LDP transport address missing
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(base_path + ['discovery', 'transport-ipv4-address', transport_ipv4_addr])
 
         # Commit changes
         self.cli_commit()
 
         # Validate configuration
         frrconfig = self.getFRRconfig('mpls ldp', endsection='^exit')
         self.assertIn(f'mpls ldp', frrconfig)
         self.assertIn(f' router-id {router_id}', frrconfig)
 
         # Validate AFI IPv4
         afiv4_config = self.getFRRconfig('mpls ldp', endsection='^exit',
                                          substring=' address-family ipv4',
                                          endsubsection='^ exit-address-family')
         self.assertIn(f'  discovery transport-address {transport_ipv4_addr}', afiv4_config)
         for interface in interfaces:
             self.assertIn(f'  interface {interface}', afiv4_config)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_openfabric.py b/smoketest/scripts/cli/test_protocols_openfabric.py
index db0d5e222..323b6cd74 100644
--- a/smoketest/scripts/cli/test_protocols_openfabric.py
+++ b/smoketest/scripts/cli/test_protocols_openfabric.py
@@ -1,185 +1,189 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.utils.process import process_named_running
 from vyos.frrender import openfabric_daemon
 
 base_path = ['protocols', 'openfabric']
 
 domain = 'VyOS'
 net = '49.0001.1111.1111.1111.00'
 dummy_if = 'dum1234'
 address_families = ['ipv4', 'ipv6']
 
 path = base_path + ['domain', domain]
 
 class TestProtocolsOpenFabric(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         # call base-classes classmethod
         super(TestProtocolsOpenFabric, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(openfabric_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(openfabric_daemon))
 
     def openfabric_base_config(self):
         self.cli_set(['interfaces', 'dummy', dummy_if])
         self.cli_set(base_path + ['net', net])
         for family in address_families:
             self.cli_set(path + ['interface', dummy_if, 'address-family', family])
 
     def test_openfabric_01_router_params(self):
         fabric_tier = '5'
         lsp_gen_interval = '20'
 
         self.cli_set(base_path)
 
         # verify() - net id and domain name are mandatory
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.openfabric_base_config()
 
         self.cli_set(path + ['log-adjacency-changes'])
         self.cli_set(path + ['set-overload-bit'])
         self.cli_set(path + ['fabric-tier', fabric_tier])
         self.cli_set(path + ['lsp-gen-interval', lsp_gen_interval])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router openfabric {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' log-adjacency-changes', tmp)
         self.assertIn(f' set-overload-bit', tmp)
         self.assertIn(f' fabric-tier {fabric_tier}', tmp)
         self.assertIn(f' lsp-gen-interval {lsp_gen_interval}', tmp)
 
         tmp = self.getFRRconfig(f'interface {dummy_if}', endsection='^exit')
         self.assertIn(f' ip router openfabric {domain}', tmp)
         self.assertIn(f' ipv6 router openfabric {domain}', tmp)
 
     def test_openfabric_02_loopback_interface(self):
         interface = 'lo'
         hello_interval = '100'
         metric = '24478'
 
         self.openfabric_base_config()
         self.cli_set(path + ['interface', interface, 'address-family', 'ipv4'])
 
         self.cli_set(path + ['interface', interface, 'hello-interval', hello_interval])
         self.cli_set(path + ['interface', interface, 'metric', metric])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify FRR openfabric configuration
         tmp = self.getFRRconfig(f'router openfabric {domain}', endsection='^exit')
         self.assertIn(f'router openfabric {domain}', tmp)
         self.assertIn(f' net {net}', tmp)
 
         # Verify interface configuration
         tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
         self.assertIn(f' ip router openfabric {domain}', tmp)
         # for lo interface 'openfabric passive' is implied
         self.assertIn(f' openfabric passive', tmp)
         self.assertIn(f' openfabric metric {metric}', tmp)
 
     def test_openfabric_03_password(self):
         password = 'foo'
 
         self.openfabric_base_config()
 
         self.cli_set(path + ['interface', dummy_if, 'password', 'plaintext-password', f'{password}-{dummy_if}'])
         self.cli_set(path + ['interface', dummy_if, 'password', 'md5', f'{password}-{dummy_if}'])
 
         # verify() - can not use both md5 and plaintext-password for password for the interface
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(path + ['interface', dummy_if, 'password', 'md5'])
 
         self.cli_set(path + ['domain-password', 'plaintext-password', password])
         self.cli_set(path + ['domain-password', 'md5', password])
 
         # verify() - can not use both md5 and plaintext-password for domain-password
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(path + ['domain-password', 'md5'])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         tmp = self.getFRRconfig(f'router openfabric {domain}', endsection='^exit')
         self.assertIn(f' net {net}', tmp)
         self.assertIn(f' domain-password clear {password}', tmp)
 
         tmp = self.getFRRconfig(f'interface {dummy_if}', endsection='^exit')
         self.assertIn(f' openfabric password clear {password}-{dummy_if}', tmp)
 
     def test_openfabric_multiple_domains(self):
         domain_2 = 'VyOS_2'
         interface = 'dum5678'
         new_path = base_path + ['domain', domain_2]
 
         self.openfabric_base_config()
 
         # set same interface for 2 OpenFabric domains
         self.cli_set(['interfaces', 'dummy', interface])
         self.cli_set(new_path + ['interface', interface, 'address-family', 'ipv4'])
         self.cli_set(path + ['interface', interface, 'address-family', 'ipv4'])
 
         # verify() - same interface can be used only for one OpenFabric instance
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(path + ['interface', interface])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify FRR openfabric configuration
         tmp = self.getFRRconfig(f'router openfabric {domain}', endsection='^exit')
         self.assertIn(f'router openfabric {domain}', tmp)
         self.assertIn(f' net {net}', tmp)
 
         tmp = self.getFRRconfig(f'router openfabric {domain_2}', endsection='^exit')
         self.assertIn(f'router openfabric {domain_2}', tmp)
         self.assertIn(f' net {net}', tmp)
 
         # Verify interface configuration
         tmp = self.getFRRconfig(f'interface {dummy_if}', endsection='^exit')
         self.assertIn(f' ip router openfabric {domain}', tmp)
         self.assertIn(f' ipv6 router openfabric {domain}', tmp)
 
         tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit')
         self.assertIn(f' ip router openfabric {domain_2}', tmp)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index f862f5889..77882737f 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,575 +1,578 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from time import sleep
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.frrender import ospf_daemon
 from vyos.utils.process import process_named_running
 from vyos.xml_ref import default_value
 
 base_path = ['protocols', 'ospf']
 
 route_map = 'foo-bar-baz10'
 dummy_if = 'dum3562'
 
 class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsOSPF, cls).setUpClass()
 
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(ospf_daemon)
 
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
         cls.cli_set(cls, ['interfaces', 'dummy', dummy_if])
 
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['policy', 'route-map', route_map])
         cls.cli_delete(cls, ['interfaces', 'dummy', dummy_if])
         super(TestProtocolsOSPF, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertNotIn(f'router ospf', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(ospf_daemon))
 
     def test_ospf_01_defaults(self):
         # commit changes
         self.cli_set(base_path)
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
 
     def test_ospf_02_simple(self):
         router_id = '127.0.0.1'
         abr_type = 'ibm'
         bandwidth = '1000'
         metric = '123'
 
         self.cli_set(base_path + ['auto-cost', 'reference-bandwidth', bandwidth])
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
         self.cli_set(base_path + ['parameters', 'abr-type', abr_type])
         self.cli_set(base_path + ['parameters', 'opaque-lsa'])
         self.cli_set(base_path + ['parameters', 'rfc1583-compatibility'])
         self.cli_set(base_path + ['log-adjacency-changes', 'detail'])
         self.cli_set(base_path + ['default-metric', metric])
         self.cli_set(base_path + ['passive-interface', 'default'])
         self.cli_set(base_path + ['area', '10', 'area-type', 'stub'])
         self.cli_set(base_path + ['area', '10', 'network', '10.0.0.0/16'])
         self.cli_set(base_path + ['area', '10', 'range', '10.0.1.0/24'])
         self.cli_set(base_path + ['area', '10', 'range', '10.0.2.0/24', 'not-advertise'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' compatible rfc1583', frrconfig)
         self.assertIn(f' auto-cost reference-bandwidth {bandwidth}', frrconfig)
         self.assertIn(f' ospf router-id {router_id}', frrconfig)
         self.assertIn(f' ospf abr-type {abr_type}', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
         self.assertIn(f' capability opaque', frrconfig)
         self.assertIn(f' default-metric {metric}', frrconfig)
         self.assertIn(f' passive-interface default', frrconfig)
         self.assertIn(f' area 10 stub', frrconfig)
         self.assertIn(f' network 10.0.0.0/16 area 10', frrconfig)
         self.assertIn(f' area 10 range 10.0.1.0/24', frrconfig)
         self.assertNotIn(f' area 10 range 10.0.1.0/24 not-advertise', frrconfig)
         self.assertIn(f' area 10 range 10.0.2.0/24 not-advertise', frrconfig)
 
     def test_ospf_03_access_list(self):
         acl = '100'
         seq = '10'
         protocols = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
 
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any'])
         for ptotocol in protocols:
             self.cli_set(base_path + ['access-list', acl, 'export', ptotocol])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
         for ptotocol in protocols:
             self.assertIn(f' distribute-list {acl} out {ptotocol}', frrconfig) # defaults
         self.cli_delete(['policy', 'access-list', acl])
 
     def test_ospf_04_default_originate(self):
         seq = '100'
         metric = '50'
         metric_type = '1'
 
         self.cli_set(base_path + ['default-information', 'originate', 'metric', metric])
         self.cli_set(base_path + ['default-information', 'originate', 'metric-type', metric_type])
         self.cli_set(base_path + ['default-information', 'originate', 'route-map', route_map])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
         self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
         # Now set 'always'
         self.cli_set(base_path + ['default-information', 'originate', 'always'])
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
     def test_ospf_05_options(self):
         global_distance = '128'
         intra_area = '100'
         inter_area = '110'
         external = '120'
         on_startup = '30'
         on_shutdown = '60'
         refresh = '50'
         aggregation_timer = '100'
         summary_nets = {
             '10.0.1.0/24' : {},
             '10.0.2.0/24' : {'tag' : '50'},
             '10.0.3.0/24' : {'no_advertise' : {}},
          }
 
         self.cli_set(base_path + ['distance', 'global', global_distance])
         self.cli_set(base_path + ['distance', 'ospf', 'external', external])
         self.cli_set(base_path + ['distance', 'ospf', 'intra-area', intra_area])
 
         self.cli_set(base_path + ['max-metric', 'router-lsa', 'on-startup', on_startup])
         self.cli_set(base_path + ['max-metric', 'router-lsa', 'on-shutdown', on_shutdown])
 
         self.cli_set(base_path + ['mpls-te', 'enable'])
         self.cli_set(base_path + ['refresh', 'timers', refresh])
 
         self.cli_set(base_path + ['aggregation', 'timer', aggregation_timer])
 
         for summary, summary_options in summary_nets.items():
             self.cli_set(base_path + ['summary-address', summary])
             if 'tag' in summary_options:
                 self.cli_set(base_path + ['summary-address', summary, 'tag', summary_options['tag']])
             if 'no_advertise' in summary_options:
                 self.cli_set(base_path + ['summary-address', summary, 'no-advertise'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' mpls-te on', frrconfig)
         self.assertIn(f' mpls-te router-address 0.0.0.0', frrconfig) # default
         self.assertIn(f' distance {global_distance}', frrconfig)
         self.assertIn(f' distance ospf intra-area {intra_area} external {external}', frrconfig)
         self.assertIn(f' max-metric router-lsa on-startup {on_startup}', frrconfig)
         self.assertIn(f' max-metric router-lsa on-shutdown {on_shutdown}', frrconfig)
         self.assertIn(f' refresh timer {refresh}', frrconfig)
 
         self.assertIn(f' aggregation timer {aggregation_timer}', frrconfig)
         for summary, summary_options in summary_nets.items():
             self.assertIn(f' summary-address {summary}', frrconfig)
             if 'tag' in summary_options:
                 tag = summary_options['tag']
                 self.assertIn(f' summary-address {summary} tag {tag}', frrconfig)
             if 'no_advertise' in summary_options:
                 self.assertIn(f' summary-address {summary} no-advertise', frrconfig)
 
         # enable inter-area
         self.cli_set(base_path + ['distance', 'ospf', 'inter-area', inter_area])
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f' distance ospf intra-area {intra_area} inter-area {inter_area} external {external}', frrconfig)
 
         # https://github.com/FRRouting/frr/issues/17011
         # We need to wait on_shutdown time, until the OSPF process is removed from the CLI
         # otherwise the test in tearDown() will fail
         self.cli_delete(base_path)
         self.cli_commit()
 
         sleep(int(on_shutdown) + 5) # additional grace period of 5 seconds
 
     def test_ospf_06_neighbor(self):
         priority = '10'
         poll_interval = '20'
         neighbors = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
         for neighbor in neighbors:
             self.cli_set(base_path + ['neighbor', neighbor, 'priority', priority])
             self.cli_set(base_path + ['neighbor', neighbor, 'poll-interval', poll_interval])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         for neighbor in neighbors:
             self.assertIn(f' neighbor {neighbor} priority {priority} poll-interval {poll_interval}', frrconfig) # default
 
     def test_ospf_07_redistribute(self):
         metric = '15'
         metric_type = '1'
         redistribute = ['babel', 'bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
 
         for protocol in redistribute:
             self.cli_set(base_path + ['redistribute', protocol, 'metric', metric])
             self.cli_set(base_path + ['redistribute', protocol, 'route-map', route_map])
             self.cli_set(base_path + ['redistribute', protocol, 'metric-type', metric_type])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         for protocol in redistribute:
             self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
     def test_ospf_08_virtual_link(self):
         networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
         area = '10'
         shortcut = 'enable'
         virtual_link = '192.0.2.1'
         hello = '6'
         retransmit = '5'
         transmit = '5'
         dead = '40'
         window_default = default_value(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-window'])
 
         self.cli_set(base_path + ['area', area, 'shortcut', shortcut])
         self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'hello-interval', hello])
         self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-interval', retransmit])
         self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'transmit-delay', transmit])
         self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'dead-interval', dead])
         for network in networks:
             self.cli_set(base_path + ['area', area, 'network', network])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' area {area} shortcut {shortcut}', frrconfig)
         self.assertIn(f' area {area} virtual-link {virtual_link} hello-interval {hello} retransmit-interval {retransmit} retransmit-window {window_default} transmit-delay {transmit} dead-interval {dead}', frrconfig)
         for network in networks:
             self.assertIn(f' network {network} area {area}', frrconfig)
 
 
     def test_ospf_09_interface_configuration(self):
         interfaces = Section.interfaces('ethernet')
         password = 'vyos1234'
         bandwidth = '10000'
         cost = '150'
         network = 'point-to-point'
         priority = '200'
         bfd_profile = 'vyos-test'
 
         self.cli_set(base_path + ['passive-interface', 'default'])
         for interface in interfaces:
             base_interface = base_path + ['interface', interface]
             self.cli_set(base_interface + ['authentication', 'plaintext-password', password])
             self.cli_set(base_interface + ['bandwidth', bandwidth])
             self.cli_set(base_interface + ['bfd', 'profile', bfd_profile])
             self.cli_set(base_interface + ['cost', cost])
             self.cli_set(base_interface + ['mtu-ignore'])
             self.cli_set(base_interface + ['network', network])
             self.cli_set(base_interface + ['priority', priority])
             self.cli_set(base_interface + ['passive', 'disable'])
 
         # commit changes
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' passive-interface default', frrconfig)
 
         for interface in interfaces:
             # Can not use daemon for getFRRconfig() as bandwidth parameter belongs to zebra process
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ip ospf authentication-key {password}', config)
             self.assertIn(f' ip ospf bfd', config)
             self.assertIn(f' ip ospf bfd profile {bfd_profile}', config)
             self.assertIn(f' ip ospf cost {cost}', config)
             self.assertIn(f' ip ospf mtu-ignore', config)
             self.assertIn(f' ip ospf network {network}', config)
             self.assertIn(f' ip ospf priority {priority}', config)
             self.assertIn(f' no ip ospf passive', config)
             self.assertIn(f' bandwidth {bandwidth}', config)
 
         # T5467: Remove interface from OSPF process and VRF
         self.cli_delete(base_path + ['interface'])
         self.cli_commit()
 
         for interface in interfaces:
             # T5467: It must also be removed from FRR config
             frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertNotIn(f'interface {interface}', frrconfig)
             # There should be no OSPF related command at all under the interface
             self.assertNotIn(f' ip ospf', frrconfig)
 
     def test_ospf_11_interface_area(self):
         area = '0'
         interfaces = Section.interfaces('ethernet')
 
         self.cli_set(base_path + ['area', area, 'network', '10.0.0.0/8'])
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'area', area])
 
         # we can not have bot area network and interface area set
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['area', area, 'network'])
 
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
 
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ip ospf area {area}', config)
 
     def test_ospf_12_vrfs(self):
         # It is safe to assume that when the basic VRF test works, all
         # other OSPF related features work, as we entirely inherit the CLI
         # templates and Jinja2 FRR template.
         table = '1000'
         vrf = 'blue'
         vrf_base = ['vrf', 'name', vrf]
         vrf_iface = 'eth1'
         area = '1'
 
         self.cli_set(vrf_base + ['table', table])
         self.cli_set(vrf_base + ['protocols', 'ospf', 'interface', vrf_iface, 'area', area])
         self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
 
         # Also set a default VRF OSPF config
         self.cli_set(base_path)
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
 
         frrconfig = self.getFRRconfig(f'router ospf vrf {vrf}', endsection='^exit')
         self.assertIn(f'router ospf vrf {vrf}', frrconfig)
         self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
 
         frrconfig = self.getFRRconfig(f'interface {vrf_iface}', endsection='^exit')
         self.assertIn(f'interface {vrf_iface}', frrconfig)
         self.assertIn(f' ip ospf area {area}', frrconfig)
 
         # T5467: Remove interface from OSPF process and VRF
         self.cli_delete(vrf_base + ['protocols', 'ospf', 'interface'])
         self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
         self.cli_commit()
 
         # T5467: It must also be removed from FRR config
         frrconfig = self.getFRRconfig(f'interface {vrf_iface}', endsection='^exit')
         self.assertNotIn(f'interface {vrf_iface}', frrconfig)
         # There should be no OSPF related command at all under the interface
         self.assertNotIn(f' ip ospf', frrconfig)
 
         # cleanup
         self.cli_delete(['vrf', 'name', vrf])
         self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
 
     def test_ospf_13_export_list(self):
         # Verify explort-list works on ospf-area
         acl = '100'
         seq = '10'
         area = '0.0.0.10'
         network = '10.0.0.0/8'
 
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
         self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any'])
         self.cli_set(base_path + ['area', area, 'network', network])
         self.cli_set(base_path + ['area', area, 'export-list', acl])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # default
         self.assertIn(f' network {network} area {area}', frrconfig)
         self.assertIn(f' area {area} export-list {acl}', frrconfig)
 
 
     def test_ospf_14_segment_routing_configuration(self):
         global_block_low = "300"
         global_block_high = "399"
         local_block_low = "400"
         local_block_high = "499"
         maximum_stack_size = '5'
         prefix_one = '192.168.0.1/32'
         prefix_two = '192.168.0.2/32'
         prefix_one_value = '1'
         prefix_two_value = '2'
 
         self.cli_set(base_path + ['interface', dummy_if])
         self.cli_set(base_path + ['segment-routing', 'maximum-label-depth', maximum_stack_size])
         self.cli_set(base_path + ['segment-routing', 'global-block', 'low-label-value', global_block_low])
         self.cli_set(base_path + ['segment-routing', 'global-block', 'high-label-value', global_block_high])
         self.cli_set(base_path + ['segment-routing', 'local-block', 'low-label-value', local_block_low])
         self.cli_set(base_path + ['segment-routing', 'local-block', 'high-label-value', local_block_high])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_one, 'index', 'value', prefix_one_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_one, 'index', 'explicit-null'])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_two, 'index', 'value', prefix_two_value])
         self.cli_set(base_path + ['segment-routing', 'prefix', prefix_two, 'index', 'no-php-flag'])
 
         # Commit all changes
         self.cli_commit()
 
         # Verify all changes
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f' segment-routing on', frrconfig)
         self.assertIn(f' segment-routing global-block {global_block_low} {global_block_high} local-block {local_block_low} {local_block_high}', frrconfig)
         self.assertIn(f' segment-routing node-msd {maximum_stack_size}', frrconfig)
         self.assertIn(f' segment-routing prefix {prefix_one} index {prefix_one_value} explicit-null', frrconfig)
         self.assertIn(f' segment-routing prefix {prefix_two} index {prefix_two_value} no-php-flag', frrconfig)
 
     def test_ospf_15_ldp_sync(self):
         holddown = "500"
         interfaces = Section.interfaces('ethernet')
 
         self.cli_set(base_path + ['interface', dummy_if])
         self.cli_set(base_path + ['ldp-sync', 'holddown', holddown])
 
         # Commit main OSPF changes
         self.cli_commit()
 
         # Verify main OSPF changes
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig)
         self.assertIn(f' mpls ldp-sync holddown {holddown}', frrconfig)
 
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'ldp-sync', 'holddown', holddown])
 
         # Commit interface changes for holddown
         self.cli_commit()
 
         for interface in interfaces:
             # Verify interface changes for holddown
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ip ospf dead-interval 40', config)
             self.assertIn(f' ip ospf mpls ldp-sync', config)
             self.assertIn(f' ip ospf mpls ldp-sync holddown {holddown}', config)
 
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'ldp-sync', 'disable'])
 
         # Commit interface changes for disable
         self.cli_commit()
 
         for interface in interfaces:
             # Verify interface changes for disable
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ip ospf dead-interval 40', config)
             self.assertNotIn(f' ip ospf mpls ldp-sync', config)
 
     def test_ospf_16_graceful_restart(self):
         period = '300'
         supported_grace_time = '400'
         router_ids = ['192.0.2.1', '192.0.2.2']
 
         self.cli_set(base_path + ['capability', 'opaque'])
         self.cli_set(base_path + ['graceful-restart', 'grace-period', period])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'planned-only'])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'no-strict-lsa-checking'])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'supported-grace-time', supported_grace_time])
         for router_id in router_ids:
             self.cli_set(base_path + ['graceful-restart', 'helper', 'enable', 'router-id', router_id])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit')
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' capability opaque', frrconfig)
         self.assertIn(f' graceful-restart grace-period {period}', frrconfig)
         self.assertIn(f' graceful-restart helper planned-only', frrconfig)
         self.assertIn(f' no graceful-restart helper strict-lsa-checking', frrconfig)
         self.assertIn(f' graceful-restart helper supported-grace-time {supported_grace_time}', frrconfig)
         for router_id in router_ids:
             self.assertIn(f' graceful-restart helper enable {router_id}', frrconfig)
 
     def test_ospf_17_duplicate_area_network(self):
         area0 = '0'
         area1 = '1'
         network = '10.0.0.0/8'
 
         self.cli_set(base_path + ['area', area0, 'network', network])
 
         # we can not have the same network defined on two areas
         self.cli_set(base_path + ['area', area1, 'network', network])
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['area', area0])
 
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf', endsection='^exit', empty_retry=60)
         self.assertIn(f'router ospf', frrconfig)
         self.assertIn(f' network {network} area {area1}', frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index fd4d4cf08..5da4c7c98 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -1,342 +1,345 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.frrender import ospf6_daemon
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'ospfv3']
 
 route_map = 'foo-bar-baz-0815'
 
 router_id = '192.0.2.1'
 default_area = '0'
 
 class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsOSPFv3, cls).setUpClass()
 
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(ospf6_daemon)
 
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
 
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['policy', 'route-map', route_map])
         super(TestProtocolsOSPFv3, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertNotIn(f'router ospf6', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(ospf6_daemon))
 
     def test_ospfv3_01_basic(self):
         seq = '10'
         prefix = '2001:db8::/32'
         acl_name = 'foo-acl-100'
 
         self.cli_set(['policy', 'access-list6', acl_name, 'rule', seq, 'action', 'permit'])
         self.cli_set(['policy', 'access-list6', acl_name, 'rule', seq, 'source', 'any'])
 
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
         self.cli_set(base_path + ['area', default_area, 'range', prefix, 'advertise'])
         self.cli_set(base_path + ['area', default_area, 'export-list', acl_name])
         self.cli_set(base_path + ['area', default_area, 'import-list', acl_name])
 
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'area', default_area])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' area {default_area} range {prefix}', frrconfig)
         self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
         self.assertIn(f' area {default_area} import-list {acl_name}', frrconfig)
         self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig)
 
         for interface in interfaces:
             if_config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'ipv6 ospf6 area {default_area}', if_config)
 
         self.cli_delete(['policy', 'access-list6', acl_name])
 
 
     def test_ospfv3_02_distance(self):
         dist_global = '200'
         dist_external = '110'
         dist_inter_area = '120'
         dist_intra_area = '130'
 
         self.cli_set(base_path + ['distance', 'global', dist_global])
         self.cli_set(base_path + ['distance', 'ospfv3', 'external', dist_external])
         self.cli_set(base_path + ['distance', 'ospfv3', 'inter-area', dist_inter_area])
         self.cli_set(base_path + ['distance', 'ospfv3', 'intra-area', dist_intra_area])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' distance {dist_global}', frrconfig)
         self.assertIn(f' distance ospf6 intra-area {dist_intra_area} inter-area {dist_inter_area} external {dist_external}', frrconfig)
 
 
     def test_ospfv3_03_redistribute(self):
         metric = '15'
         metric_type = '1'
         route_map = 'foo-bar'
         route_map_seq = '10'
         redistribute = ['babel', 'bgp', 'connected', 'isis', 'kernel', 'ripng', 'static']
 
         self.cli_set(['policy', 'route-map', route_map, 'rule', route_map_seq, 'action', 'permit'])
 
         for protocol in redistribute:
             self.cli_set(base_path + ['redistribute', protocol, 'metric', metric])
             self.cli_set(base_path + ['redistribute', protocol, 'route-map', route_map])
             self.cli_set(base_path + ['redistribute', protocol, 'metric-type', metric_type])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         for protocol in redistribute:
             self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
 
     def test_ospfv3_04_interfaces(self):
         bfd_profile = 'vyos-ipv6'
 
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
         self.cli_set(base_path + ['area', default_area])
 
         cost = '100'
         priority = '10'
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             if_base = base_path + ['interface', interface]
             self.cli_set(if_base + ['bfd', 'profile', bfd_profile])
             self.cli_set(if_base + ['cost', cost])
             self.cli_set(if_base + ['instance-id', '0'])
             self.cli_set(if_base + ['mtu-ignore'])
             self.cli_set(if_base + ['network', 'point-to-point'])
             self.cli_set(if_base + ['passive'])
             self.cli_set(if_base + ['priority', priority])
             cost = str(int(cost) + 10)
             priority = str(int(priority) + 5)
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
 
         cost = '100'
         priority = '10'
         for interface in interfaces:
             if_config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', if_config)
             self.assertIn(f' ipv6 ospf6 bfd', if_config)
             self.assertIn(f' ipv6 ospf6 bfd profile {bfd_profile}', if_config)
             self.assertIn(f' ipv6 ospf6 cost {cost}', if_config)
             self.assertIn(f' ipv6 ospf6 mtu-ignore', if_config)
             self.assertIn(f' ipv6 ospf6 network point-to-point', if_config)
             self.assertIn(f' ipv6 ospf6 passive', if_config)
             self.assertIn(f' ipv6 ospf6 priority {priority}', if_config)
             cost = str(int(cost) + 10)
             priority = str(int(priority) + 5)
 
         # Cleanup interfaces
         self.cli_delete(base_path + ['interface'])
         self.cli_commit()
 
         for interface in interfaces:
             if_config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             # There should be no OSPF6 configuration at all after interface removal
             self.assertNotIn(f' ipv6 ospf6', if_config)
 
 
     def test_ospfv3_05_area_stub(self):
         area_stub = '23'
         area_stub_nosum = '26'
 
         self.cli_set(base_path + ['area', area_stub, 'area-type', 'stub'])
         self.cli_set(base_path + ['area', area_stub_nosum, 'area-type', 'stub', 'no-summary'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' area {area_stub} stub', frrconfig)
         self.assertIn(f' area {area_stub_nosum} stub no-summary', frrconfig)
 
 
     def test_ospfv3_06_area_nssa(self):
         area_nssa = '1.1.1.1'
         area_nssa_nosum = '2.2.2.2'
         area_nssa_default = '3.3.3.3'
 
         self.cli_set(base_path + ['area', area_nssa, 'area-type', 'nssa'])
         self.cli_set(base_path + ['area', area_nssa, 'area-type', 'stub'])
         # can only set one area-type per OSPFv3 area
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['area', area_nssa, 'area-type', 'stub'])
 
         self.cli_set(base_path + ['area', area_nssa_nosum, 'area-type', 'nssa', 'no-summary'])
         self.cli_set(base_path + ['area', area_nssa_nosum, 'area-type', 'nssa', 'default-information-originate'])
         self.cli_set(base_path + ['area', area_nssa_default, 'area-type', 'nssa', 'default-information-originate'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' area {area_nssa} nssa', frrconfig)
         self.assertIn(f' area {area_nssa_nosum} nssa default-information-originate no-summary', frrconfig)
         self.assertIn(f' area {area_nssa_default} nssa default-information-originate', frrconfig)
 
 
     def test_ospfv3_07_default_originate(self):
         seq = '100'
         metric = '50'
         metric_type = '1'
 
         self.cli_set(base_path + ['default-information', 'originate', 'metric', metric])
         self.cli_set(base_path + ['default-information', 'originate', 'metric-type', metric_type])
         self.cli_set(base_path + ['default-information', 'originate', 'route-map', route_map])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
         # Now set 'always'
         self.cli_set(base_path + ['default-information', 'originate', 'always'])
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
 
 
     def test_ospfv3_08_vrfs(self):
         # It is safe to assume that when the basic VRF test works, all
         # other OSPF related features work, as we entirely inherit the CLI
         # templates and Jinja2 FRR template.
         table = '1000'
         vrf = 'blue'
         vrf_base = ['vrf', 'name', vrf]
         vrf_iface = 'eth1'
         router_id = '1.2.3.4'
         router_id_vrf = '1.2.3.5'
 
         self.cli_set(vrf_base + ['table', table])
         self.cli_set(vrf_base + ['protocols', 'ospfv3', 'interface', vrf_iface, 'bfd'])
         self.cli_set(vrf_base + ['protocols', 'ospfv3', 'parameters', 'router-id', router_id_vrf])
 
         self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
 
         # Also set a default VRF OSPF config
         self.cli_set(base_path + ['parameters', 'router-id', router_id])
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
 
         frrconfig = self.getFRRconfig(f'interface {vrf_iface}', endsection='^exit')
         self.assertIn(f'interface {vrf_iface}', frrconfig)
         self.assertIn(f' ipv6 ospf6 bfd', frrconfig)
 
         frrconfig = self.getFRRconfig(f'router ospf6 vrf {vrf}', endsection='^exit')
         self.assertIn(f'router ospf6 vrf {vrf}', frrconfig)
         self.assertIn(f' ospf6 router-id {router_id_vrf}', frrconfig)
 
         # T5467: Remove interface from OSPF process and VRF
         self.cli_delete(vrf_base + ['protocols', 'ospfv3', 'interface'])
         self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
         self.cli_commit()
 
         # T5467: It must also be removed from FRR config
         frrconfig = self.getFRRconfig(f'interface {vrf_iface}', endsection='^exit')
         self.assertNotIn(f'interface {vrf_iface}', frrconfig)
         # There should be no OSPF related command at all under the interface
         self.assertNotIn(f' ipv6 ospf6', frrconfig)
 
         # cleanup
         self.cli_delete(['vrf', 'name', vrf])
         self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
 
 
     def test_ospfv3_09_graceful_restart(self):
         period = '300'
         supported_grace_time = '400'
         router_ids = ['192.0.2.1', '192.0.2.2']
 
         self.cli_set(base_path + ['graceful-restart', 'grace-period', period])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'planned-only'])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'lsa-check-disable'])
         self.cli_set(base_path + ['graceful-restart', 'helper', 'supported-grace-time', supported_grace_time])
         for router_id in router_ids:
             self.cli_set(base_path + ['graceful-restart', 'helper', 'enable', 'router-id', router_id])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ospf6', endsection='^exit')
         self.assertIn(f'router ospf6', frrconfig)
         self.assertIn(f' graceful-restart grace-period {period}', frrconfig)
         self.assertIn(f' graceful-restart helper planned-only', frrconfig)
         self.assertIn(f' graceful-restart helper lsa-check-disable', frrconfig)
         self.assertIn(f' graceful-restart helper supported-grace-time {supported_grace_time}', frrconfig)
         for router_id in router_ids:
             self.assertIn(f' graceful-restart helper enable {router_id}', frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_pim.py b/smoketest/scripts/cli/test_protocols_pim.py
index 1ba24c196..cc62769b3 100755
--- a/smoketest/scripts/cli/test_protocols_pim.py
+++ b/smoketest/scripts/cli/test_protocols_pim.py
@@ -1,192 +1,203 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.frrender import pim_daemon
 from vyos.ifconfig import Section
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'pim']
 
 class TestProtocolsPIM(VyOSUnitTestSHIM.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # call base-classes classmethod
+        super(TestProtocolsPIM, cls).setUpClass()
+        # ensure we can also run this test on a live system - so lets clean
+        # out the current configuration :)
+        cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
+
     def tearDown(self):
         # pimd process must be running
         self.assertTrue(process_named_running(pim_daemon))
 
         self.cli_delete(base_path)
         self.cli_commit()
 
         # pimd process must be stopped by now
         self.assertFalse(process_named_running(pim_daemon))
 
     def test_01_pim_basic(self):
         rp = '127.0.0.1'
         group = '224.0.0.0/4'
         hello = '100'
         dr_priority = '64'
 
         self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
 
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface , 'bfd'])
             self.cli_set(base_path + ['interface', interface , 'dr-priority', dr_priority])
             self.cli_set(base_path + ['interface', interface , 'hello', hello])
             self.cli_set(base_path + ['interface', interface , 'no-bsm'])
             self.cli_set(base_path + ['interface', interface , 'no-unicast-bsm'])
             self.cli_set(base_path + ['interface', interface , 'passive'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR pimd configuration
         frrconfig = self.getFRRconfig('router pim', endsection='^exit')
         self.assertIn(f' rp {rp} {group}', frrconfig)
 
         for interface in interfaces:
             frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', frrconfig)
             self.assertIn(f' ip pim', frrconfig)
             self.assertIn(f' ip pim bfd', frrconfig)
             self.assertIn(f' ip pim drpriority {dr_priority}', frrconfig)
             self.assertIn(f' ip pim hello {hello}', frrconfig)
             self.assertIn(f' no ip pim bsm', frrconfig)
             self.assertIn(f' no ip pim unicast-bsm', frrconfig)
             self.assertIn(f' ip pim passive', frrconfig)
 
         self.cli_commit()
 
     def test_02_pim_advanced(self):
         rp = '127.0.0.2'
         group = '224.0.0.0/4'
         join_prune_interval = '123'
         rp_keep_alive_timer = '190'
         keep_alive_timer = '180'
         packets = '10'
         prefix_list = 'pim-test'
         register_suppress_time = '300'
 
         self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
         self.cli_set(base_path + ['rp', 'keep-alive-timer', rp_keep_alive_timer])
 
         self.cli_set(base_path + ['ecmp', 'rebalance'])
         self.cli_set(base_path + ['join-prune-interval', join_prune_interval])
         self.cli_set(base_path + ['keep-alive-timer', keep_alive_timer])
         self.cli_set(base_path + ['packets', packets])
         self.cli_set(base_path + ['register-accept-list', 'prefix-list', prefix_list])
         self.cli_set(base_path + ['register-suppress-time', register_suppress_time])
         self.cli_set(base_path + ['no-v6-secondary'])
         self.cli_set(base_path + ['spt-switchover', 'infinity-and-beyond', 'prefix-list', prefix_list])
         self.cli_set(base_path + ['ssm', 'prefix-list', prefix_list])
 
         # check validate() - PIM require defined interfaces!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR pimd configuration
         frrconfig = self.getFRRconfig('router pim', endsection='^exit')
         self.assertIn(f' no send-v6-secondary', frrconfig)
         self.assertIn(f' rp {rp} {group}', frrconfig)
         self.assertIn(f' register-suppress-time {register_suppress_time}', frrconfig)
         self.assertIn(f' join-prune-interval {join_prune_interval}', frrconfig)
         self.assertIn(f' packets {packets}', frrconfig)
         self.assertIn(f' keep-alive-timer {keep_alive_timer}', frrconfig)
         self.assertIn(f' rp keep-alive-timer {rp_keep_alive_timer}', frrconfig)
         self.assertIn(f' ssm prefix-list {prefix_list}', frrconfig)
         self.assertIn(f' register-accept-list {prefix_list}', frrconfig)
         self.assertIn(f' spt-switchover infinity-and-beyond prefix-list {prefix_list}', frrconfig)
         self.assertIn(f' ecmp rebalance', frrconfig)
 
     def test_03_pim_igmp_proxy(self):
         igmp_proxy = ['protocols', 'igmp-proxy']
         rp = '127.0.0.1'
         group = '224.0.0.0/4'
 
         self.cli_set(base_path)
         self.cli_set(igmp_proxy)
 
         # check validate() - can not set both IGMP proxy and PIM
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         self.cli_delete(igmp_proxy)
 
         self.cli_set(base_path + ['rp', 'address', rp, 'group', group])
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface , 'bfd'])
 
         # commit changes
         self.cli_commit()
 
     def test_04_igmp(self):
         watermark_warning = '2000'
         query_interval = '1000'
         query_max_response_time = '200'
         version = '2'
 
         igmp_join = {
             '224.1.1.1' : { 'source' : ['1.1.1.1', '2.2.2.2', '3.3.3.3'] },
             '224.1.2.2' : { 'source' : [] },
             '224.1.3.3' : {},
         }
 
         self.cli_set(base_path + ['igmp', 'watermark-warning', watermark_warning])
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface , 'igmp', 'version', version])
             self.cli_set(base_path + ['interface', interface , 'igmp', 'query-interval', query_interval])
             self.cli_set(base_path + ['interface', interface , 'igmp', 'query-max-response-time', query_max_response_time])
 
             for join, join_config in igmp_join.items():
                 self.cli_set(base_path + ['interface', interface , 'igmp', 'join', join])
                 if 'source' in join_config:
                     for source in join_config['source']:
                         self.cli_set(base_path + ['interface', interface , 'igmp', 'join', join, 'source-address', source])
 
         self.cli_commit()
 
         frrconfig = self.getFRRconfig()
         self.assertIn(f'ip igmp watermark-warn {watermark_warning}', frrconfig)
 
         for interface in interfaces:
             frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', frrconfig)
             self.assertIn(f' ip igmp', frrconfig)
             self.assertIn(f' ip igmp version {version}', frrconfig)
             self.assertIn(f' ip igmp query-interval {query_interval}', frrconfig)
             self.assertIn(f' ip igmp query-max-response-time {query_max_response_time}', frrconfig)
 
             for join, join_config in igmp_join.items():
                 if 'source' in join_config:
                     for source in join_config['source']:
                         self.assertIn(f' ip igmp join-group {join} {source}', frrconfig)
                 else:
                     self.assertIn(f' ip igmp join-group {join}', frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_pim6.py b/smoketest/scripts/cli/test_protocols_pim6.py
index 98be54f4c..4ed8fcf7a 100755
--- a/smoketest/scripts/cli/test_protocols_pim6.py
+++ b/smoketest/scripts/cli/test_protocols_pim6.py
@@ -1,146 +1,150 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.frrender import pim6_daemon
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'pim6']
 
 class TestProtocolsPIMv6(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         # call base-classes classmethod
         super(TestProtocolsPIMv6, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(pim6_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(pim6_daemon))
 
     def test_pim6_01_mld_simple(self):
         # commit changes
         interfaces = Section.interfaces('ethernet')
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface])
 
         self.cli_commit()
 
         # Verify FRR pim6d configuration
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ipv6 mld', config)
             self.assertNotIn(f' ipv6 mld version 1', config)
 
         # Change to MLD version 1
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'mld', 'version', '1'])
 
         self.cli_commit()
 
         # Verify FRR pim6d configuration
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ipv6 mld', config)
             self.assertIn(f' ipv6 mld version 1', config)
 
     def test_pim6_02_mld_join(self):
         interfaces = Section.interfaces('ethernet')
         # Use an invalid multicast group address
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'fd00::1234'])
 
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_delete(base_path + ['interface'])
 
         # Use a valid multicast group address
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'ff18::1234'])
 
         self.cli_commit()
 
         # Verify FRR pim6d configuration
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ipv6 mld join-group ff18::1234', config)
 
         # Join a source-specific multicast group
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'mld', 'join', 'ff38::5678', 'source', '2001:db8::5678'])
 
         self.cli_commit()
 
         # Verify FRR pim6d configuration
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f'interface {interface}', config)
             self.assertIn(f' ipv6 mld join-group ff38::5678 2001:db8::5678', config)
 
     def test_pim6_03_basic(self):
         interfaces = Section.interfaces('ethernet')
         join_prune_interval = '123'
         keep_alive_timer = '77'
         packets = '5'
         register_suppress_time = '99'
         dr_priority = '100'
         hello = '50'
 
         self.cli_set(base_path + ['join-prune-interval', join_prune_interval])
         self.cli_set(base_path + ['keep-alive-timer', keep_alive_timer])
         self.cli_set(base_path + ['packets', packets])
         self.cli_set(base_path + ['register-suppress-time', register_suppress_time])
 
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'dr-priority', dr_priority])
             self.cli_set(base_path + ['interface', interface, 'hello', hello])
             self.cli_set(base_path + ['interface', interface, 'no-bsm'])
             self.cli_set(base_path + ['interface', interface, 'no-unicast-bsm'])
             self.cli_set(base_path + ['interface', interface, 'passive'])
 
         self.cli_commit()
 
         # Verify FRR pim6d configuration
         config = self.getFRRconfig('router pim6', endsection='^exit')
         self.assertIn(f' join-prune-interval {join_prune_interval}', config)
         self.assertIn(f' keep-alive-timer {keep_alive_timer}', config)
         self.assertIn(f' packets {packets}', config)
         self.assertIn(f' register-suppress-time {register_suppress_time}', config)
 
         for interface in interfaces:
             config = self.getFRRconfig(f'interface {interface}', endsection='^exit')
             self.assertIn(f' ipv6 pim drpriority {dr_priority}', config)
             self.assertIn(f' ipv6 pim hello {hello}', config)
             self.assertIn(f' no ipv6 pim bsm', config)
             self.assertIn(f' no ipv6 pim unicast-bsm', config)
             self.assertIn(f' ipv6 pim passive', config)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_rip.py b/smoketest/scripts/cli/test_protocols_rip.py
index 78567d12c..671ef8cd5 100755
--- a/smoketest/scripts/cli/test_protocols_rip.py
+++ b/smoketest/scripts/cli/test_protocols_rip.py
@@ -1,186 +1,189 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2023 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.ifconfig import Section
 from vyos.frrender import rip_daemon
 from vyos.utils.process import process_named_running
 
 acl_in = '198'
 acl_out = '199'
 prefix_list_in = 'foo-prefix'
 prefix_list_out = 'bar-prefix'
 route_map = 'FooBar123'
 
 base_path = ['protocols', 'rip']
 
 class TestProtocolsRIP(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsRIP, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(rip_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
         cls.cli_set(cls, ['policy', 'access-list', acl_in, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'access-list', acl_in, 'rule', '10', 'source', 'any'])
         cls.cli_set(cls, ['policy', 'access-list', acl_in, 'rule', '10', 'destination', 'any'])
         cls.cli_set(cls, ['policy', 'access-list', acl_out, 'rule', '20', 'action', 'deny'])
         cls.cli_set(cls, ['policy', 'access-list', acl_out, 'rule', '20', 'source', 'any'])
         cls.cli_set(cls, ['policy', 'access-list', acl_out, 'rule', '20', 'destination', 'any'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'prefix', '192.0.2.0/24'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'action', 'deny'])
         cls.cli_set(cls, ['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'prefix', '192.0.2.0/24'])
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, ['policy', 'access-list', acl_in])
         cls.cli_delete(cls, ['policy', 'access-list', acl_out])
         cls.cli_delete(cls, ['policy', 'prefix-list', prefix_list_in])
         cls.cli_delete(cls, ['policy', 'prefix-list', prefix_list_out])
         cls.cli_delete(cls, ['policy', 'route-map', route_map])
 
         super(TestProtocolsRIP, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router rip', endsection='^exit')
         self.assertNotIn(f'router rip', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(rip_daemon))
 
     def test_rip_01_parameters(self):
         distance = '40'
         network_distance = '66'
         metric = '8'
         interfaces = Section.interfaces('ethernet')
         neighbors = ['1.2.3.4', '1.2.3.5', '1.2.3.6']
         networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
         redistribute = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'static']
         timer_garbage = '888'
         timer_timeout = '1000'
         timer_update = '90'
 
         self.cli_set(base_path + ['default-distance', distance])
         self.cli_set(base_path + ['default-information', 'originate'])
         self.cli_set(base_path + ['default-metric', metric])
         self.cli_set(base_path + ['distribute-list', 'access-list', 'in', acl_in])
         self.cli_set(base_path + ['distribute-list', 'access-list', 'out', acl_out])
         self.cli_set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in])
         self.cli_set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out])
         self.cli_set(base_path + ['passive-interface', 'default'])
         self.cli_set(base_path + ['timers', 'garbage-collection', timer_garbage])
         self.cli_set(base_path + ['timers', 'timeout', timer_timeout])
         self.cli_set(base_path + ['timers', 'update', timer_update])
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out])
         for neighbor in neighbors:
             self.cli_set(base_path + ['neighbor', neighbor])
         for network in networks:
             self.cli_set(base_path + ['network', network])
             self.cli_set(base_path + ['network-distance', network, 'distance', network_distance])
             self.cli_set(base_path + ['route', network])
         for proto in redistribute:
             self.cli_set(base_path + ['redistribute', proto, 'metric', metric])
             self.cli_set(base_path + ['redistribute', proto, 'route-map', route_map])
 
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ripd configuration
         frrconfig = self.getFRRconfig('router rip', endsection='^exit')
         self.assertIn(f'router rip', frrconfig)
         self.assertIn(f' distance {distance}', frrconfig)
         self.assertIn(f' default-information originate', frrconfig)
         self.assertIn(f' default-metric {metric}', frrconfig)
         self.assertIn(f' distribute-list {acl_in} in', frrconfig)
         self.assertIn(f' distribute-list {acl_out} out', frrconfig)
         self.assertIn(f' distribute-list prefix {prefix_list_in} in', frrconfig)
         self.assertIn(f' distribute-list prefix {prefix_list_out} out', frrconfig)
         self.assertIn(f' passive-interface default', frrconfig)
         self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig)
         for interface in interfaces:
             self.assertIn(f' network {interface}', frrconfig)
             self.assertIn(f' distribute-list {acl_in} in {interface}', frrconfig)
             self.assertIn(f' distribute-list {acl_out} out {interface}', frrconfig)
             self.assertIn(f' distribute-list prefix {prefix_list_in} in {interface}', frrconfig)
             self.assertIn(f' distribute-list prefix {prefix_list_out} out {interface}', frrconfig)
         for neighbor in neighbors:
             self.assertIn(f' neighbor {neighbor}', frrconfig)
         for network in networks:
             self.assertIn(f' network {network}', frrconfig)
             self.assertIn(f' distance {network_distance} {network}', frrconfig)
             self.assertIn(f' route {network}', frrconfig)
         for proto in redistribute:
             self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
 
     def test_rip_02_zebra_route_map(self):
         # Implemented because of T3328
         self.cli_set(base_path + ['route-map', route_map])
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         zebra_route_map = f'ip protocol rip route-map {route_map}'
         frrconfig = self.getFRRconfig(zebra_route_map)
         self.assertIn(zebra_route_map, frrconfig)
 
         # Remove the route-map again
         self.cli_delete(base_path + ['route-map'])
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig(zebra_route_map)
         self.assertNotIn(zebra_route_map, frrconfig)
 
     def test_rip_03_version(self):
         rx_version = '1'
         tx_version = '2'
         interface = 'eth0'
 
         self.cli_set(base_path + ['version', tx_version])
         self.cli_set(base_path + ['interface', interface, 'send', 'version', tx_version])
         self.cli_set(base_path + ['interface', interface, 'receive', 'version', rx_version])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig('router rip', endsection='^exit')
         self.assertIn(f'version {tx_version}', frrconfig)
 
         frrconfig = self.getFRRconfig(f'interface {interface}', endsection='^exit')
         self.assertIn(f' ip rip receive version {rx_version}', frrconfig)
         self.assertIn(f' ip rip send version {tx_version}', frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py
index 26da2b62b..d2066b825 100755
--- a/smoketest/scripts/cli/test_protocols_ripng.py
+++ b/smoketest/scripts/cli/test_protocols_ripng.py
@@ -1,163 +1,166 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.ifconfig import Section
 from vyos.frrender import ripng_daemon
 from vyos.utils.process import process_named_running
 
 acl_in = '198'
 acl_out = '199'
 prefix_list_in = 'foo-prefix'
 prefix_list_out = 'bar-prefix'
 route_map = 'FooBar123'
 
 base_path = ['protocols', 'ripng']
 
 class TestProtocolsRIPng(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         # call base-classes classmethod
         super(TestProtocolsRIPng, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(ripng_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
         cls.cli_set(cls, ['policy', 'access-list6', acl_in, 'rule', '10', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'access-list6', acl_in, 'rule', '10', 'source', 'any'])
         cls.cli_set(cls, ['policy', 'access-list6', acl_out, 'rule', '20', 'action', 'deny'])
         cls.cli_set(cls, ['policy', 'access-list6', acl_out, 'rule', '20', 'source', 'any'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'action', 'permit'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'prefix', '2001:db8::/32'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'action', 'deny'])
         cls.cli_set(cls, ['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'prefix', '2001:db8::/32'])
         cls.cli_set(cls, ['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
 
     @classmethod
     def tearDownClass(cls):
         # call base-classes classmethod
         super(TestProtocolsRIPng, cls).tearDownClass()
 
         cls.cli_delete(cls, ['policy', 'access-list6', acl_in])
         cls.cli_delete(cls, ['policy', 'access-list6', acl_out])
         cls.cli_delete(cls, ['policy', 'prefix-list6', prefix_list_in])
         cls.cli_delete(cls, ['policy', 'prefix-list6', prefix_list_out])
         cls.cli_delete(cls, ['policy', 'route-map', route_map])
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('router ripng', endsection='^exit')
         self.assertNotIn(f'router ripng', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(ripng_daemon))
 
     def test_ripng_01_parameters(self):
         metric = '8'
         interfaces = Section.interfaces('ethernet')
         aggregates = ['2001:db8:1000::/48', '2001:db8:2000::/48', '2001:db8:3000::/48']
         networks = ['2001:db8:1000::/64', '2001:db8:1001::/64', '2001:db8:2000::/64', '2001:db8:2001::/64']
         redistribute = ['bgp', 'connected', 'kernel', 'ospfv3', 'static']
         timer_garbage = '888'
         timer_timeout = '1000'
         timer_update = '90'
 
         self.cli_set(base_path + ['default-information', 'originate'])
         self.cli_set(base_path + ['default-metric', metric])
         self.cli_set(base_path + ['distribute-list', 'access-list', 'in', acl_in])
         self.cli_set(base_path + ['distribute-list', 'access-list', 'out', acl_out])
         self.cli_set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in])
         self.cli_set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out])
         self.cli_set(base_path + ['passive-interface', 'default'])
         self.cli_set(base_path + ['timers', 'garbage-collection', timer_garbage])
         self.cli_set(base_path + ['timers', 'timeout', timer_timeout])
         self.cli_set(base_path + ['timers', 'update', timer_update])
         for aggregate in aggregates:
             self.cli_set(base_path + ['aggregate-address', aggregate])
 
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in])
             self.cli_set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out])
         for network in networks:
             self.cli_set(base_path + ['network', network])
             self.cli_set(base_path + ['route', network])
         for proto in redistribute:
             self.cli_set(base_path + ['redistribute', proto, 'metric', metric])
             self.cli_set(base_path + ['redistribute', proto, 'route-map', route_map])
 
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR ospfd configuration
         frrconfig = self.getFRRconfig('router ripng', endsection='^exit')
         self.assertIn(f'router ripng', frrconfig)
         self.assertIn(f' default-information originate', frrconfig)
         self.assertIn(f' default-metric {metric}', frrconfig)
         self.assertIn(f' ipv6 distribute-list {acl_in} in', frrconfig)
         self.assertIn(f' ipv6 distribute-list {acl_out} out', frrconfig)
         self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in', frrconfig)
         self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out', frrconfig)
         self.assertIn(f' passive-interface default', frrconfig)
         self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig)
         for aggregate in aggregates:
             self.assertIn(f' aggregate-address {aggregate}', frrconfig)
         for interface in interfaces:
             self.assertIn(f' network {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list {acl_in} in {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list {acl_out} out {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in {interface}', frrconfig)
             self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out {interface}', frrconfig)
         for network in networks:
             self.assertIn(f' network {network}', frrconfig)
             self.assertIn(f' route {network}', frrconfig)
         for proto in redistribute:
             if proto == 'ospfv3':
                 proto = 'ospf6'
             self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
 
     def test_ripng_02_zebra_route_map(self):
         # Implemented because of T3328
         self.cli_set(base_path + ['route-map', route_map])
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         zebra_route_map = f'ipv6 protocol ripng route-map {route_map}'
         frrconfig = self.getFRRconfig(zebra_route_map)
         self.assertIn(zebra_route_map, frrconfig)
 
         # Remove the route-map again
         self.cli_delete(base_path + ['route-map'])
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig(zebra_route_map)
         self.assertNotIn(zebra_route_map, frrconfig)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
index 36edbd5c2..ef2f30d3e 100755
--- a/smoketest/scripts/cli/test_protocols_rpki.py
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -1,249 +1,252 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.frrender import bgp_daemon
 from vyos.utils.file import read_file
 from vyos.utils.process import process_named_running
 
 base_path = ['protocols', 'rpki']
 rpki_key_name = 'rpki-smoketest'
 rpki_key_type = 'ssh-rsa'
 
 rpki_ssh_key = """
 b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
 NhAAAAAwEAAQAAAQEAweDyflDFR4qyEwETbJkZ2ZZc+sJNiDTvYpwGsWIkju49lJSxHe1x
 Kf8FhwfyMu40Snt1yDlRmmmz4CsbLgbuZGMPvXG11e34+C0pSVUvpF6aqRTeLl1pDRK7Rn
 jgm3su+I8SRLQR4qbLG6VXWOFuVpwiqbExLaU0hFYTPNP+dArNpsWEEKsohk6pTXdhg3Vz
 Wp3vCMjl2JTshDa3lD7p2xISSAReEY0fnfEAmQzH4Z6DIwwGdFuMWoQIg+oFBM9ARrO2/F
 IjRsz6AecR/WeU72JEw4aJic1/cAJQA6PiQBHwkuo3Wll1tbpxeRZoB2NQG22ETyJLvhfT
 aooNLT9HpQAAA8joU5dM6FOXTAAAAAdzc2gtcnNhAAABAQDB4PJ+UMVHirITARNsmRnZll
 z6wk2INO9inAaxYiSO7j2UlLEd7XEp/wWHB/Iy7jRKe3XIOVGaabPgKxsuBu5kYw+9cbXV
 7fj4LSlJVS+kXpqpFN4uXWkNErtGeOCbey74jxJEtBHipssbpVdY4W5WnCKpsTEtpTSEVh
 M80/50Cs2mxYQQqyiGTqlNd2GDdXNane8IyOXYlOyENreUPunbEhJIBF4RjR+d8QCZDMfh
 noMjDAZ0W4xahAiD6gUEz0BGs7b8UiNGzPoB5xH9Z5TvYkTDhomJzX9wAlADo+JAEfCS6j
 daWXW1unF5FmgHY1AbbYRPIku+F9Nqig0tP0elAAAAAwEAAQAAAQACkDlUjzfUhtJs6uY5
 WNrdJB5NmHUS+HQzzxFNlhkapK6+wKqI1UNaRUtq6iF7J+gcFf7MK2nXS098BsXguWm8fQ
 zPuemoDvHsQhiaJhyvpSqRUrvPTB/f8t/0AhQiKiJIWgfpTaIw53inAGwjujNNxNm2eafH
 TThhCYxOkRT7rsT6bnSio6yeqPy5QHg7IKFztp5FXDUyiOS3aX3SvzQcDUkMXALdvzX50t
 1XIk+X48Rgkq72dL4VpV2oMNDu3hM6FqBUplf9Mv3s51FNSma/cibCQoVufrIfoqYjkNTj
 IpYFUcq4zZ0/KvgXgzSsy9VN/4TtbalrOuu7X/SHJbvhAAAAgGPFsXgONYQvXxCnK1dIue
 ozgaZg1I/n522E2ZCOXBW4dYJVyNpppwRreDzuFzTDEe061MpNHfScjVBJCCulivFYWscL
 6oaGsryDbFxO3QmB4I98UBqrds2yan9/JGc6EYe299yvaHy7Y64+NC0+fN8H2RAZ61T4w1
 0JrCaJRyvzAAAAgQDvBfuV1U7o9k/fbU+U7W2UYnWblpOZAMfi1XQP6IJJeyWs90PdTdXh
 +l0eIQrCawIiRJytNfxMmbD4huwTf77fWiyCcPznmALQ7ex/yJ+W5Z0V4dPGF3h7o1uiS2
 36JhQ7mfcliCkhp/1PIklBIMPcCp0zl+s9wMv2hX7w1Pah9QAAAIEAz6YgU9Xute+J+dBw
 oWxEQ+igR6KE55Um7O9AvSrqnCm9r7lSFsXC2ErYOxoDSJ3yIBEV0b4XAGn6tbbVIs3jS8
 BnLHxclAHQecOx1PGn7PKbnPW0oJRq/X9QCIEelKYvlykpayn7uZooTXqcDaPZxfPpmPdy
 e8chVJvdygi7kPEAAAAMY3BvQExSMS53dWUzAQIDBAUGBw==
 """
 
 rpki_ssh_pub = """
 AAAAB3NzaC1yc2EAAAADAQABAAABAQDB4PJ+UMVHirITARNsmRnZllz6wk2INO9inAaxYi
 SO7j2UlLEd7XEp/wWHB/Iy7jRKe3XIOVGaabPgKxsuBu5kYw+9cbXV7fj4LSlJVS+kXpqp
 FN4uXWkNErtGeOCbey74jxJEtBHipssbpVdY4W5WnCKpsTEtpTSEVhM80/50Cs2mxYQQqy
 iGTqlNd2GDdXNane8IyOXYlOyENreUPunbEhJIBF4RjR+d8QCZDMfhnoMjDAZ0W4xahAiD
 6gUEz0BGs7b8UiNGzPoB5xH9Z5TvYkTDhomJzX9wAlADo+JAEfCS6jdaWXW1unF5FmgHY1
 AbbYRPIku+F9Nqig0tP0el
 """
 
 rpki_ssh_key_replacement = """
 b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
 NhAAAAAwEAAQAAAQEAtLPMwiGR3o6puPDbus9Yqoah9/7rv7i6ykykPmcEZ6ERnA0N6bl7
 LkQxnCuX270ukTTZOhROvQnvQYIZohCMz27Q16z7r+I755QXL0x8x4Gqhg/hQUY7UtX6ts
 db8+pO7G1PL4r9zT6/KJAF/wv86DezJ3I6TMaA7MCikXfQWJisBvhgAXF1+7V9CWaroGgV
 /hHzQJu1yd4cfsYoHyeDaZ+lwFw4egNItIy63fIGDxrnXaonJ1ODGQh7zWlpl/cwQR/KyJ
 P8vvOZ9olQ6syZV+DAcAo4Fe59wW2Zj4bl8bdGcdiDn0grkafxwTcg9ynr9kwQ8b66oXY4
 hwB4vlPFPwAAA8jkGyX45Bsl+AAAAAdzc2gtcnNhAAABAQC0s8zCIZHejqm48Nu6z1iqhq
 H3/uu/uLrKTKQ+ZwRnoRGcDQ3puXsuRDGcK5fbvS6RNNk6FE69Ce9BghmiEIzPbtDXrPuv
 4jvnlBcvTHzHgaqGD+FBRjtS1fq2x1vz6k7sbU8viv3NPr8okAX/C/zoN7MncjpMxoDswK
 KRd9BYmKwG+GABcXX7tX0JZqugaBX+EfNAm7XJ3hx+xigfJ4Npn6XAXDh6A0i0jLrd8gYP
 GuddqicnU4MZCHvNaWmX9zBBH8rIk/y+85n2iVDqzJlX4MBwCjgV7n3BbZmPhuXxt0Zx2I
 OfSCuRp/HBNyD3Kev2TBDxvrqhdjiHAHi+U8U/AAAAAwEAAQAAAQA99gkX5/rknXaE+9Hc
 VIzKrC+NodOkgetKwszuuNRB1HD9WVyT8A3U5307V5dSuaPmFoEF8UCugWGQzNONRq+B0T
 W7Po1u2dxAo/7vMQL4RfX60icjAroExWqakfFtycIWP8UPQFGWtxVFC12C/tFRrwe3Vuu2
 t7otdEBKMRM3zU0Hj88/5FIk/MDhththDCKTMe4+iwNKo30dyqSCckpTd2k5de9JYz8Aom
 87jtQcyDdynaELSo9CsA8KRPlozZ4VSWTVLH+Cv2TZWPL7hy79YvvIfuF/Sd6PGkNwG1Vj
 TAbq2Wx4uq+HmpNiz7W0LnbZtQJ7dzLA3FZlvQMC8fVBAAAAgQDWvImVZCyVWpoG+LnKY3
 joegjKRYKdgKRPCqGoIHiYsqCRxqSRW3jsuQCCvk4YO3/ZmqORiGktK+5r8R1QEtwg5qbi
 N7GZD34m7USNuqG2G/4puEly8syMmR6VRRvEURFQrpv2wniXNSefvsDc+WDqTfXGUxr+FT
 478wkzjwc/fAAAAIEA9uP0Ym3OC3cZ5FOvmu51lxo5lqPlUeE78axg2I4u/9Il8nOvSVuq
 B9X5wAUyGAGcUjT3EZmRAtL2sQxc5T0Vw3bnxCjzukEbFM+DRtYy1hXSOoGTTwKoMWBpho
 R3X5uRLUQL/22C4rd7tSJpjqnZXIH0B5z2fFh4vzu8/SrgCrUAAACBALtep4BcGJfjfhfF
 ODzQe7Rk7tsaX8pfNv6bQu0sR5C9pDURFRf0fRC0oqgeTuzq/vHPyNLsUUgTCpKWiLFmvU
 G9pelLT3XPPgzA+g0gycM0unuX8kkP3T5VQAM/7u0+h1CaJ8A6cCkzvDJxYdfio3WR60OP
 ulHg7HCcyomFLaSjAAAADGNwb0BMUjEud3VlMwECAwQFBg==
 """
 
 rpki_ssh_pub_replacement = """
 AAAAB3NzaC1yc2EAAAADAQABAAABAQC0s8zCIZHejqm48Nu6z1iqhqH3/uu/uLrKTKQ+Zw
 RnoRGcDQ3puXsuRDGcK5fbvS6RNNk6FE69Ce9BghmiEIzPbtDXrPuv4jvnlBcvTHzHgaqG
 D+FBRjtS1fq2x1vz6k7sbU8viv3NPr8okAX/C/zoN7MncjpMxoDswKKRd9BYmKwG+GABcX
 X7tX0JZqugaBX+EfNAm7XJ3hx+xigfJ4Npn6XAXDh6A0i0jLrd8gYPGuddqicnU4MZCHvN
 aWmX9zBBH8rIk/y+85n2iVDqzJlX4MBwCjgV7n3BbZmPhuXxt0Zx2IOfSCuRp/HBNyD3Ke
 v2TBDxvrqhdjiHAHi+U8U/
 """
 
 class TestProtocolsRPKI(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         # call base-classes classmethod
         super(TestProtocolsRPKI, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(bgp_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         frrconfig = self.getFRRconfig('rpki', endsection='^exit')
         self.assertNotIn(f'rpki', frrconfig)
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(bgp_daemon))
 
     def test_rpki(self):
         expire_interval = '3600'
         polling_period = '600'
         retry_interval = '300'
         cache = {
             '192.0.2.1' : {
                 'port' : '8080',
                 'preference' : '10'
             },
             '2001:db8::1' : {
                 'port' : '1234',
                 'preference' : '30'
             },
             'rpki.vyos.net' : {
                 'port' : '5678',
                 'preference' : '40'
             },
         }
 
         self.cli_set(base_path + ['expire-interval', expire_interval])
         self.cli_set(base_path + ['polling-period', polling_period])
         self.cli_set(base_path + ['retry-interval', retry_interval])
 
         for peer, peer_config in cache.items():
             self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
             self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig('rpki', endsection='^exit')
         self.assertIn(f'rpki expire_interval {expire_interval}', frrconfig)
         self.assertIn(f'rpki polling_period {polling_period}', frrconfig)
         self.assertIn(f'rpki retry_interval {retry_interval}', frrconfig)
 
         for peer, peer_config in cache.items():
             port = peer_config['port']
             preference = peer_config['preference']
             self.assertIn(f'rpki cache tcp {peer} {port} preference {preference}', frrconfig)
 
     def test_rpki_ssh(self):
         polling = '7200'
         cache = {
             '192.0.2.3' : {
                 'port' : '1234',
                 'username' : 'foo',
                 'preference' : '10'
             },
             '192.0.2.4' : {
                 'port' : '5678',
                 'username' : 'bar',
                 'preference' : '20'
             },
         }
 
         self.cli_set(['pki', 'openssh', rpki_key_name, 'private', 'key', rpki_ssh_key.replace('\n','')])
         self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'key', rpki_ssh_pub.replace('\n','')])
         self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'type', rpki_key_type])
 
         for cache_name, cache_config in cache.items():
             self.cli_set(base_path + ['cache', cache_name, 'port', cache_config['port']])
             self.cli_set(base_path + ['cache', cache_name, 'preference', cache_config['preference']])
             self.cli_set(base_path + ['cache', cache_name, 'ssh', 'username', cache_config['username']])
             self.cli_set(base_path + ['cache', cache_name, 'ssh', 'key', rpki_key_name])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig('rpki', endsection='^exit')
         for cache_name, cache_config in cache.items():
             port = cache_config['port']
             preference = cache_config['preference']
             username = cache_config['username']
             self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
 
             # Verify content of SSH keys
             tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
             self.assertIn(rpki_ssh_key.replace('\n',''), tmp)
             tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
             self.assertIn(rpki_ssh_pub.replace('\n',''), tmp)
 
         # Change OpenSSH key and verify it was properly written to filesystem
         self.cli_set(['pki', 'openssh', rpki_key_name, 'private', 'key', rpki_ssh_key_replacement.replace('\n','')])
         self.cli_set(['pki', 'openssh', rpki_key_name, 'public', 'key', rpki_ssh_pub_replacement.replace('\n','')])
         # commit changes
         self.cli_commit()
 
         for cache_name, cache_config in cache.items():
             port = cache_config['port']
             preference = cache_config['preference']
             username = cache_config['username']
             self.assertIn(f'rpki cache ssh {cache_name} {port} {username} /run/frr/id_rpki_{cache_name} /run/frr/id_rpki_{cache_name}.pub preference {preference}', frrconfig)
 
             # Verify content of SSH keys
             tmp = read_file(f'/run/frr/id_rpki_{cache_name}')
             self.assertIn(rpki_ssh_key_replacement.replace('\n',''), tmp)
             tmp = read_file(f'/run/frr/id_rpki_{cache_name}.pub')
             self.assertIn(rpki_ssh_pub_replacement.replace('\n',''), tmp)
 
         self.cli_delete(['pki', 'openssh'])
 
     def test_rpki_verify_preference(self):
         cache = {
             '192.0.2.1' : {
                 'port' : '8080',
                 'preference' : '1'
             },
             '192.0.2.2' : {
                 'port' : '9090',
                 'preference' : '1'
             },
         }
 
         for peer, peer_config in cache.items():
             self.cli_set(base_path + ['cache', peer, 'port', peer_config['port']])
             self.cli_set(base_path + ['cache', peer, 'preference', peer_config['preference']])
 
         # check validate() - preferences must be unique
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_segment-routing.py b/smoketest/scripts/cli/test_protocols_segment-routing.py
index af4ef2adf..94c808733 100755
--- a/smoketest/scripts/cli/test_protocols_segment-routing.py
+++ b/smoketest/scripts/cli/test_protocols_segment-routing.py
@@ -1,187 +1,190 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
 
 import unittest
 
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Section
 from vyos.frrender import zebra_daemon
 from vyos.utils.process import process_named_running
 from vyos.utils.system import sysctl_read
 
 base_path = ['protocols', 'segment-routing']
 
 
 class TestProtocolsSegmentRouting(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         # call base-classes classmethod
         super(TestProtocolsSegmentRouting, cls).setUpClass()
         # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same
         cls.daemon_pid = process_named_running(zebra_daemon)
         # ensure we can also run this test on a live system - so lets clean
         # out the current configuration :)
         cls.cli_delete(cls, base_path)
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_commit()
 
         # check process health and continuity
         self.assertEqual(self.daemon_pid, process_named_running(zebra_daemon))
 
     def test_srv6(self):
         interfaces = Section.interfaces('ethernet', vlan=False)
         locators = {
             'foo1': {'prefix': '2001:a::/64'},
             'foo2': {'prefix': '2001:b::/64', 'usid': {}},
             'foo3': {'prefix': '2001:c::/64', 'format': 'uncompressed-f4024'},
             'foo4': {
                 'prefix': '2001:d::/48',
                 'block-len': '32',
                 'node-len': '16',
                 'func-bits': '16',
                 'usid': {},
                 'format': 'usid-f3216',
             },
         }
 
         for locator, locator_config in locators.items():
             self.cli_set(
                 base_path
                 + ['srv6', 'locator', locator, 'prefix', locator_config['prefix']]
             )
             if 'block-len' in locator_config:
                 self.cli_set(
                     base_path
                     + [
                         'srv6',
                         'locator',
                         locator,
                         'block-len',
                         locator_config['block-len'],
                     ]
                 )
             if 'node-len' in locator_config:
                 self.cli_set(
                     base_path
                     + [
                         'srv6',
                         'locator',
                         locator,
                         'node-len',
                         locator_config['node-len'],
                     ]
                 )
             if 'func-bits' in locator_config:
                 self.cli_set(
                     base_path
                     + [
                         'srv6',
                         'locator',
                         locator,
                         'func-bits',
                         locator_config['func-bits'],
                     ]
                 )
             if 'usid' in locator_config:
                 self.cli_set(base_path + ['srv6', 'locator', locator, 'behavior-usid'])
             if 'format' in locator_config:
                 self.cli_set(
                     base_path
                     + ['srv6', 'locator', locator, 'format', locator_config['format']]
                 )
 
         # verify() - SRv6 should be enabled on at least one interface!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'srv6'])
 
         self.cli_commit()
 
         for interface in interfaces:
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
             )
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '0'
             )  # default
 
         frrconfig = self.getFRRconfig('segment-routing', endsection='^exit')
         self.assertIn('segment-routing', frrconfig)
         self.assertIn(' srv6', frrconfig)
         self.assertIn('  locators', frrconfig)
         for locator, locator_config in locators.items():
             prefix = locator_config['prefix']
             block_len = locator_config.get('block-len', '40')
             node_len = locator_config.get('node-len', '24')
             func_bits = locator_config.get('func-bits', '16')
 
             self.assertIn(f'   locator {locator}', frrconfig)
             self.assertIn(
                 f'    prefix {prefix} block-len {block_len} node-len {node_len} func-bits {func_bits}',
                 frrconfig,
             )
 
             if 'format' in locator_config:
                 self.assertIn(f'    format {locator_config["format"]}', frrconfig)
             if 'usid' in locator_config:
                 self.assertIn('    behavior usid', frrconfig)
 
     def test_srv6_sysctl(self):
         interfaces = Section.interfaces('ethernet', vlan=False)
 
         # HMAC accept
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'srv6'])
             self.cli_set(base_path + ['interface', interface, 'srv6', 'hmac', 'ignore'])
         self.cli_commit()
 
         for interface in interfaces:
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
             )
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '-1'
             )  # ignore
 
         # HMAC drop
         for interface in interfaces:
             self.cli_set(base_path + ['interface', interface, 'srv6'])
             self.cli_set(base_path + ['interface', interface, 'srv6', 'hmac', 'drop'])
         self.cli_commit()
 
         for interface in interfaces:
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_enabled'), '1'
             )
             self.assertEqual(
                 sysctl_read(f'net.ipv6.conf.{interface}.seg6_require_hmac'), '1'
             )  # drop
 
         # Disable SRv6 on first interface
         first_if = interfaces[-1]
         self.cli_delete(base_path + ['interface', first_if])
         self.cli_commit()
 
         self.assertEqual(sysctl_read(f'net.ipv6.conf.{first_if}.seg6_enabled'), '0')
 
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py
index 7cfc02e30..79d6b3af4 100755
--- a/smoketest/scripts/cli/test_protocols_static.py
+++ b/smoketest/scripts/cli/test_protocols_static.py
@@ -1,620 +1,623 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# Copyright (C) 2021-2025 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 <http://www.gnu.org/licenses/>.
 
 import os
 import unittest
 
 from time import sleep
 from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
 
 from vyos.configsession import ConfigSessionError
 from vyos.template import is_ipv6
 from vyos.template import get_dhcp_router
 from vyos.utils.network import get_interface_config
 from vyos.utils.network import get_vrf_tableid
 from vyos.utils.process import process_named_running
 from vyos.xml_ref import default_value
 
 base_path = ['protocols', 'static']
 vrf_path =  ['protocols', 'vrf']
 
 routes = {
     '10.0.0.0/8' : {
         'next_hop' : {
             '192.0.2.100' : { 'distance' : '100' },
             '192.0.2.110' : { 'distance' : '110', 'interface' : 'eth0' },
             '192.0.2.120' : { 'distance' : '120', 'disable' : '' },
             '192.0.2.130' : { 'bfd' : '' },
             '192.0.2.131' : { 'bfd' : '',
                               'bfd_profile' : 'vyos1' },
             '192.0.2.140' : { 'bfd' : '',
                               'bfd_source' : '192.0.2.10',
                               'bfd_profile' : 'vyos2' },
         },
         'interface' : {
             'eth0'  : { 'distance' : '130' },
             'eth1'  : { 'distance' : '140' },
         },
         'blackhole' : { 'distance' : '250', 'tag' : '500' },
     },
     '172.16.0.0/12' : {
         'interface' : {
             'eth0'  : { 'distance' : '50', 'vrf' : 'black' },
             'eth1'  : { 'distance' : '60', 'vrf' : 'black' },
         },
         'blackhole' : { 'distance' : '90' },
     },
     '192.0.2.0/24' : {
         'interface' : {
             'eth0'  : { 'distance' : '50', 'vrf' : 'black' },
             'eth1'  : { 'disable' : '' },
         },
         'blackhole' : { 'distance' : '90' },
     },
     '100.64.0.0/16' : {
         'blackhole' : {},
     },
     '100.65.0.0/16' : {
         'reject'    : { 'distance' : '10', 'tag' : '200' },
     },
     '100.66.0.0/16' : {
         'blackhole' : {},
         'reject'    : { 'distance' : '10', 'tag' : '200' },
     },
     '2001:db8:100::/40' : {
         'next_hop' : {
             '2001:db8::1' : { 'distance' : '10' },
             '2001:db8::2' : { 'distance' : '20', 'interface' : 'eth0' },
             '2001:db8::3' : { 'distance' : '30', 'disable' : '' },
             '2001:db8::4' : { 'bfd' : '' },
             '2001:db8::5' : { 'bfd_source' : '2001:db8::ffff' },
         },
         'interface' : {
             'eth0'  : { 'distance' : '40', 'vrf' : 'black' },
             'eth1'  : { 'distance' : '50', 'disable' : '' },
         },
         'blackhole' : { 'distance' : '250', 'tag' : '500' },
     },
     '2001:db8:200::/40' : {
         'interface' : {
             'eth0'  : { 'distance' : '40' },
             'eth1'  : { 'distance' : '50', 'disable' : '' },
         },
         'blackhole' : { 'distance' : '250', 'tag' : '500' },
     },
     '2001:db8:300::/40' : {
         'reject'    : { 'distance' : '250', 'tag' : '500' },
     },
     '2001:db8:400::/40' : {
         'next_hop' : {
             '2001:db8::400' : { 'segments' : '2001:db8:aaaa::400/2002::400/2003::400/2004::400' },
         },
     },
     '2001:db8:500::/40' : {
         'next_hop' : {
             '2001:db8::500' : { 'segments' : '2001:db8:aaaa::500/2002::500/2003::500/2004::500' },
         },
     },
     '2001:db8:600::/40' : {
         'interface' : {
             'eth0'  : { 'segments' : '2001:db8:aaaa::600/2002::600' },
         },
     },
     '2001:db8:700::/40' : {
         'interface' : {
             'eth1'  : { 'segments' : '2001:db8:aaaa::700' },
         },
     },
     '2001:db8::/32' : {
         'blackhole' : { 'distance' : '200', 'tag' : '600' }
     },
 }
 
 multicast_routes = {
     '224.0.0.0/24' : {
         'next_hop' : {
             '224.203.0.1' : { },
             '224.203.0.2' : { 'distance' : '110'},
         },
     },
     '224.1.0.0/24' : {
         'next_hop' : {
             '224.205.0.1' : { 'disable' : {} },
             '224.205.0.2' : { 'distance' : '110'},
         },
     },
     '224.2.0.0/24' : {
         'next_hop' : {
             '1.2.3.0' : { },
             '1.2.3.1' : { 'distance' : '110'},
         },
     },
     '224.10.0.0/24' : {
         'interface' : {
             'eth1' : { 'disable' : {} },
             'eth2' : { 'distance' : '110'},
         },
     },
     '224.11.0.0/24' : {
         'interface' : {
             'eth0' : { },
             'eth1' : { 'distance' : '10'},
         },
     },
     '224.12.0.0/24' : {
         'interface' : {
             'eth0' : { },
             'eth1' : { 'distance' : '200'},
         },
     },
 }
 
 tables = ['80', '81', '82']
 
 class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
     @classmethod
     def setUpClass(cls):
         super(TestProtocolsStatic, cls).setUpClass()
         cls.cli_delete(cls, base_path)
         cls.cli_delete(cls, ['vrf'])
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
 
     @classmethod
     def tearDownClass(cls):
         cls.cli_delete(cls, base_path)
         cls.cli_delete(cls, ['vrf'])
         super(TestProtocolsStatic, cls).tearDownClass()
 
     def tearDown(self):
         self.cli_delete(base_path)
         self.cli_delete(['vrf'])
         self.cli_commit()
 
         v4route = self.getFRRconfig('ip route', end='')
         self.assertFalse(v4route)
         v6route = self.getFRRconfig('ipv6 route', end='')
         self.assertFalse(v6route)
 
     def test_01_static(self):
         self.cli_set(['vrf', 'name', 'black', 'table', '43210'])
         for route, route_config in routes.items():
             route_type = 'route'
             if is_ipv6(route):
                 route_type = 'route6'
             base = base_path + [route_type, route]
             if 'next_hop' in route_config:
                 for next_hop, next_hop_config in route_config['next_hop'].items():
                     self.cli_set(base + ['next-hop', next_hop])
                     if 'disable' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'disable'])
                     if 'distance' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
                     if 'interface' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
                     if 'vrf' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
                     if 'bfd' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'bfd'])
                         if 'bfd_profile' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'bfd', 'profile', next_hop_config['bfd_profile']])
                         if 'bfd_source' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'bfd', 'multi-hop', 'source-address', next_hop_config['bfd_source']])
                     if 'segments' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'segments', next_hop_config['segments']])
 
             if 'interface' in route_config:
                 for interface, interface_config in route_config['interface'].items():
                     self.cli_set(base + ['interface', interface])
                     if 'disable' in interface_config:
                         self.cli_set(base + ['interface', interface, 'disable'])
                     if 'distance' in interface_config:
                         self.cli_set(base + ['interface', interface, 'distance', interface_config['distance']])
                     if 'vrf' in interface_config:
                         self.cli_set(base + ['interface', interface, 'vrf', interface_config['vrf']])
                     if 'segments' in interface_config:
                         self.cli_set(base + ['interface', interface, 'segments', interface_config['segments']])
 
             if 'blackhole' in route_config:
                 self.cli_set(base + ['blackhole'])
                 if 'distance' in route_config['blackhole']:
                     self.cli_set(base + ['blackhole', 'distance', route_config['blackhole']['distance']])
                 if 'tag' in route_config['blackhole']:
                     self.cli_set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
 
             if 'reject' in route_config:
                 self.cli_set(base + ['reject'])
                 if 'distance' in route_config['reject']:
                     self.cli_set(base + ['reject', 'distance', route_config['reject']['distance']])
                 if 'tag' in route_config['reject']:
                     self.cli_set(base + ['reject', 'tag', route_config['reject']['tag']])
 
             if {'blackhole', 'reject'} <= set(route_config):
                 # Can not use blackhole and reject at the same time
                 with self.assertRaises(ConfigSessionError):
                     self.cli_commit()
                 self.cli_delete(base + ['blackhole'])
                 self.cli_delete(base + ['reject'])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig('ip route', end='')
 
         # Verify routes
         for route, route_config in routes.items():
             ip_ipv6 = 'ip'
             if is_ipv6(route):
                 ip_ipv6 = 'ipv6'
 
             if 'next_hop' in route_config:
                 for next_hop, next_hop_config in route_config['next_hop'].items():
                     tmp = f'{ip_ipv6} route {route} {next_hop}'
                     if 'interface' in next_hop_config:
                         tmp += ' ' + next_hop_config['interface']
                     if 'distance' in next_hop_config:
                         tmp += ' ' + next_hop_config['distance']
                     if 'vrf' in next_hop_config:
                         tmp += ' nexthop-vrf ' + next_hop_config['vrf']
                     if 'bfd' in next_hop_config:
                         tmp += ' bfd'
                         if 'bfd_source' in next_hop_config:
                             tmp += ' multi-hop source ' + next_hop_config['bfd_source']
                         if 'bfd_profile' in next_hop_config:
                             tmp += ' profile ' + next_hop_config['bfd_profile']
                     if 'segments' in next_hop_config:
                         tmp += ' segments ' + next_hop_config['segments']
 
                     if 'disable' in next_hop_config:
                         self.assertNotIn(tmp, frrconfig)
                     else:
                         self.assertIn(tmp, frrconfig)
 
             if 'interface' in route_config:
                 for interface, interface_config in route_config['interface'].items():
                     tmp = f'{ip_ipv6} route {route} {interface}'
                     if 'interface' in interface_config:
                         tmp += ' ' + interface_config['interface']
                     if 'distance' in interface_config:
                         tmp += ' ' + interface_config['distance']
                     if 'vrf' in interface_config:
                         tmp += ' nexthop-vrf ' + interface_config['vrf']
                     if 'segments' in interface_config:
                         tmp += ' segments ' + interface_config['segments']
 
                     if 'disable' in interface_config:
                         self.assertNotIn(tmp, frrconfig)
                     else:
                         self.assertIn(tmp, frrconfig)
 
             if {'blackhole', 'reject'} <= set(route_config):
                 # Can not use blackhole and reject at the same time
                 # Config error validated above - skip this route
                 continue
 
             if 'blackhole' in route_config:
                 tmp = f'{ip_ipv6} route {route} blackhole'
                 if 'tag' in route_config['blackhole']:
                     tmp += ' tag ' + route_config['blackhole']['tag']
                 if 'distance' in route_config['blackhole']:
                     tmp += ' ' + route_config['blackhole']['distance']
 
                 self.assertIn(tmp, frrconfig)
 
             if 'reject' in route_config:
                 tmp = f'{ip_ipv6} route {route} reject'
                 if 'tag' in route_config['reject']:
                     tmp += ' tag ' + route_config['reject']['tag']
                 if 'distance' in route_config['reject']:
                     tmp += ' ' + route_config['reject']['distance']
 
                 self.assertIn(tmp, frrconfig)
 
     def test_02_static_table(self):
         self.cli_set(['vrf', 'name', 'black', 'table', '43210'])
         for table in tables:
             for route, route_config in routes.items():
                 route_type = 'route'
                 if is_ipv6(route):
                     route_type = 'route6'
                 base = base_path + ['table', table, route_type, route]
 
                 if 'next_hop' in route_config:
                     for next_hop, next_hop_config in route_config['next_hop'].items():
                         self.cli_set(base + ['next-hop', next_hop])
                         if 'disable' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'disable'])
                         if 'distance' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
                         if 'interface' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
                         if 'vrf' in next_hop_config:
                             self.cli_set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
 
 
                 if 'interface' in route_config:
                     for interface, interface_config in route_config['interface'].items():
                         self.cli_set(base + ['interface', interface])
                         if 'disable' in interface_config:
                             self.cli_set(base + ['interface', interface, 'disable'])
                         if 'distance' in interface_config:
                             self.cli_set(base + ['interface', interface, 'distance', interface_config['distance']])
                         if 'vrf' in interface_config:
                             self.cli_set(base + ['interface', interface, 'vrf', interface_config['vrf']])
 
                 if 'blackhole' in route_config:
                     self.cli_set(base + ['blackhole'])
                     if 'distance' in route_config['blackhole']:
                         self.cli_set(base + ['blackhole', 'distance', route_config['blackhole']['distance']])
                     if 'tag' in route_config['blackhole']:
                         self.cli_set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
 
         # commit changes
         self.cli_commit()
 
         # Verify FRR bgpd configuration
         frrconfig = self.getFRRconfig('ip route', end='')
 
         for table in tables:
             # Verify routes
             for route, route_config in routes.items():
                 ip_ipv6 = 'ip'
                 if is_ipv6(route):
                     ip_ipv6 = 'ipv6'
 
                 if 'next_hop' in route_config:
                     for next_hop, next_hop_config in route_config['next_hop'].items():
                         tmp = f'{ip_ipv6} route {route} {next_hop}'
                         if 'interface' in next_hop_config:
                             tmp += ' ' + next_hop_config['interface']
                         if 'distance' in next_hop_config:
                             tmp += ' ' + next_hop_config['distance']
                         if 'vrf' in next_hop_config:
                             tmp += ' nexthop-vrf ' + next_hop_config['vrf']
 
                         tmp += ' table ' + table
                         if 'disable' in next_hop_config:
                             self.assertNotIn(tmp, frrconfig)
                         else:
                             self.assertIn(tmp, frrconfig)
 
                 if 'interface' in route_config:
                     for interface, interface_config in route_config['interface'].items():
                         tmp = f'{ip_ipv6} route {route} {interface}'
                         if 'interface' in interface_config:
                             tmp += ' ' + interface_config['interface']
                         if 'distance' in interface_config:
                             tmp += ' ' + interface_config['distance']
                         if 'vrf' in interface_config:
                             tmp += ' nexthop-vrf ' + interface_config['vrf']
 
                         tmp += ' table ' + table
                         if 'disable' in interface_config:
                             self.assertNotIn(tmp, frrconfig)
                         else:
                             self.assertIn(tmp, frrconfig)
 
                 if 'blackhole' in route_config:
                     tmp = f'{ip_ipv6} route {route} blackhole'
                     if 'tag' in route_config['blackhole']:
                         tmp += ' tag ' + route_config['blackhole']['tag']
                     if 'distance' in route_config['blackhole']:
                         tmp += ' ' + route_config['blackhole']['distance']
 
                     tmp += ' table ' + table
                     self.assertIn(tmp, frrconfig)
 
 
     def test_03_static_vrf(self):
         self.cli_set(['vrf', 'name', 'black', 'table', '43210'])
         # Create VRF instances and apply the static routes from above to FRR.
         # Re-read the configured routes and match them if they are programmed
         # properly. This also includes VRF leaking
         vrfs = {
             'red'   : { 'table' : '1000' },
             'green' : { 'table' : '2000' },
             'blue'  : { 'table' : '3000' },
         }
 
         for vrf, vrf_config in vrfs.items():
             vrf_base_path = ['vrf', 'name', vrf]
             self.cli_set(vrf_base_path + ['table', vrf_config['table']])
 
             for route, route_config in routes.items():
                 route_type = 'route'
                 if is_ipv6(route):
                     route_type = 'route6'
                 route_base_path = vrf_base_path + ['protocols', 'static', route_type, route]
 
                 if 'next_hop' in route_config:
                     for next_hop, next_hop_config in route_config['next_hop'].items():
                         self.cli_set(route_base_path + ['next-hop', next_hop])
                         if 'disable' in next_hop_config:
                             self.cli_set(route_base_path + ['next-hop', next_hop, 'disable'])
                         if 'distance' in next_hop_config:
                             self.cli_set(route_base_path + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
                         if 'interface' in next_hop_config:
                             self.cli_set(route_base_path + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
                         if 'vrf' in next_hop_config:
                             self.cli_set(route_base_path + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
                         if 'segments' in next_hop_config:
                             self.cli_set(route_base_path + ['next-hop', next_hop, 'segments', next_hop_config['segments']])
 
                 if 'interface' in route_config:
                     for interface, interface_config in route_config['interface'].items():
                         self.cli_set(route_base_path + ['interface', interface])
                         if 'disable' in interface_config:
                             self.cli_set(route_base_path + ['interface', interface, 'disable'])
                         if 'distance' in interface_config:
                             self.cli_set(route_base_path + ['interface', interface, 'distance', interface_config['distance']])
                         if 'vrf' in interface_config:
                             self.cli_set(route_base_path + ['interface', interface, 'vrf', interface_config['vrf']])
                         if 'segments' in interface_config:
                             self.cli_set(route_base_path + ['interface', interface, 'segments', interface_config['segments']])
 
                 if 'blackhole' in route_config:
                     self.cli_set(route_base_path + ['blackhole'])
                     if 'distance' in route_config['blackhole']:
                         self.cli_set(route_base_path + ['blackhole', 'distance', route_config['blackhole']['distance']])
                     if 'tag' in route_config['blackhole']:
                         self.cli_set(route_base_path + ['blackhole', 'tag', route_config['blackhole']['tag']])
 
         # commit changes
         self.cli_commit()
 
         for vrf, vrf_config in vrfs.items():
             tmp = get_interface_config(vrf)
 
             # Compare VRF table ID
             self.assertEqual(get_vrf_tableid(vrf), int(vrf_config['table']))
             self.assertEqual(tmp['linkinfo']['info_kind'],          'vrf')
 
             # Verify FRR bgpd configuration
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f'vrf {vrf}', frrconfig)
 
             # Verify routes
             for route, route_config in routes.items():
                 ip_ipv6 = 'ip'
                 if is_ipv6(route):
                     ip_ipv6 = 'ipv6'
 
                 if 'next_hop' in route_config:
                     for next_hop, next_hop_config in route_config['next_hop'].items():
                         tmp = f'{ip_ipv6} route {route} {next_hop}'
                         if 'interface' in next_hop_config:
                             tmp += ' ' + next_hop_config['interface']
                         if 'distance' in next_hop_config:
                             tmp += ' ' + next_hop_config['distance']
                         if 'vrf' in next_hop_config:
                             tmp += ' nexthop-vrf ' + next_hop_config['vrf']
                         if 'segments' in next_hop_config:
                             tmp += ' segments ' + next_hop_config['segments']
 
                         if 'disable' in next_hop_config:
                             self.assertNotIn(tmp, frrconfig)
                         else:
                             self.assertIn(tmp, frrconfig)
 
                 if 'interface' in route_config:
                     for interface, interface_config in route_config['interface'].items():
                         tmp = f'{ip_ipv6} route {route} {interface}'
                         if 'interface' in interface_config:
                             tmp += ' ' + interface_config['interface']
                         if 'distance' in interface_config:
                             tmp += ' ' + interface_config['distance']
                         if 'vrf' in interface_config:
                             tmp += ' nexthop-vrf ' + interface_config['vrf']
                         if 'segments' in interface_config:
                             tmp += ' segments ' + interface_config['segments']
 
                         if 'disable' in interface_config:
                             self.assertNotIn(tmp, frrconfig)
                         else:
                             self.assertIn(tmp, frrconfig)
 
                 if 'blackhole' in route_config:
                     tmp = f'{ip_ipv6} route {route} blackhole'
                     if 'tag' in route_config['blackhole']:
                         tmp += ' tag ' + route_config['blackhole']['tag']
                     if 'distance' in route_config['blackhole']:
                         tmp += ' ' + route_config['blackhole']['distance']
 
                     self.assertIn(tmp, frrconfig)
 
     def test_04_static_multicast(self):
         for route, route_config in multicast_routes.items():
             if 'next_hop' in route_config:
                 base = base_path + ['mroute', route]
                 for next_hop, next_hop_config in route_config['next_hop'].items():
                     self.cli_set(base + ['next-hop', next_hop])
                     if 'distance' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
                     if 'disable' in next_hop_config:
                         self.cli_set(base + ['next-hop', next_hop, 'disable'])
 
             if 'interface' in route_config:
                 base = base_path + ['mroute', route]
                 for next_hop, next_hop_config in route_config['interface'].items():
                     self.cli_set(base + ['interface', next_hop])
                     if 'distance' in next_hop_config:
                         self.cli_set(base + ['interface', next_hop, 'distance', next_hop_config['distance']])
 
         self.cli_commit()
 
         # Verify FRR configuration
         frrconfig = self.getFRRconfig('ip mroute', end='')
         for route, route_config in multicast_routes.items():
             if 'next_hop' in route_config:
                 for next_hop, next_hop_config in route_config['next_hop'].items():
                     tmp = f'ip mroute {route} {next_hop}'
                     if 'distance' in next_hop_config:
                         tmp += ' ' + next_hop_config['distance']
                     if 'disable' in next_hop_config:
                         self.assertNotIn(tmp, frrconfig)
                     else:
                         self.assertIn(tmp, frrconfig)
 
             if 'next_hop_interface' in route_config:
                 for next_hop, next_hop_config in route_config['next_hop_interface'].items():
                     tmp = f'ip mroute {route} {next_hop}'
                     if 'distance' in next_hop_config:
                         tmp += ' ' + next_hop_config['distance']
                     if 'disable' in next_hop_config:
                         self.assertNotIn(tmp, frrconfig)
                     else:
                         self.assertIn(tmp, frrconfig)
 
     def test_05_dhcp_default_route(self):
         # When running via vyos-build under the QEmu environment a local DHCP
         # server is available. This test verifies that the default route is set.
         # When not running under the VyOS QEMU environment, this test is skipped.
         if not os.path.exists('/tmp/vyos.smoketests.hint'):
             self.skipTest('Not running under VyOS CI/CD QEMU environment!')
 
         interface = 'eth0'
         interface_path = ['interfaces', 'ethernet', interface]
         default_distance = default_value(interface_path + ['dhcp-options', 'default-route-distance'])
         self.cli_set(interface_path + ['address', 'dhcp'])
         self.cli_commit()
 
         # Wait for dhclient to receive IP address and default gateway
         sleep(5)
 
         router = get_dhcp_router(interface)
         frrconfig = self.getFRRconfig('')
         self.assertIn(rf'ip route 0.0.0.0/0 {router} {interface} tag 210 {default_distance}', frrconfig)
 
         # T6991: Default route is missing when there is no "protocols static"
         # CLI node entry
         self.cli_delete(base_path)
         # We can trigger a FRR reconfiguration and config re-rendering when
         # we simply disable IPv6 forwarding
         self.cli_set(['system', 'ipv6', 'disable-forwarding'])
         self.cli_commit()
 
         # Re-check FRR configuration that default route is still present
         frrconfig = self.getFRRconfig('')
         self.assertIn(rf'ip route 0.0.0.0/0 {router} {interface} tag 210 {default_distance}', frrconfig)
 
         self.cli_delete(interface_path + ['address'])
         self.cli_commit()
 
         # Wait for dhclient to stop
         while process_named_running('dhclient', cmdline=interface, timeout=10):
             sleep(0.250)
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 1676f8f19..30980f9ec 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -1,599 +1,605 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2020-2024 VyOS maintainers and contributors
+# Copyright (C) 2020-2025 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 <http://www.gnu.org/licenses/>.
 
 import re
 import os
 import unittest
 
-from base_vyostest_shim import VyOSUnitTestSHIM
 from json import loads
 from jmespath import search
 
+from base_vyostest_shim import VyOSUnitTestSHIM
+from base_vyostest_shim import CSTORE_GUARD_TIME
+
 from vyos.configsession import ConfigSessionError
 from vyos.ifconfig import Interface
 from vyos.ifconfig import Section
 from vyos.utils.file import read_file
 from vyos.utils.network import get_interface_config
 from vyos.utils.network import get_vrf_tableid
 from vyos.utils.network import is_intf_addr_assigned
 from vyos.utils.network import interface_exists
 from vyos.utils.process import cmd
 from vyos.utils.system import sysctl_read
 
 base_path = ['vrf']
 vrfs = ['red', 'green', 'blue', 'foo-bar', 'baz_foo']
 v4_protocols = ['any', 'babel', 'bgp', 'connected', 'eigrp', 'isis', 'kernel', 'ospf', 'rip', 'static', 'table']
 v6_protocols = ['any', 'babel', 'bgp', 'connected', 'isis', 'kernel', 'ospfv3', 'ripng', 'static', 'table']
 
 class VRFTest(VyOSUnitTestSHIM.TestCase):
     _interfaces = []
 
     @classmethod
     def setUpClass(cls):
         # we need to filter out VLAN interfaces identified by a dot (.)
         # in their name - just in case!
         if 'TEST_ETH' in os.environ:
             tmp = os.environ['TEST_ETH'].split()
             cls._interfaces = tmp
         else:
             for tmp in Section.interfaces('ethernet', vlan=False):
                 cls._interfaces.append(tmp)
+
+        # Enable CSTORE guard time required by FRR related tests
+        cls._commit_guard_time = CSTORE_GUARD_TIME
+
         # call base-classes classmethod
         super(VRFTest, cls).setUpClass()
 
     def setUp(self):
         # VRF strict_most ist always enabled
         tmp = read_file('/proc/sys/net/vrf/strict_mode')
         self.assertEqual(tmp, '1')
 
     def tearDown(self):
         # delete all VRFs
         self.cli_delete(base_path)
         self.cli_commit()
         for vrf in vrfs:
             self.assertFalse(interface_exists(vrf))
 
     def test_vrf_vni_and_table_id(self):
         base_table = '1000'
         table = base_table
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             description = f'VyOS-VRF-{vrf}'
             self.cli_set(base + ['description', description])
 
             # check validate() - a table ID is mandatory
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
             self.cli_set(base + ['table', table])
             self.cli_set(base + ['vni', table])
             if vrf == 'green':
                 self.cli_set(base + ['disable'])
 
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         iproute2_config = read_file('/etc/iproute2/rt_tables.d/vyos-vrf.conf')
         for vrf in vrfs:
             description = f'VyOS-VRF-{vrf}'
             self.assertTrue(interface_exists(vrf))
             vrf_if = Interface(vrf)
             # validate proper interface description
             self.assertEqual(vrf_if.get_alias(), description)
             # validate admin up/down state of VRF
             state = 'up'
             if vrf == 'green':
                 state = 'down'
             self.assertEqual(vrf_if.get_admin_state(), state)
 
             # Test the iproute2 lookup file, syntax is as follows:
             #
             # # id       vrf name         comment
             # 1000       red              # VyOS-VRF-red
             # 1001       green            # VyOS-VRF-green
             #  ...
             regex = f'{table}\s+{vrf}\s+#\s+{description}'
             self.assertTrue(re.findall(regex, iproute2_config))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
 
             self.assertEqual(int(table), get_vrf_tableid(vrf))
 
             # Increment table ID for the next run
             table = str(int(table) + 1)
 
     def test_vrf_loopbacks_ips(self):
         table = '2000'
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', str(table)])
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         loopbacks = ['127.0.0.1', '::1']
         for vrf in vrfs:
             # Ensure VRF was created
             self.assertTrue(interface_exists(vrf))
             # Verify IP forwarding is 1 (enabled)
             self.assertEqual(sysctl_read(f'net.ipv4.conf.{vrf}.forwarding'), '1')
             self.assertEqual(sysctl_read(f'net.ipv6.conf.{vrf}.forwarding'), '1')
 
             # Test for proper loopback IP assignment
             for addr in loopbacks:
                 self.assertTrue(is_intf_addr_assigned(vrf, addr))
 
     def test_vrf_bind_all(self):
         table = '2000'
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', str(table)])
             table = str(int(table) + 1)
 
         self.cli_set(base_path +  ['bind-to-all'])
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         self.assertEqual(sysctl_read('net.ipv4.tcp_l3mdev_accept'), '1')
         self.assertEqual(sysctl_read('net.ipv4.udp_l3mdev_accept'), '1')
 
         # If there is any VRF defined, strict_mode should be on
         self.assertEqual(sysctl_read('net.vrf.strict_mode'), '1')
 
     def test_vrf_table_id_is_unalterable(self):
         # Linux Kernel prohibits the change of a VRF table  on the fly.
         # VRF must be deleted and recreated!
         table = '1000'
         vrf = vrfs[0]
         base = base_path + ['name', vrf]
         self.cli_set(base + ['table', table])
 
         # commit changes
         self.cli_commit()
 
         # Check if VRF has been created
         self.assertTrue(interface_exists(vrf))
 
         table = str(int(table) + 1)
         self.cli_set(base + ['table', table])
         # check validate() - table ID can not be altered!
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
     def test_vrf_assign_interface(self):
         vrf = vrfs[0]
         table = '5000'
         self.cli_set(['vrf', 'name', vrf, 'table', table])
 
         for interface in self._interfaces:
             section = Section.section(interface)
             self.cli_set(['interfaces', section, interface, 'vrf', vrf])
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF assignmant
         for interface in self._interfaces:
             tmp = get_interface_config(interface)
             self.assertEqual(vrf, tmp['master'])
 
             # cleanup
             section = Section.section(interface)
             self.cli_delete(['interfaces', section, interface, 'vrf'])
 
     def test_vrf_static_route(self):
         base_table = '100'
         table = base_table
         for vrf in vrfs:
             next_hop = f'192.0.{table}.1'
             prefix = f'10.0.{table}.0/24'
             base = base_path + ['name', vrf]
 
             self.cli_set(base + ['vni', table])
 
             # check validate() - a table ID is mandatory
             with self.assertRaises(ConfigSessionError):
                 self.cli_commit()
 
             self.cli_set(base + ['table', table])
             self.cli_set(base + ['protocols', 'static', 'route', prefix, 'next-hop', next_hop])
 
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         for vrf in vrfs:
             next_hop = f'192.0.{table}.1'
             prefix = f'10.0.{table}.0/24'
 
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
             self.assertIn(f' ip route {prefix} {next_hop}', frrconfig)
 
             # Increment table ID for the next run
             table = str(int(table) + 1)
 
     def test_vrf_link_local_ip_addresses(self):
         # Testcase for issue T4331
         table = '100'
         vrf = 'orange'
         interface = 'dum9998'
         addresses = ['192.0.2.1/26', '2001:db8:9998::1/64', 'fe80::1/64']
 
         for address in addresses:
             self.cli_set(['interfaces', 'dummy', interface, 'address', address])
 
         # Create dummy interfaces
         self.cli_commit()
 
         # ... and verify IP addresses got assigned
         for address in addresses:
             self.assertTrue(is_intf_addr_assigned(interface, address))
 
         # Move interface to VRF
         self.cli_set(base_path + ['name', vrf, 'table', table])
         self.cli_set(['interfaces', 'dummy', interface, 'vrf', vrf])
 
         # Apply VRF config
         self.cli_commit()
         # Ensure VRF got created
         self.assertTrue(interface_exists(vrf))
         # ... and IP addresses are still assigned
         for address in addresses:
             self.assertTrue(is_intf_addr_assigned(interface, address))
         # Verify VRF table ID
         self.assertEqual(int(table), get_vrf_tableid(vrf))
 
         # Verify interface is assigned to VRF
         tmp = get_interface_config(interface)
         self.assertEqual(vrf, tmp['master'])
 
         # Delete Interface
         self.cli_delete(['interfaces', 'dummy', interface])
         self.cli_commit()
 
     def test_vrf_disable_forwarding(self):
         table = '2000'
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
             self.cli_set(base + ['ip', 'disable-forwarding'])
             self.cli_set(base + ['ipv6', 'disable-forwarding'])
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         loopbacks = ['127.0.0.1', '::1']
         for vrf in vrfs:
             # Ensure VRF was created
             self.assertTrue(interface_exists(vrf))
             # Verify IP forwarding is 0 (disabled)
             self.assertEqual(sysctl_read(f'net.ipv4.conf.{vrf}.forwarding'), '0')
             self.assertEqual(sysctl_read(f'net.ipv6.conf.{vrf}.forwarding'), '0')
 
     def test_vrf_ip_protocol_route_map(self):
         table = '6000'
 
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
 
             for protocol in v4_protocols:
                 self.cli_set(['policy', 'route-map', f'route-map-{vrf}-{protocol}', 'rule', '10', 'action', 'permit'])
                 self.cli_set(base + ['ip', 'protocol', protocol, 'route-map', f'route-map-{vrf}-{protocol}'])
 
             table = str(int(table) + 1)
 
         self.cli_commit()
 
         # Verify route-map properly applied to FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f'vrf {vrf}', frrconfig)
             for protocol in v4_protocols:
                 self.assertIn(f' ip protocol {protocol} route-map route-map-{vrf}-{protocol}', frrconfig)
 
         # Delete route-maps
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_delete(['policy', 'route-map', f'route-map-{vrf}-{protocol}'])
             self.cli_delete(base + ['ip', 'protocol'])
 
         self.cli_commit()
 
         # Verify route-map properly is removed from FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertNotIn(f' ip protocol', frrconfig)
 
     def test_vrf_ip_ipv6_protocol_non_existing_route_map(self):
         table = '6100'
         non_existing = 'non-existing'
 
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
             for protocol in v4_protocols:
                 self.cli_set(base + ['ip', 'protocol', protocol, 'route-map', f'v4-{non_existing}'])
             for protocol in v6_protocols:
                 self.cli_set(base + ['ipv6', 'protocol', protocol, 'route-map', f'v6-{non_existing}'])
 
             table = str(int(table) + 1)
 
         # Both v4 and v6 route-maps do not exist yet
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(['policy', 'route-map', f'v4-{non_existing}', 'rule', '10', 'action', 'deny'])
 
         # v6 route-map does not exist yet
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
         self.cli_set(['policy', 'route-map', f'v6-{non_existing}', 'rule', '10', 'action', 'deny'])
 
         # Commit again
         self.cli_commit()
 
     def test_vrf_ipv6_protocol_route_map(self):
         table = '6200'
 
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
 
             for protocol in v6_protocols:
                 route_map = f'route-map-{vrf}-{protocol.replace("ospfv3", "ospf6")}'
                 self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
                 self.cli_set(base + ['ipv6', 'protocol', protocol, 'route-map', route_map])
 
             table = str(int(table) + 1)
 
         self.cli_commit()
 
         # Verify route-map properly applied to FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f'vrf {vrf}', frrconfig)
             for protocol in v6_protocols:
                 # VyOS and FRR use a different name for OSPFv3 (IPv6)
                 if protocol == 'ospfv3':
                     protocol = 'ospf6'
                 route_map = f'route-map-{vrf}-{protocol}'
                 self.assertIn(f' ipv6 protocol {protocol} route-map {route_map}', frrconfig)
 
         # Delete route-maps
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_delete(['policy', 'route-map', f'route-map-{vrf}-{protocol}'])
             self.cli_delete(base + ['ipv6', 'protocol'])
 
         self.cli_commit()
 
         # Verify route-map properly is removed from FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertNotIn(f' ipv6 protocol', frrconfig)
 
     def test_vrf_vni_duplicates(self):
         base_table = '6300'
         table = base_table
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', str(table)])
             self.cli_set(base + ['vni', '100'])
             table = str(int(table) + 1)
 
         # L3VNIs can only be used once
         with self.assertRaises(ConfigSessionError):
             self.cli_commit()
 
         table = base_table
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['vni', str(table)])
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         for vrf in vrfs:
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
             # Increment table ID for the next run
             table = str(int(table) + 1)
 
     def test_vrf_vni_add_change_remove(self):
         base_table = '6300'
         table = base_table
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', str(table)])
             self.cli_set(base + ['vni', str(table)])
             table = str(int(table) + 1)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         for vrf in vrfs:
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
             # Increment table ID for the next run
             table = str(int(table) + 1)
 
         # Now change all L3VNIs (increment 2)
         # We must also change the base_table number as we probably could get
         # duplicate VNI's during the test as VNIs are applied 1:1 to FRR
         base_table = '5000'
         table = base_table
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['vni', str(table)])
             table = str(int(table) + 2)
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         for vrf in vrfs:
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
             # Increment table ID for the next run
             table = str(int(table) + 2)
 
 
         # add a new VRF with VNI - this must not delete any existing VRF/VNI
         purple = 'purple'
         table = str(int(table) + 10)
         self.cli_set(base_path + ['name', purple, 'table', table])
         self.cli_set(base_path + ['name', purple, 'vni', table])
 
         # commit changes
         self.cli_commit()
 
         # Verify VRF configuration
         table = base_table
         for vrf in vrfs:
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f' vni {table}', frrconfig)
             # Increment table ID for the next run
             table = str(int(table) + 2)
 
         # Verify purple VRF/VNI
         self.assertTrue(interface_exists(purple))
         table = str(int(table) + 10)
         frrconfig = self.getFRRconfig(f'vrf {purple}', endsection='^exit-vrf')
         self.assertIn(f' vni {table}', frrconfig)
 
         # Now delete all the VNIs
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_delete(base + ['vni'])
 
         # commit changes
         self.cli_commit()
 
         # Verify no VNI is defined
         for vrf in vrfs:
             self.assertTrue(interface_exists(vrf))
 
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertNotIn('vni', frrconfig)
 
         # Verify purple VNI remains
         self.assertTrue(interface_exists(purple))
         frrconfig = self.getFRRconfig(f'vrf {purple}', endsection='^exit-vrf')
         self.assertIn(f' vni {table}', frrconfig)
 
     def test_vrf_ip_ipv6_nht(self):
         table = '6910'
 
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
             self.cli_set(base + ['ip', 'nht', 'no-resolve-via-default'])
             self.cli_set(base + ['ipv6', 'nht', 'no-resolve-via-default'])
 
             table = str(int(table) + 1)
 
         self.cli_commit()
 
         # Verify route-map properly applied to FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertIn(f'vrf {vrf}', frrconfig)
             self.assertIn(f' no ip nht resolve-via-default', frrconfig)
             self.assertIn(f' no ipv6 nht resolve-via-default', frrconfig)
 
         # Delete route-maps
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_delete(base + ['ip'])
             self.cli_delete(base + ['ipv6'])
 
         self.cli_commit()
 
         # Verify route-map properly is removed from FRR
         for vrf in vrfs:
             frrconfig = self.getFRRconfig(f'vrf {vrf}', endsection='^exit-vrf')
             self.assertNotIn(f' no ip nht resolve-via-default', frrconfig)
             self.assertNotIn(f' no ipv6 nht resolve-via-default', frrconfig)
 
     def test_vrf_conntrack(self):
         table = '8710'
         nftables_rules = {
             'vrf_zones_ct_in': ['ct original zone set iifname map @ct_iface_map'],
             'vrf_zones_ct_out': ['ct original zone set oifname map @ct_iface_map']
         }
 
         self.cli_set(base_path + ['name', 'randomVRF', 'table', '1000'])
         self.cli_commit()
 
         # Conntrack rules should not be present
         for chain, rule in nftables_rules.items():
             self.verify_nftables_chain(rule, 'inet vrf_zones', chain, inverse=True)
 
         # conntrack is only enabled once NAT, NAT66 or firewalling is enabled
         self.cli_set(['nat'])
 
         for vrf in vrfs:
             base = base_path + ['name', vrf]
             self.cli_set(base + ['table', table])
             table = str(int(table) + 1)
             # We need the commit inside the loop to trigger the bug in T6603
             self.cli_commit()
 
         # Conntrack rules should now be present
         for chain, rule in nftables_rules.items():
             self.verify_nftables_chain(rule, 'inet vrf_zones', chain, inverse=False)
 
         # T6603: there should be only ONE entry for the iifname/oifname in the chains
         tmp = loads(cmd('sudo nft -j list table inet vrf_zones'))
         num_rules = len(search("nftables[].rule[].chain", tmp))
         # ['vrf_zones_ct_in', 'vrf_zones_ct_out']
         self.assertEqual(num_rules, 2)
 
         self.cli_delete(['nat'])
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index e4655fdf7..b161fe6ba 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -1,341 +1,341 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2020-2024 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 <http://www.gnu.org/licenses/>.
 
 # pylint: disable=redefined-outer-name
 
 import os
 import sys
 import grp
 import re
 import json
 import typing
 import logging
 import signal
 import traceback
 import importlib.util
 import io
 from contextlib import redirect_stdout
 
 import zmq
 
 from vyos.defaults import directories
 from vyos.utils.boot import boot_configuration_complete
 from vyos.configsource import ConfigSourceString
 from vyos.configsource import ConfigSourceError
 from vyos.configdiff import get_commit_scripts
 from vyos.config import Config
 from vyos.frrender import FRRender
 from vyos.frrender import get_frrender_dict
 from vyos import ConfigError
 
 CFG_GROUP = 'vyattacfg'
 
 script_stdout_log = '/tmp/vyos-configd-script-stdout'
 
 debug = True
 
 logger = logging.getLogger(__name__)
 logs_handler = logging.StreamHandler()
 logger.addHandler(logs_handler)
 
 if debug:
     logger.setLevel(logging.DEBUG)
 else:
     logger.setLevel(logging.INFO)
 
 SOCKET_PATH = 'ipc:///run/vyos-configd.sock'
 MAX_MSG_SIZE = 65535
 PAD_MSG_SIZE = 6
 
 # Response error codes
 R_SUCCESS = 1
 R_ERROR_COMMIT = 2
 R_ERROR_DAEMON = 4
 R_PASS = 8
 
 vyos_conf_scripts_dir = directories['conf_mode']
 configd_include_file = os.path.join(directories['data'], 'configd-include.json')
 configd_env_set_file = os.path.join(directories['data'], 'vyos-configd-env-set')
 configd_env_unset_file = os.path.join(directories['data'], 'vyos-configd-env-unset')
 # sourced on entering config session
 configd_env_file = '/etc/default/vyos-configd-env'
 
 def key_name_from_file_name(f):
     return os.path.splitext(f)[0]
 
 def module_name_from_key(k):
     return k.replace('-', '_')
 
 def path_from_file_name(f):
     return os.path.join(vyos_conf_scripts_dir, f)
 
 
 # opt-in to be run by daemon
 with open(configd_include_file) as f:
     try:
         include = json.load(f)
     except OSError as e:
         logger.critical(f'configd include file error: {e}')
         sys.exit(1)
     except json.JSONDecodeError as e:
         logger.critical(f'JSON load error: {e}')
         sys.exit(1)
 
 
 # import conf_mode scripts
 (_, _, filenames) = next(iter(os.walk(vyos_conf_scripts_dir)))
 filenames.sort()
 
 load_filenames = [f for f in filenames if f in include]
 imports = [key_name_from_file_name(f) for f in load_filenames]
 module_names = [module_name_from_key(k) for k in imports]
 paths = [path_from_file_name(f) for f in load_filenames]
 to_load = list(zip(module_names, paths))
 
 modules = []
 
 for x in to_load:
     spec = importlib.util.spec_from_file_location(x[0], x[1])
     module = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(module)
     modules.append(module)
 
 conf_mode_scripts = dict(zip(imports, modules))
 
 exclude_set = {key_name_from_file_name(f) for f in filenames if f not in include}
 include_set = {key_name_from_file_name(f) for f in filenames if f in include}
 
 
 def write_stdout_log(file_name, msg):
     if boot_configuration_complete():
         return
     with open(file_name, 'a') as f:
         f.write(msg)
 
 
 def run_script(script_name, config, args) -> tuple[int, str]:
     # pylint: disable=broad-exception-caught
 
     script = conf_mode_scripts[script_name]
     script.argv = args
     config.set_level([])
     try:
         c = script.get_config(config)
         script.verify(c)
         script.generate(c)
         script.apply(c)
     except ConfigError as e:
         logger.error(e)
         return R_ERROR_COMMIT, str(e)
     except Exception:
         tb = traceback.format_exc()
         logger.error(tb)
         return R_ERROR_COMMIT, tb
 
     return R_SUCCESS, ''
 
 
 def initialization(socket):
     # pylint: disable=broad-exception-caught,too-many-locals
 
     # Reset config strings:
     active_string = ''
     session_string = ''
     # check first for resent init msg, in case of client timeout
     while True:
         msg = socket.recv().decode('utf-8', 'ignore')
         try:
             message = json.loads(msg)
             if message['type'] == 'init':
                 resp = 'init'
                 socket.send(resp.encode())
         except Exception:
             break
 
     # zmq synchronous for ipc from single client:
     active_string = msg
     resp = 'active'
     socket.send(resp.encode())
     session_string = socket.recv().decode('utf-8', 'ignore')
     resp = 'session'
     socket.send(resp.encode())
     pid_string = socket.recv().decode('utf-8', 'ignore')
     resp = 'pid'
     socket.send(resp.encode())
     sudo_user_string = socket.recv().decode('utf-8', 'ignore')
     resp = 'sudo_user'
     socket.send(resp.encode())
     temp_config_dir_string = socket.recv().decode('utf-8', 'ignore')
     resp = 'temp_config_dir'
     socket.send(resp.encode())
     changes_only_dir_string = socket.recv().decode('utf-8', 'ignore')
     resp = 'changes_only_dir'
     socket.send(resp.encode())
 
     logger.debug(f'config session pid is {pid_string}')
     logger.debug(f'config session sudo_user is {sudo_user_string}')
 
     os.environ['SUDO_USER'] = sudo_user_string
     if temp_config_dir_string:
         os.environ['VYATTA_TEMP_CONFIG_DIR'] = temp_config_dir_string
     if changes_only_dir_string:
         os.environ['VYATTA_CHANGES_ONLY_DIR'] = changes_only_dir_string
 
     try:
         configsource = ConfigSourceString(running_config_text=active_string,
                                           session_config_text=session_string)
     except ConfigSourceError as e:
         logger.debug(e)
         return None
 
     config = Config(config_source=configsource)
     dependent_func: dict[str, list[typing.Callable]] = {}
     setattr(config, 'dependent_func', dependent_func)
 
     commit_scripts = get_commit_scripts(config)
     logger.debug(f'commit_scripts: {commit_scripts}')
 
     scripts_called = []
     setattr(config, 'scripts_called', scripts_called)
 
-    if not hasattr(config, 'frrender_cls'):
-        setattr(config, 'frrender_cls', FRRender())
-
     return config
 
 
 def process_node_data(config, data, _last: bool = False) -> tuple[int, str]:
     if not config:
         out = 'Empty config'
         logger.critical(out)
         return R_ERROR_DAEMON, out
 
     script_name = None
     os.environ['VYOS_TAGNODE_VALUE'] = ''
     args = []
     config.dependency_list.clear()
 
     res = re.match(r'^(VYOS_TAGNODE_VALUE=[^/]+)?.*\/([^/]+).py(.*)', data)
     if res.group(1):
         env = res.group(1).split('=')
         os.environ[env[0]] = env[1]
     if res.group(2):
         script_name = res.group(2)
     if not script_name:
         out = 'Missing script_name'
         logger.critical(out)
         return R_ERROR_DAEMON, out
     if res.group(3):
         args = res.group(3).split()
     args.insert(0, f'{script_name}.py')
 
     tag_value = os.getenv('VYOS_TAGNODE_VALUE', '')
     tag_ext = f'_{tag_value}' if tag_value else ''
     script_record = f'{script_name}{tag_ext}'
     scripts_called = getattr(config, 'scripts_called', [])
     scripts_called.append(script_record)
 
     if script_name not in include_set:
         return R_PASS, ''
 
     with redirect_stdout(io.StringIO()) as o:
         result, err_out = run_script(script_name, config, args)
     amb_out = o.getvalue()
     o.close()
 
     out = amb_out + err_out
 
     return result, out
 
 
 def send_result(sock, err, msg):
     msg = msg if msg else ''
     msg_size = min(MAX_MSG_SIZE, len(msg))
 
     err_rep = err.to_bytes(1)
     msg_size_rep = f'{msg_size:#0{PAD_MSG_SIZE}x}'
 
     logger.debug(f'Sending reply: error_code {err} with output')
     sock.send_multipart([err_rep, msg_size_rep.encode(), msg.encode()])
 
     write_stdout_log(script_stdout_log, msg)
 
 
 def remove_if_file(f: str):
     try:
         os.remove(f)
     except FileNotFoundError:
         pass
 
 
 def shutdown():
     remove_if_file(configd_env_file)
     os.symlink(configd_env_unset_file, configd_env_file)
     sys.exit(0)
 
 
 if __name__ == '__main__':
     context = zmq.Context()
     socket = context.socket(zmq.REP)
 
     # Set the right permissions on the socket, then change it back
     o_mask = os.umask(0)
     socket.bind(SOCKET_PATH)
     os.umask(o_mask)
 
     cfg_group = grp.getgrnam(CFG_GROUP)
     os.setgid(cfg_group.gr_gid)
 
     os.environ['VYOS_CONFIGD'] = 't'
 
     def sig_handler(signum, frame):
         # pylint: disable=unused-argument
         shutdown()
 
     signal.signal(signal.SIGTERM, sig_handler)
     signal.signal(signal.SIGINT, sig_handler)
 
     # Define the vyshim environment variable
     remove_if_file(configd_env_file)
     os.symlink(configd_env_set_file, configd_env_file)
 
-    config = None
+    # We only need one long-lived instance of FRRender
+    frr = FRRender()
 
+    config = None
     while True:
         #  Wait for next request from client
         msg = socket.recv().decode()
         logger.debug(f'Received message: {msg}')
         message = json.loads(msg)
 
         if message['type'] == 'init':
             resp = 'init'
             socket.send(resp.encode())
             config = initialization(socket)
         elif message['type'] == 'node':
             res, out = process_node_data(config, message['data'], message['last'])
             send_result(socket, res, out)
 
             if message['last'] and config:
                 scripts_called = getattr(config, 'scripts_called', [])
                 logger.debug(f'scripts_called: {scripts_called}')
 
-                if hasattr(config, 'frrender_cls') and res == R_SUCCESS:
-                    frrender_cls = getattr(config, 'frrender_cls')
+                if res == R_SUCCESS:
                     tmp = get_frrender_dict(config)
-                    if frrender_cls.generate(tmp):
-                        frrender_cls.apply()
+                    if frr.generate(tmp):
+                        # only apply a new FRR configuration if anything changed
+                        # in comparison to the previous applied configuration
+                        frr.apply()
         else:
             logger.critical(f'Unexpected message: {message}')