diff --git a/ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py b/ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py index 6e4cfc89..7efd40a1 100644 --- a/ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py +++ b/ovn_bgp_agent/drivers/openstack/nb_ovn_bgp_driver.py @@ -265,6 +265,9 @@ class NBOVNBGPDriver(driver_api.AgentDriverBase): # This means it is not a provider network self.ovn_tenant_ls[logical_switch] = True return False + if bridge_device not in self.ovn_bridge_mappings.values(): + # This node is not properly configured, no need to expose it + return False if not self.ovn_provider_ls.get(logical_switch): self.ovn_provider_ls[logical_switch] = { 'bridge_device': bridge_device, @@ -376,6 +379,9 @@ class NBOVNBGPDriver(driver_api.AgentDriverBase): if not bridge_device: # This means it is not a provider network return False + if bridge_device not in self.ovn_bridge_mappings.values(): + # This node is not properly configured, no need to expose it + return False if not self.ovn_provider_ls.get(logical_switch): self.ovn_provider_ls[logical_switch] = { 'bridge_device': bridge_device, diff --git a/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py b/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py index aa771d45..2458c6f8 100644 --- a/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py +++ b/ovn_bgp_agent/drivers/openstack/ovn_bgp_driver.py @@ -29,6 +29,7 @@ from ovn_bgp_agent.drivers.openstack.utils import ovs from ovn_bgp_agent.drivers.openstack.utils import wire as wire_utils from ovn_bgp_agent.drivers.openstack.watchers import bgp_watcher as watcher from ovn_bgp_agent import exceptions as agent_exc +from ovn_bgp_agent.utils import helpers from ovn_bgp_agent.utils import linux_net @@ -169,8 +170,9 @@ class OVNBGPDriver(driver_api.AgentDriverBase): extra_routes = {} for bridge_index, bridge_mapping in enumerate(bridge_mappings, 1): - network = bridge_mapping.split(":")[0] - bridge = bridge_mapping.split(":")[1] + network, bridge = helpers.parse_bridge_mapping(bridge_mapping) + if not network: + continue self.ovn_bridge_mappings[network] = bridge if not extra_routes.get(bridge): @@ -323,8 +325,9 @@ class OVNBGPDriver(driver_api.AgentDriverBase): if not bridge_device and not bridge_vlan: bridge_device, bridge_vlan = self._get_bridge_for_datapath( provider_datapath) - if not bridge_device: - return False + if (not bridge_device or + bridge_device not in self.ovn_bridge_mappings.values()): + return False localnet = self.ovn_provider_datapath.get(provider_datapath) if not localnet: diff --git a/ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py b/ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py index 0eb1c5ab..2b8d4adb 100644 --- a/ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py +++ b/ovn_bgp_agent/drivers/openstack/ovn_evpn_driver.py @@ -27,6 +27,7 @@ from ovn_bgp_agent.drivers.openstack.utils import ovn from ovn_bgp_agent.drivers.openstack.utils import ovs from ovn_bgp_agent.drivers.openstack.watchers import evpn_watcher as \ watcher +from ovn_bgp_agent.utils import helpers from ovn_bgp_agent.utils import linux_net @@ -127,8 +128,9 @@ class OVNEVPNDriver(driver_api.AgentDriverBase): bridge_mappings = self.ovs_idl.get_ovn_bridge_mappings() # 2) Get macs for bridge mappings for bridge_index, bridge_mapping in enumerate(bridge_mappings, 1): - network = bridge_mapping.split(":")[0] - bridge = bridge_mapping.split(":")[1] + network, bridge = helpers.parse_bridge_mapping(bridge_mapping) + if not network: + continue self.ovn_bridge_mappings[network] = bridge linux_net.ensure_arp_ndp_enabled_for_bridge(bridge, bridge_index) diff --git a/ovn_bgp_agent/drivers/openstack/utils/wire.py b/ovn_bgp_agent/drivers/openstack/utils/wire.py index 8ddbb424..d8ca5973 100644 --- a/ovn_bgp_agent/drivers/openstack/utils/wire.py +++ b/ovn_bgp_agent/drivers/openstack/utils/wire.py @@ -18,6 +18,7 @@ from oslo_log import log as logging from ovn_bgp_agent import constants from ovn_bgp_agent.drivers.openstack.utils import ovs from ovn_bgp_agent import exceptions as agent_exc +from ovn_bgp_agent.utils import helpers from ovn_bgp_agent.utils import linux_net @@ -37,8 +38,9 @@ def _ensure_base_wiring_config_underlay(idl, bridge_mappings, routing_tables): ovn_bridge_mappings = {} flows_info = {} for bridge_index, bridge_mapping in enumerate(bridge_mappings, 1): - network = bridge_mapping.split(":")[0] - bridge = bridge_mapping.split(":")[1] + network, bridge = helpers.parse_bridge_mapping(bridge_mapping) + if not network: + continue ovn_bridge_mappings[network] = bridge linux_net.ensure_routing_table_for_bridge( diff --git a/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py b/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py index 9d4b8710..bdd7c76f 100644 --- a/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py +++ b/ovn_bgp_agent/tests/unit/drivers/openstack/test_nb_ovn_bgp_driver.py @@ -330,6 +330,7 @@ class TestNBOVNBGPDriver(test_base.TestCase): mock_get_ls_localnet_info = mock.patch.object( self.nb_bgp_driver, '_get_ls_localnet_info').start() mock_get_ls_localnet_info.return_value = ('fake-localnet', 'br-ex', 10) + self.nb_bgp_driver.ovn_bridge_mappings = {'fake-localnet': 'br-ex'} cidr = row.external_ids.get(constants.OVN_CIDRS_EXT_ID_KEY) logical_switch = row.external_ids.get(constants.OVN_LS_NAME_EXT_ID_KEY) @@ -515,6 +516,7 @@ class TestNBOVNBGPDriver(test_base.TestCase): self.nb_bgp_driver, '_get_ls_localnet_info').start() mock_get_ls_localnet_info.return_value = ('fake-localnet', 'br-ex', 100) + self.nb_bgp_driver.ovn_bridge_mappings = {'fake-localnet': 'br-ex'} mock_expose_provider_port = mock.patch.object( self.nb_bgp_driver, '_expose_provider_port').start() row = fakes.create_object({ diff --git a/ovn_bgp_agent/tests/unit/utils/test_helpers.py b/ovn_bgp_agent/tests/unit/utils/test_helpers.py new file mode 100644 index 00000000..6b927683 --- /dev/null +++ b/ovn_bgp_agent/tests/unit/utils/test_helpers.py @@ -0,0 +1,43 @@ +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ovn_bgp_agent.tests import base as test_base +from ovn_bgp_agent.utils import helpers + + +class TestHelpers(test_base.TestCase): + + def setUp(self): + super(TestHelpers, self).setUp() + + def test_parse_bridge_mappings(self): + bridge_mappings = "provider-1:br-ex" + ret_net, ret_bridge = helpers.parse_bridge_mapping(bridge_mappings) + + self.assertEqual(ret_net, 'provider-1') + self.assertEqual(ret_bridge, 'br-ex') + + def test_parse_bridge_mappings_missing_mapping(self): + bridge_mappings = "" + ret_net, ret_bridge = helpers.parse_bridge_mapping(bridge_mappings) + + self.assertEqual(ret_net, None) + self.assertEqual(ret_bridge, None) + + def test_parse_bridge_mappings_wrong_format(self): + bridge_mappings = "provider-1:br-ex:extra_field" + ret_net, ret_bridge = helpers.parse_bridge_mapping(bridge_mappings) + + self.assertEqual(ret_net, None) + self.assertEqual(ret_bridge, None) diff --git a/ovn_bgp_agent/utils/helpers.py b/ovn_bgp_agent/utils/helpers.py new file mode 100644 index 00000000..9e7ec205 --- /dev/null +++ b/ovn_bgp_agent/utils/helpers.py @@ -0,0 +1,27 @@ +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from oslo_log import log as logging + +LOG = logging.getLogger(__name__) + + +def parse_bridge_mapping(bridge_mapping): + try: + network, bridge = bridge_mapping.split(":") + except ValueError: + LOG.warning("Incorrect bridge mapping settings: %s", + bridge_mapping) + return None, None + return network, bridge