Ensure drop flows on br-int at agent startup for DVR too
Commit90212b12
changed the OVS agent so adding vital drop flows on br-int (table 0 priority 2) for packets from physical bridges was deferred until DVR initialization later on. But if br-int has no flows from a previous run (eg after host reboot), then these packets will hit the NORMAL flow in table 60. And if there is more than one physical bridge, then the physical interfaces from the different bridges are now essentially connected at layer 2 and a network loop is possible in the time before the flows are added by DVR. Also the DVR code won't add them until after RPC calls to the server, so a loop is more likely if the server is not available. This patch restores adding these flows to when the physical bridges are first configured. Also updated a comment that was no longer correct and updated the unit test. Change-Id: I42c33fefaae6a7bee134779c840f35632823472e Closes-Bug: #1887148 Related-Bug: #1869808 (cherry picked from commitc1a77ef8b7
) (cherry picked from commit143fe8ff89
) (cherry picked from commit 6a861b8c8c28e5675ec2208057298b811ba2b649)
This commit is contained in:
parent
65a6010da7
commit
8181c5dbfe
|
@ -1366,28 +1366,13 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
||||||
self.int_ofports[physical_network] = int_ofport
|
self.int_ofports[physical_network] = int_ofport
|
||||||
self.phys_ofports[physical_network] = phys_ofport
|
self.phys_ofports[physical_network] = phys_ofport
|
||||||
|
|
||||||
# following drop operations are not necessary for
|
# Drop packets from physical bridges that have not matched a higher
|
||||||
# dvr agent setup_dvr_flows. So skip it if dvr enabled
|
# priority flow to set a local vlan. This prevents these stray
|
||||||
# the reason is for br_int it is duplicate
|
# packets from being forwarded to other physical bridges which
|
||||||
# for br_physical drop_port is dangerous because when dvr
|
# could cause a network loop in the physical network.
|
||||||
# enabled the highest flow on table=0 is 2 which means
|
self.int_br.drop_port(in_port=int_ofport)
|
||||||
# basically everything will be dropped until setup_dvr_flows
|
|
||||||
# got executed.
|
|
||||||
if not self.enable_distributed_routing:
|
if not self.enable_distributed_routing:
|
||||||
# These two drop flows are the root cause for the bug #1803919.
|
|
||||||
# And now we add a rpc check during agent start procedure. If
|
|
||||||
# ovs agent can not reach any neutron server, or all neutron
|
|
||||||
# servers are down, these flows will not be installed anymore.
|
|
||||||
# Bug #1803919 was fixed in that way.
|
|
||||||
# And as a reminder, we can not do much work on this. Because
|
|
||||||
# the bridge mappings can be varied. Provider (external)
|
|
||||||
# network can be implicitly set on any physical bridge
|
|
||||||
# due to the basic NORMAL flow.
|
|
||||||
# Different vlan range networks can also have many
|
|
||||||
# bridge map settings, these tenant network traffic can also be
|
|
||||||
# blocked by the following drop flows.
|
|
||||||
# block all untranslated traffic between bridges
|
|
||||||
self.int_br.drop_port(in_port=int_ofport)
|
|
||||||
br.drop_port(in_port=phys_ofport)
|
br.drop_port(in_port=phys_ofport)
|
||||||
|
|
||||||
if self.use_veth_interconnection:
|
if self.use_veth_interconnection:
|
||||||
|
|
|
@ -1370,7 +1370,9 @@ class TestOvsNeutronAgent(object):
|
||||||
self.assertIn('added_port_id', port_info['added'])
|
self.assertIn('added_port_id', port_info['added'])
|
||||||
self.assertNotIn('activated_port_id', port_info['added'])
|
self.assertNotIn('activated_port_id', port_info['added'])
|
||||||
|
|
||||||
def _test_setup_physical_bridges(self, port_exists=False):
|
def _test_setup_physical_bridges(self, port_exists=False,
|
||||||
|
dvr_enabled=False):
|
||||||
|
self.agent.enable_distributed_routing = dvr_enabled
|
||||||
with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\
|
with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\
|
||||||
mock.patch.object(sys, "exit"),\
|
mock.patch.object(sys, "exit"),\
|
||||||
mock.patch.object(self.agent, 'br_phys_cls') as phys_br_cls,\
|
mock.patch.object(self.agent, 'br_phys_cls') as phys_br_cls,\
|
||||||
|
@ -1427,8 +1429,13 @@ class TestOvsNeutronAgent(object):
|
||||||
'phy-br-eth', constants.NONEXISTENT_PEER),
|
'phy-br-eth', constants.NONEXISTENT_PEER),
|
||||||
]
|
]
|
||||||
expected_calls += [
|
expected_calls += [
|
||||||
mock.call.int_br.drop_port(in_port='int_ofport'),
|
mock.call.int_br.drop_port(in_port='int_ofport')
|
||||||
mock.call.phys_br.drop_port(in_port='phy_ofport'),
|
]
|
||||||
|
if not dvr_enabled:
|
||||||
|
expected_calls += [
|
||||||
|
mock.call.phys_br.drop_port(in_port='phy_ofport')
|
||||||
|
]
|
||||||
|
expected_calls += [
|
||||||
mock.call.int_br.set_db_attribute('Interface', 'int-br-eth',
|
mock.call.int_br.set_db_attribute('Interface', 'int-br-eth',
|
||||||
'options',
|
'options',
|
||||||
{'peer': 'phy-br-eth'}),
|
{'peer': 'phy-br-eth'}),
|
||||||
|
@ -1448,6 +1455,9 @@ class TestOvsNeutronAgent(object):
|
||||||
def test_setup_physical_bridges_port_exists(self):
|
def test_setup_physical_bridges_port_exists(self):
|
||||||
self._test_setup_physical_bridges(port_exists=True)
|
self._test_setup_physical_bridges(port_exists=True)
|
||||||
|
|
||||||
|
def test_setup_physical_bridges_dvr_enabled(self):
|
||||||
|
self._test_setup_physical_bridges(dvr_enabled=True)
|
||||||
|
|
||||||
def test_setup_physical_bridges_using_veth_interconnection(self):
|
def test_setup_physical_bridges_using_veth_interconnection(self):
|
||||||
self.agent.use_veth_interconnection = True
|
self.agent.use_veth_interconnection = True
|
||||||
with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\
|
with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\
|
||||||
|
|
Loading…
Reference in New Issue