Ensure agent is protected again wrong/missing bridge mappings

If the bridge mappings are changed to a wrong value, we should not
expose the previous IPs. This is needed to ensure the traffic is
only exposed in the right node.

Closes-Bug: #2025057
Change-Id: I5d56801ae87d2640d9671aaef65bc94228c60f52
This commit is contained in:
Luis Tomas Bolivar 2023-06-26 14:32:28 +02:00
parent 439efdb30a
commit 6c765fcd66
7 changed files with 93 additions and 8 deletions

View File

@ -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,

View File

@ -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:

View File

@ -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)

View File

@ -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(

View File

@ -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({

View File

@ -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)

View File

@ -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