Trigger router update only when gateway port IP changed

During the ha router state change event, the gateway port only
changed the L2 binding host. So l3 agent has the entire gateway
port information. It is not necessary to send a router_update
message to l3 agent again.

Depends-On: https://review.opendev.org/708825/
Closes-Bug: #1795127
Change-Id: Ia332421aff995f42e7a6e6e96b74be1338d54fe1
(cherry picked from commit 452b282412)
This commit is contained in:
LIU Yulong 2018-09-29 18:04:10 +08:00 committed by Bernard Cafarelli
parent 54e1a6b1bc
commit 4f7e1f6b9f
3 changed files with 82 additions and 4 deletions

View File

@ -799,3 +799,25 @@ def disable_extension_by_service_plugin(core_plugin, service_plugin):
core_plugin.supported_extension_aliases.remove('filter-validation')
LOG.info('Disable filter validation extension by service plugin '
'%s.', service_plugin.__class__.__name__)
def get_port_fixed_ips_set(port):
return set([ip["ip_address"] for ip in port.get("fixed_ips", [])])
def port_ip_changed(new_port, original_port):
if not new_port or not original_port:
return False
# Quantity is not same, so it is changed.
if (len(new_port.get("fixed_ips", [])) !=
len(original_port.get("fixed_ips", []))):
return True
# IPs can be placed in any order, so use python set to verify the
# fixed IP addresses.
if (get_port_fixed_ips_set(new_port) !=
get_port_fixed_ips_set(original_port)):
return True
return False

View File

@ -527,6 +527,15 @@ def _notify_l3_agent_port_update(resource, event, trigger, **kwargs):
new_port = kwargs.get('port')
original_port = kwargs.get('original_port')
is_fixed_ips_changed = n_utils.port_ip_changed(new_port, original_port)
if (original_port['device_owner'] in
[n_const.DEVICE_OWNER_HA_REPLICATED_INT,
n_const.DEVICE_OWNER_ROUTER_SNAT,
n_const.DEVICE_OWNER_ROUTER_GW] and
not is_fixed_ips_changed):
return
if new_port and original_port:
l3plugin = directory.get_plugin(plugin_constants.L3)
context = kwargs['context']
@ -616,10 +625,6 @@ def _notify_l3_agent_port_update(resource, event, trigger, **kwargs):
l3plugin, context, original_port, address_pair)
return
is_fixed_ips_changed = (
'fixed_ips' in new_port and
'fixed_ips' in original_port and
new_port['fixed_ips'] != original_port['fixed_ips'])
if kwargs.get('mac_address_updated') or is_fixed_ips_changed:
l3plugin.update_arp_entry_for_dvr_service_port(
context, new_port)

View File

@ -1029,10 +1029,12 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
'context': self.adminContext,
'original_port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': DEVICE_OWNER_COMPUTE,
'mac_address': '02:04:05:17:18:19'
},
'port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': DEVICE_OWNER_COMPUTE,
'mac_address': '02:04:05:17:18:29'
},
'mac_address_updated': True
@ -1047,6 +1049,55 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
self.adminContext, kwargs.get('port'))
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
def test__notify_l3_agent_update_port_with_ip_update(self):
kwargs = {
'context': self.adminContext,
'original_port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': constants.DEVICE_OWNER_ROUTER_GW,
'fixed_ips': [{'ip_address': '1.1.1.1'}],
'mac_address': '02:04:05:17:18:19'
},
'port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': constants.DEVICE_OWNER_ROUTER_GW,
'fixed_ips': [{'ip_address': '2.2.2.2'}],
'mac_address': '02:04:05:17:18:19'
},
'mac_address_updated': False
}
l3plugin = mock.Mock()
directory.add_plugin(plugin_constants.L3, l3plugin)
l3_dvrscheduler_db._notify_l3_agent_port_update(
'port', 'after_update', mock.ANY, **kwargs)
l3plugin.update_arp_entry_for_dvr_service_port.\
assert_called_once_with(
self.adminContext, kwargs.get('port'))
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
def test__notify_l3_agent_update_port_without_ip_change(self):
kwargs = {
'context': self.adminContext,
'original_port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': constants.DEVICE_OWNER_ROUTER_GW,
'fixed_ips': [{'ip_address': '1.1.1.1'}],
},
'port': {
portbindings.HOST_ID: 'vm-host',
'device_owner': constants.DEVICE_OWNER_ROUTER_GW,
'fixed_ips': [{'ip_address': '1.1.1.1'}],
},
}
l3plugin = mock.Mock()
directory.add_plugin(plugin_constants.L3, l3plugin)
l3_dvrscheduler_db._notify_l3_agent_port_update(
'port', 'after_update', mock.ANY, **kwargs)
self.assertFalse(l3plugin.update_arp_entry_for_dvr_service_port.called)
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
def test__notify_l3_agent_port_binding_change(self):
self._test__notify_l3_agent_port_binding_change()