From 1daf945f832716b98b8c2d630cd2e730178a46fa Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Thu, 17 Sep 2015 09:53:46 -0700 Subject: [PATCH] Remove early yields in _iter_hosts in dhcp agent There were early yields in the DHCP agent to handling skipping lease setup for certain IPv6 addresses. However, the setup for name resolution in _output_addn_hosts_file depends on the same function so certain IPv6 addresses weren't getting name resolution. This patch adjusts the function to return a flag indicating that DHCP isn't required for the port so the callers setting up reservations can skip based on that and the name resolution setup can continue as normal. Change-Id: I81b4669eadaa9119e08c6a5e1d2a7b5959babdcc Closes-Bug: #1498665 --- neutron/agent/linux/dhcp.py | 28 +++++++++------------ neutron/tests/unit/agent/linux/test_dhcp.py | 11 +++++--- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index f27ac4353..c79f6577d 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -512,6 +512,7 @@ class Dnsmasq(DhcpLocalProcess): # an IPv6 address because of stateless DHCPv6 network. host_name, # Host name. name, # Canonical hostname in the format 'hostname[.domain]'. + no_dhcp, # A flag indicating that the address doesn't need DHCP. ) """ v6_nets = dict((subnet.id, subnet) for subnet in @@ -526,17 +527,11 @@ class Dnsmasq(DhcpLocalProcess): if dns_assignment: dns_ip_map = {d.ip_address: d for d in dns_assignment} for alloc in fixed_ips: - # Note(scollins) Only create entries that are - # associated with the subnet being managed by this - # dhcp agent + no_dhcp = False if alloc.subnet_id in v6_nets: addr_mode = v6_nets[alloc.subnet_id].ipv6_address_mode - if addr_mode == constants.IPV6_SLAAC: - continue - elif addr_mode == constants.DHCPV6_STATELESS: - alloc = hostname = fqdn = None - yield (port, alloc, hostname, fqdn) - continue + no_dhcp = addr_mode in (constants.IPV6_SLAAC, + constants.DHCPV6_STATELESS) # If dns_name attribute is supported by ports API, return the # dns_assignment generated by the Neutron server. Otherwise, @@ -550,7 +545,7 @@ class Dnsmasq(DhcpLocalProcess): fqdn = hostname if self.conf.dhcp_domain: fqdn = '%s.%s' % (fqdn, self.conf.dhcp_domain) - yield (port, alloc, hostname, fqdn) + yield (port, alloc, hostname, fqdn, no_dhcp) def _get_port_extra_dhcp_opts(self, port): return getattr(port, edo_ext.EXTRADHCPOPTS, False) @@ -582,9 +577,10 @@ class Dnsmasq(DhcpLocalProcess): timestamp = int(time.time()) + self.conf.dhcp_lease_duration dhcp_enabled_subnet_ids = [s.id for s in self.network.subnets if s.enable_dhcp] - for (port, alloc, hostname, name) in self._iter_hosts(): - # don't write ip address which belongs to a dhcp disabled subnet. - if not alloc or alloc.subnet_id not in dhcp_enabled_subnet_ids: + for (port, alloc, hostname, name, no_dhcp) in self._iter_hosts(): + # don't write ip address which belongs to a dhcp disabled subnet + # or an IPv6 SLAAC/stateless subnet + if no_dhcp or alloc.subnet_id not in dhcp_enabled_subnet_ids: continue ip_address = self._format_address_for_dnsmasq(alloc.ip_address) @@ -631,8 +627,8 @@ class Dnsmasq(DhcpLocalProcess): if s.enable_dhcp] # NOTE(ihrachyshka): the loop should not log anything inside it, to # avoid potential performance drop when lots of hosts are dumped - for (port, alloc, hostname, name) in self._iter_hosts(): - if not alloc: + for (port, alloc, hostname, name, no_dhcp) in self._iter_hosts(): + if no_dhcp: if self._get_port_extra_dhcp_opts(port): buf.write('%s,%s%s\n' % (port.mac_address, 'set:', port.id)) @@ -726,7 +722,7 @@ class Dnsmasq(DhcpLocalProcess): file. """ buf = six.StringIO() - for (port, alloc, hostname, fqdn) in self._iter_hosts(): + for (port, alloc, hostname, fqdn, no_dhcp) in self._iter_hosts(): # It is compulsory to write the `fqdn` before the `hostname` in # order to obtain it in PTR responses. if alloc: diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py index d82c02f12..929cc2d35 100644 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@ -148,7 +148,9 @@ class FakePort4(object): 'dddddddd-dddd-dddd-dddd-dddddddddddd'), FakeIPAllocation('ffda:3ba5:a17a:4ba3:0216:3eff:fec2:771d', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee')] - dns_assignment = [FakeDNSAssignment('192.168.0.4')] + dns_assignment = [ + FakeDNSAssignment('192.168.0.4'), + FakeDNSAssignment('ffda:3ba5:a17a:4ba3:0216:3eff:fec2:771d')] mac_address = '00:16:3E:C2:77:1D' device_id = 'fake_port4' @@ -213,7 +215,8 @@ class FakeV6PortExtraOpt(object): device_owner = 'foo3' fixed_ips = [FakeIPAllocation('ffea:3ba5:a17a:4ba3:0216:3eff:fec2:771d', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee')] - dns_assignment = [] + dns_assignment = [ + FakeDNSAssignment('ffea:3ba5:a17a:4ba3:0216:3eff:fec2:771d')] mac_address = '00:16:3e:c2:77:1d' device_id = 'fake_port6' @@ -232,7 +235,9 @@ class FakeDualPortWithV6ExtraOpt(object): 'dddddddd-dddd-dddd-dddd-dddddddddddd'), FakeIPAllocation('ffea:3ba5:a17a:4ba3:0216:3eff:fec2:771d', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee')] - dns_assignment = [FakeDNSAssignment('192.168.0.3')] + dns_assignment = [ + FakeDNSAssignment('192.168.0.3'), + FakeDNSAssignment('ffea:3ba5:a17a:4ba3:0216:3eff:fec2:771d')] mac_address = '00:16:3e:c2:77:1d' device_id = 'fake_port6' -- 2.45.2