Add option to avoid VRF removal

A usecase posisble when operator wants to have a peering established
per-VRF. This would mean, that they need to enslave a unique
interface inside of the VRF and define peers for the router in FRR.

Current logic with removal of the VRF upon disconnect makes such
usecase impossible, as there are no means inside of the agent
to recover FRR and VRF configuration to intended by operator state.

This serves as motivation to allow operator to disable VRF removal
through configuration option.

Closes-Bug: #2097121
Change-Id: I2155508b167f84289de8f6510dfca1d5fc6a2a74
This commit is contained in:
Dmitriy Rabotyagov 2025-01-31 17:32:03 +01:00
parent f90262e7d3
commit 0840f4afc9
4 changed files with 38 additions and 6 deletions

View File

@ -102,6 +102,12 @@ agent_opts = [
help='If enabled, all routes are removed from the VRF table'
'(specified by bgp_vrf_table_id option) at startup.',
default=False),
cfg.BoolOpt('delete_vrf_on_disconnect',
help='If enabled agent will take care of completely deleting'
'VRF from both kernel and FRR configuration.'
'Disabling option will keep VRF even when agent considers'
'its presence as redundant',
default=True),
cfg.StrOpt('bgp_nic',
default='bgp-nic',
help='The name of the interface used within the VRF '

View File

@ -112,15 +112,20 @@ class EvpnBridge:
LOG.info('Disconnecting evpn bridge %s',
self.vrf_name)
for devname in [self.bridge_name, self.vxlan_name, self.vrf_name]:
disconnect_devices = [self.bridge_name, self.vxlan_name]
if CONF.delete_vrf_on_disconnect:
disconnect_devices.append(self.vrf_name)
for devname in disconnect_devices:
LOG.info('Delete device %s', devname)
linux_net.delete_device(devname)
# We need to do the frr reconfigure after deleting all devices.
# otherwise, frr will throw an error that it can only delete
# inactive vrf's
LOG.debug('Configure FRR VRF (del)')
frr.vrf_reconfigure(self.evpn_opts, action="del-vrf")
if CONF.delete_vrf_on_disconnect:
# We need to do the frr reconfigure after deleting all devices.
# otherwise, frr will throw an error that it can only delete
# inactive vrf's
LOG.debug('Configure FRR VRF (del)')
frr.vrf_reconfigure(self.evpn_opts, action="del-vrf")
self._setup_done = False

View File

@ -219,6 +219,19 @@ class TestEVPN(test_base.TestCase):
self.assertFalse(bridge._setup_done)
def test_evpnbridge_disconnect_keep_vrf(self):
bridge = self._create_bridge()
bridge._setup_done = True
CONF.set_override('delete_vrf_on_disconnect', False)
bridge.disconnect()
calls = [mock.call('br-100'),
mock.call('vxlan-100')]
self.mock_linux_net.delete_device.assert_has_calls(calls)
self.mock_frr.vrf_reconfigure.assert_not_called()
self.assertFalse(bridge._setup_done)
def test_evpnbridge_connect_vlan_again(self):
port, bridge, evpn_vlan = self._create_bridge_and_vlan()

View File

@ -0,0 +1,8 @@
---
features:
- |
Added configuration option ``delete_vrf_on_disconnect`` which prevents
deletion of VRF from FRR and Linux kernel networking. This allows to
establish a peering session within VRF as well as externally enslave
additional interfaces into VRF in case EVPN integration with the rest of
infrastructure is not preferable.