Browse Source

Don't configure dnsmasq entries for "network" ports

Ports with device_owner like:
* floating_ip,
* DHCP,
* some types of router ports, like: HA interface interface,
* distributed ports,
don't need to be configured in the dnsmasq file.
So there is no need to reload dnsmasq every time when such port is
added/updated to the network.

This patch adds skip in such case which should improve load on the
Neutron DHCP agent.

Closes-Bug: #1913269
Change-Id: I63221507713b941c261cdf88781133149da8ab8d
(cherry picked from commit e4bbeee206)
changes/20/777120/1
Slawek Kaplonski 8 months ago
parent
commit
1239ac5023
  1. 6
      neutron/agent/dhcp/agent.py
  2. 20
      neutron/agent/linux/dhcp.py
  3. 14
      neutron/tests/unit/agent/linux/test_dhcp.py
  4. 6
      releasenotes/notes/do-not-create-dhcp-entries-for-all-types-of-ports-39c03b3782d2753e.yaml

6
neutron/agent/dhcp/agent.py

@ -602,6 +602,8 @@ class DhcpAgent(manager.Manager):
def port_update_end(self, context, payload):
"""Handle the port.update.end notification event."""
updated_port = dhcp.DictModel(payload['port'])
if not dhcp.port_requires_dhcp_configuration(updated_port):
return
if self.cache.is_port_message_stale(updated_port):
LOG.debug("Discarding stale port update: %s", updated_port)
return
@ -626,6 +628,8 @@ class DhcpAgent(manager.Manager):
def reload_allocations(self, port, network, prio=False):
LOG.info("Trigger reload_allocations for port %s on network %s",
port, network)
if not dhcp.port_requires_dhcp_configuration(port):
return
driver_action = 'reload_allocations'
if self._is_port_on_this_agent(port):
orig = self.cache.get_port_by_id(port['id'])
@ -664,6 +668,8 @@ class DhcpAgent(manager.Manager):
def port_create_end(self, context, payload):
"""Handle the port.create.end notification event."""
created_port = dhcp.DictModel(payload['port'])
if not dhcp.port_requires_dhcp_configuration(created_port):
return
update = DHCPResourceUpdate(created_port.network_id,
payload.get('priority', DEFAULT_PRIORITY),
action='_port_create',

20
neutron/agent/linux/dhcp.py

@ -59,6 +59,23 @@ HOST_DHCPV6_TAG = 'tag:dhcpv6,'
DHCP_OPT_CLIENT_ID_NUM = 61
def port_requires_dhcp_configuration(port):
if not getattr(port, 'device_owner', None):
# We can't check if port needs dhcp entry, so it will be better
# to create one
return True
# TODO(slaweq): define this list as a constant in neutron_lib.constants
# NOTE(slaweq): Not all port types which belongs e.g. to the routers can be
# excluded from that list. For some of them, like router interfaces used to
# plug subnet to the router should be configured in dnsmasq to provide DNS
# naming resolution. Otherwise it may slowdown e.g. traceroutes from the VM
return port.device_owner not in [
constants.DEVICE_OWNER_ROUTER_HA_INTF,
constants.DEVICE_OWNER_FLOATINGIP,
constants.DEVICE_OWNER_DHCP,
constants.DEVICE_OWNER_DISTRIBUTED]
class DictModel(collections.abc.MutableMapping):
"""Convert dict into an object that provides attribute access to values."""
@ -723,6 +740,9 @@ class Dnsmasq(DhcpLocalProcess):
if subnet.ip_version == 6)
for port in self.network.ports:
if not port_requires_dhcp_configuration(port):
continue
fixed_ips = self._sort_fixed_ips_for_dnsmasq(port.fixed_ips,
v6_nets)
# TODO(hjensas): Drop this conditional and option once distros

14
neutron/tests/unit/agent/linux/test_dhcp.py

@ -308,6 +308,19 @@ class FakeRouterPort(object):
for ip in self.fixed_ips]
class FakeRouterHAPort(object):
def __init__(self):
self.id = 'hahahaha-haha-haha-haha-hahahahahaha'
self.admin_state_up = True
self.device_owner = constants.DEVICE_OWNER_ROUTER_HA_INTF
self.mac_address = '00:00:0f:aa:aa:aa'
self.device_id = 'fake_router_ha_port'
self.dns_assignment = []
self.extra_dhcp_opts = []
self.fixed_ips = [FakeIPAllocation(
'169.254.169.20', 'dddddddd-dddd-dddd-dddd-dddddddddddd')]
class FakeRouterPortNoDHCP(object):
def __init__(self, dev_owner=constants.DEVICE_OWNER_ROUTER_INTF,
ip_address='192.168.0.1', domain='openstacklocal'):
@ -694,6 +707,7 @@ class FakeDualNetwork(object):
self.namespace = 'qdhcp-ns'
self.ports = [FakePort1(domain=domain), FakeV6Port(domain=domain),
FakeDualPort(domain=domain),
FakeRouterHAPort(),
FakeRouterPort(domain=domain)]

6
releasenotes/notes/do-not-create-dhcp-entries-for-all-types-of-ports-39c03b3782d2753e.yaml

@ -0,0 +1,6 @@
---
other:
- |
To improve performance of the DHCP agent, it will no longer configure the DHCP server
for every port type created in Neutron. For example, for floating IP or router HA
interfaces there is no need since a client will not make a DHCP request for them
Loading…
Cancel
Save