Merge "[DVR] Reconfigure re-created physical bridges for dvr routers" into stable/ussuri

This commit is contained in:
Zuul 2020-06-10 17:21:16 +00:00 committed by Gerrit Code Review
commit fe5d772c9f
3 changed files with 76 additions and 14 deletions

View File

@ -128,10 +128,9 @@ class OVSDVRNeutronAgent(object):
self.enable_tunneling = enable_tunneling self.enable_tunneling = enable_tunneling
self.enable_distributed_routing = enable_distributed_routing self.enable_distributed_routing = enable_distributed_routing
self.bridge_mappings = bridge_mappings self.bridge_mappings = bridge_mappings
self.phys_brs = phys_brs
self.int_ofports = int_ofports self.int_ofports = int_ofports
self.phys_ofports = phys_ofports self.phys_ofports = phys_ofports
self.reset_ovs_parameters(integ_br, tun_br, self.reset_ovs_parameters(integ_br, tun_br, phys_brs,
patch_int_ofport, patch_tun_ofport) patch_int_ofport, patch_tun_ofport)
self.reset_dvr_parameters() self.reset_dvr_parameters()
self.dvr_mac_address = None self.dvr_mac_address = None
@ -143,17 +142,19 @@ class OVSDVRNeutronAgent(object):
def set_firewall(self, firewall=None): def set_firewall(self, firewall=None):
self.firewall = firewall self.firewall = firewall
def setup_dvr_flows(self): def setup_dvr_flows(self, bridge_mappings=None):
bridge_mappings = bridge_mappings or self.bridge_mappings
self.setup_dvr_flows_on_integ_br() self.setup_dvr_flows_on_integ_br()
self.setup_dvr_flows_on_tun_br() self.setup_dvr_flows_on_tun_br()
self.setup_dvr_flows_on_phys_br() self.setup_dvr_flows_on_phys_br(bridge_mappings)
self.setup_dvr_mac_flows_on_all_brs() self.setup_dvr_mac_flows_on_all_brs()
def reset_ovs_parameters(self, integ_br, tun_br, def reset_ovs_parameters(self, integ_br, tun_br, phys_brs,
patch_int_ofport, patch_tun_ofport): patch_int_ofport, patch_tun_ofport):
'''Reset the openvswitch parameters''' '''Reset the openvswitch parameters'''
self.int_br = integ_br self.int_br = integ_br
self.tun_br = tun_br self.tun_br = tun_br
self.phys_brs = phys_brs
self.patch_int_ofport = patch_int_ofport self.patch_int_ofport = patch_int_ofport
self.patch_tun_ofport = patch_tun_ofport self.patch_tun_ofport = patch_tun_ofport
@ -164,6 +165,15 @@ class OVSDVRNeutronAgent(object):
self.local_ports = {} self.local_ports = {}
self.registered_dvr_macs = set() self.registered_dvr_macs = set()
def reset_dvr_flows(self, integ_br, tun_br, phys_brs,
patch_int_ofport, patch_tun_ofport,
bridge_mappings=None):
'''Reset the openvswitch and DVR parameters and DVR flows'''
self.reset_ovs_parameters(
integ_br, tun_br, phys_brs, patch_int_ofport, patch_tun_ofport)
self.reset_dvr_parameters()
self.setup_dvr_flows(bridge_mappings)
def get_dvr_mac_address(self): def get_dvr_mac_address(self):
try: try:
self.get_dvr_mac_address_with_retry() self.get_dvr_mac_address_with_retry()
@ -239,10 +249,10 @@ class OVSDVRNeutronAgent(object):
self.tun_br.install_goto(table_id=constants.DVR_PROCESS, self.tun_br.install_goto(table_id=constants.DVR_PROCESS,
dest_table_id=constants.PATCH_LV_TO_TUN) dest_table_id=constants.PATCH_LV_TO_TUN)
def setup_dvr_flows_on_phys_br(self): def setup_dvr_flows_on_phys_br(self, bridge_mappings=None):
'''Setup up initial dvr flows into br-phys''' '''Setup up initial dvr flows into br-phys'''
bridge_mappings = bridge_mappings or self.bridge_mappings
for physical_network in self.bridge_mappings: for physical_network in bridge_mappings:
self.phys_brs[physical_network].install_goto( self.phys_brs[physical_network].install_goto(
in_port=self.phys_ofports[physical_network], in_port=self.phys_ofports[physical_network],
priority=2, priority=2,

View File

@ -1449,6 +1449,11 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
if bridge_mappings: if bridge_mappings:
sync = True sync = True
self.setup_physical_bridges(bridge_mappings) self.setup_physical_bridges(bridge_mappings)
if self.enable_distributed_routing:
self.dvr_agent.reset_dvr_flows(
self.int_br, self.tun_br, self.phys_brs,
self.patch_int_ofport, self.patch_tun_ofport,
bridge_mappings)
return sync return sync
def _check_bridge_datapath_id(self, bridge, datapath_ids_set): def _check_bridge_datapath_id(self, bridge, datapath_ids_set):
@ -2493,12 +2498,9 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
# with l2pop fdb entries update # with l2pop fdb entries update
self._report_state() self._report_state()
if self.enable_distributed_routing: if self.enable_distributed_routing:
self.dvr_agent.reset_ovs_parameters(self.int_br, self.dvr_agent.reset_dvr_flows(
self.tun_br, self.int_br, self.tun_br, self.phys_brs,
self.patch_int_ofport, self.patch_int_ofport, self.patch_tun_ofport)
self.patch_tun_ofport)
self.dvr_agent.reset_dvr_parameters()
self.dvr_agent.setup_dvr_flows()
# notify that OVS has restarted # notify that OVS has restarted
registry.publish( registry.publish(
callback_resources.AGENT, callback_resources.AGENT,

View File

@ -3953,6 +3953,56 @@ class TestOvsDvrNeutronAgent(object):
self.agent.ancillary_brs = mock.Mock() self.agent.ancillary_brs = mock.Mock()
self._test_scan_ports_failure('scan_ancillary_ports') self._test_scan_ports_failure('scan_ancillary_ports')
def test_ext_br_recreated(self):
self._setup_for_dvr_test()
reset_methods = (
'reset_ovs_parameters', 'reset_dvr_parameters',
'setup_dvr_flows_on_integ_br', 'setup_dvr_flows_on_tun_br',
'setup_dvr_flows_on_phys_br', 'setup_dvr_mac_flows_on_all_brs')
for method in reset_methods:
mock.patch.object(self.agent.dvr_agent, method).start()
bridge_mappings = {'physnet0': 'br-ex0',
'physnet1': 'br-ex1'}
ex_br_mocks = [mock.Mock(br_name='br-ex0'),
mock.Mock(br_name='br-ex1')]
phys_bridges = {'physnet0': ex_br_mocks[0],
'physnet1': ex_br_mocks[1]},
bridges_added = ['br-ex0']
with mock.patch.object(self.agent, 'check_ovs_status',
return_value=constants.OVS_NORMAL), \
mock.patch.object(self.agent, '_agent_has_updates',
side_effect=TypeError('loop exit')), \
mock.patch.dict(self.agent.bridge_mappings, bridge_mappings,
clear=True), \
mock.patch.dict(self.agent.phys_brs, phys_bridges,
clear=True), \
mock.patch.object(self.agent, 'setup_physical_bridges') as \
setup_physical_bridges, \
mock.patch.object(self.agent.ovs.ovsdb, 'idl_monitor') as \
mock_idl_monitor:
mock_idl_monitor.bridges_added = bridges_added
try:
self.agent.rpc_loop(polling_manager=mock.Mock())
except TypeError:
pass
# Setup bridges should be called once even if it will raise Runtime
# Error because TypeError is raised in _agent_has_updates to stop
# agent after first loop iteration
setup_physical_bridges.assert_called_once_with({'physnet0': 'br-ex0'})
# Ensure dvr_agent methods were called correctly
self.agent.dvr_agent.reset_ovs_parameters.assert_called_once_with(
self.agent.int_br, self.agent.tun_br, self.agent.phys_brs,
self.agent.patch_int_ofport, self.agent.patch_tun_ofport)
self.agent.dvr_agent.reset_dvr_parameters.assert_called_once_with()
(self.agent.dvr_agent.setup_dvr_flows_on_phys_br.
assert_called_once_with({'physnet0': 'br-ex0'}))
(self.agent.dvr_agent.setup_dvr_flows_on_integ_br.
assert_called_once_with())
(self.agent.dvr_agent.setup_dvr_flows_on_tun_br.
assert_called_once_with())
(self.agent.dvr_agent.setup_dvr_mac_flows_on_all_brs.
assert_called_once_with())
class TestOvsDvrNeutronAgentOSKen(TestOvsDvrNeutronAgent, class TestOvsDvrNeutronAgentOSKen(TestOvsDvrNeutronAgent,
ovs_test_base.OVSOSKenTestBase): ovs_test_base.OVSOSKenTestBase):