Ensure all vlan tags are processed

There may be serveral neutron vlan provider networks associated
to a physical bridge. For example, having ovs bridge-mappings
set to "datacentre:br-ex", and then have several provider networks
of vlan type associated to datacentre.

This was not being properly handled on the sync actions as only
the first vlan tag was being processed. This patch ensure all the
vlan tags associated to a bridge are processed and their respective
vlan devices are created

In addition, it seems the way of estimating the coverage has changed,
as now the value is higher, this patch also bumps the minimal coverage
(setting it to 92%), so that the coverage is not reduced unnoticed

Change-Id: I39168fa633f0a69439980c5a2fd163e389cf11fe
This commit is contained in:
Luis Tomas Bolivar 2023-04-27 18:59:43 +02:00
parent 9c7f8fc9f5
commit b46dcf8d7f
7 changed files with 20 additions and 18 deletions

View File

@ -177,17 +177,16 @@ class OVNBGPDriver(driver_api.AgentDriverBase):
linux_net.ensure_routing_table_for_bridge(
self.ovn_routing_tables, bridge,
CONF.bgp_vrf_table_id))
vlan_tag = self.sb_idl.get_network_vlan_tag_by_network_name(
vlan_tags = self.sb_idl.get_network_vlan_tag_by_network_name(
network)
if vlan_tag:
vlan_tag = vlan_tag[0]
for vlan_tag in vlan_tags:
linux_net.ensure_vlan_device_for_network(bridge,
vlan_tag)
linux_net.ensure_arp_ndp_enabled_for_bridge(bridge,
bridge_index,
vlan_tag)
vlan_tags)
if self.ovs_flows.get(bridge):
continue

View File

@ -157,12 +157,14 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
self.idl._session.reconnect.set_probe_interval(60000)
def get_network_vlan_tag_by_network_name(self, network_name):
tags = []
cmd = self.db_find_rows('Logical_Switch_Port', ('type', '=',
constants.OVN_LOCALNET_VIF_PORT_TYPE))
for row in cmd.execute(check_error=True):
if (row.options and
row.options.get('network_name') == network_name):
return row.tag
tags.append(row.tag[0])
return tags
def ls_has_virtual_ports(self, logical_switch):
ls = self.lookup('Logical_Switch', logical_switch)
@ -297,12 +299,14 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
return None, None
def get_network_vlan_tag_by_network_name(self, network_name):
tags = []
cmd = self.db_find_rows('Port_Binding', ('type', '=',
constants.OVN_LOCALNET_VIF_PORT_TYPE))
for row in cmd.execute(check_error=True):
if (row.options and
row.options.get('network_name') == network_name):
return row.tag
tags.append(row.tag[0])
return tags
def is_router_gateway_on_chassis(self, datapath, chassis):
port_info = self.get_ports_on_datapath(

View File

@ -45,16 +45,15 @@ def _ensure_base_wiring_config_underlay(idl, bridge_mappings, routing_tables):
linux_net.ensure_routing_table_for_bridge(
routing_tables, bridge, CONF.bgp_vrf_table_id)
vlan_tag = idl.get_network_vlan_tag_by_network_name(network)
vlan_tags = idl.get_network_vlan_tag_by_network_name(network)
if vlan_tag:
vlan_tag = vlan_tag[0]
for vlan_tag in vlan_tags:
linux_net.ensure_vlan_device_for_network(bridge,
vlan_tag)
linux_net.ensure_arp_ndp_enabled_for_bridge(bridge,
bridge_index,
vlan_tag)
vlan_tags)
if not flows_info.get(bridge):
with pyroute2.NDB() as ndb:
flows_info[bridge] = {

View File

@ -160,8 +160,8 @@ class TestNBOVNBGPDriver(test_base.TestCase):
mock_routing_bridge.assert_has_calls(expected_calls)
expected_calls = [mock.call('bridge0', 10), mock.call('bridge1', 11)]
mock_ensure_vlan_network.assert_has_calls(expected_calls)
expected_calls = [mock.call('bridge0', 1, 10),
mock.call('bridge1', 2, 11)]
expected_calls = [mock.call('bridge0', 1, [10]),
mock.call('bridge1', 2, [11])]
mock_ensure_arp.assert_has_calls(expected_calls)
expected_calls = [
mock.call('bridge0'), mock.call('bridge1')]

View File

@ -144,8 +144,8 @@ class TestOVNBGPDriver(test_base.TestCase):
self.bgp_driver.sync()
expected_calls = [mock.call('bridge0', 1, 10),
mock.call('bridge1', 2, 11)]
expected_calls = [mock.call('bridge0', 1, [10]),
mock.call('bridge1', 2, [11])]
mock_ensure_arp.assert_has_calls(expected_calls)
expected_calls = [mock.call({}, 'bridge0', CONF.bgp_vrf_table_id),

View File

@ -42,7 +42,7 @@ class TestOvsdbNbOvnIdl(test_base.TestCase):
def test_get_network_vlan_tag_by_network_name(self):
network_name = 'net0'
tag = 123
tag = [123]
lsp = fakes.create_object({'name': 'port-0',
'options': {'network_name': network_name},
'tag': tag})
@ -325,7 +325,7 @@ class TestOvsdbSbOvnIdl(test_base.TestCase):
def _test_get_network_vlan_tag_by_network_name(self, match=True):
network = 'public' if match else 'spongebob'
tag = 1001
tag = [1001]
row = fakes.create_object({
'options': {'network_name': 'public'},
'tag': tag})
@ -335,7 +335,7 @@ class TestOvsdbSbOvnIdl(test_base.TestCase):
if match:
self.assertEqual(tag, ret)
else:
self.assertIsNone(ret)
self.assertEqual([], ret)
def test_get_network_vlan_tag_by_network_name(self):
self._test_get_network_vlan_tag_by_network_name()

View File

@ -36,7 +36,7 @@ commands =
coverage combine
coverage html -d cover --omit='*tests*'
coverage xml -o cover/coverage.xml --omit='*tests*'
coverage report --fail-under=87 --skip-covered --omit='*tests*'
coverage report --fail-under=92 --skip-covered --omit='*tests*'
[testenv:docs]
deps = -r{toxinidir}/doc/requirements.txt