From 5c433a027daab2419d974820589205253871885e Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Fri, 10 May 2019 10:47:00 +0200 Subject: [PATCH] [DHCP] Don't resync network if same port is alredy in cache Sometimes when port is created on dhcp agent's side, it may happend that same port is already in network cache. Before this patch if port with same IP address was already in cache, resync was rescheduled because of duplicate IPs found in cache. Now resync will be scheduled only if duplicate IP address belongs to port with different MAC address or different id. Change-Id: I23afbc10725f5dc78e3c63e6e505ef89ba8dc4a5 Closes-Bug: #1824802 --- neutron/agent/dhcp/agent.py | 9 ++++++--- neutron/tests/unit/agent/dhcp/test_agent.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/neutron/agent/dhcp/agent.py b/neutron/agent/dhcp/agent.py index af6774b3b6b..ba1fbc73cf1 100644 --- a/neutron/agent/dhcp/agent.py +++ b/neutron/agent/dhcp/agent.py @@ -587,11 +587,14 @@ class DhcpAgent(manager.Manager): return new_ips = {i['ip_address'] for i in created_port['fixed_ips']} for port_cached in network.ports: - # if there are other ports cached with the same ip address in - # the same network this indicate that the cache is out of sync + # if in the same network there are ports cached with the same + # ip address but different MAC address and/or different id, + # this indicate that the cache is out of sync cached_ips = {i['ip_address'] for i in port_cached['fixed_ips']} - if new_ips.intersection(cached_ips): + if (new_ips.intersection(cached_ips) and + (created_port['id'] != port_cached['id'] or + created_port['mac_address'] != port_cached['mac_address'])): self.schedule_resync("Duplicate IP addresses found, " "DHCP cache is out of sync", created_port.network_id) diff --git a/neutron/tests/unit/agent/dhcp/test_agent.py b/neutron/tests/unit/agent/dhcp/test_agent.py index ee27cbeab0a..a6db52d63a7 100644 --- a/neutron/tests/unit/agent/dhcp/test_agent.py +++ b/neutron/tests/unit/agent/dhcp/test_agent.py @@ -1175,6 +1175,21 @@ class TestDhcpAgentEventHandler(base.BaseTestCase): self.reload_allocations.assert_called_once_with(fake_port2, fake_network) + def test_port_create_end_no_resync_if_same_port_already_in_cache(self): + self.reload_allocations_p = mock.patch.object(self.dhcp, + 'reload_allocations') + self.reload_allocations = self.reload_allocations_p.start() + payload = dict(port=copy.deepcopy(fake_port2)) + cached_port = copy.deepcopy(fake_port2) + new_fake_network = copy.deepcopy(fake_network) + new_fake_network.ports = [cached_port] + self.cache.get_network_by_id.return_value = new_fake_network + self.dhcp.port_create_end(None, payload) + self.dhcp._process_resource_update() + self.reload_allocations.assert_called_once_with(fake_port2, + new_fake_network) + self.schedule_resync.assert_not_called() + def test_port_update_change_ip_on_port(self): payload = dict(port=fake_port1, priority=FAKE_PRIORITY) self.cache.get_network_by_id.return_value = fake_network