diff --git a/ovn_bgp_agent/config.py b/ovn_bgp_agent/config.py index d704ecb0..fe57b298 100644 --- a/ovn_bgp_agent/config.py +++ b/ovn_bgp_agent/config.py @@ -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 ' diff --git a/ovn_bgp_agent/drivers/openstack/utils/evpn.py b/ovn_bgp_agent/drivers/openstack/utils/evpn.py index 40def89a..7ba06b9a 100644 --- a/ovn_bgp_agent/drivers/openstack/utils/evpn.py +++ b/ovn_bgp_agent/drivers/openstack/utils/evpn.py @@ -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 diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py b/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py index 3e85931c..5df3d993 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/utils/test_evpn.py @@ -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() diff --git a/releasenotes/notes/skip_vrf_delete-fcc8ac95db4fde21.yaml b/releasenotes/notes/skip_vrf_delete-fcc8ac95db4fde21.yaml new file mode 100644 index 00000000..ef367d47 --- /dev/null +++ b/releasenotes/notes/skip_vrf_delete-fcc8ac95db4fde21.yaml @@ -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.