From 9b809126a219854eedf4ce8e8f48195381123e4c Mon Sep 17 00:00:00 2001 From: Daniel Alvarez Date: Fri, 29 Sep 2017 14:26:23 +0200 Subject: [PATCH] Allow to configure DHCP T1 and T2 timers in dnsmasq This patch introduces two new options for dnsmasq in neutron-dhcp-agent: * dhcp_renewal_time (T1): This option specifies the time interval from address assignment until the client transitions to the RENEWING state. * dhcp_rebinding_time (T2): This option specifies the time interval from address assignment until the client transitions to the REBINDING state. By allowing to set these timers we can configure both the renewal and rebinding times (options 58 and 59 as per RFC2132) and, for example allow to change some parameters (like MTU) on instances without having to wait or the lease time. The advantage of changing T1 over the lease time is that if the DHCP server becomes unreachable within the lease time, instances won't drop their IP addresses and won't cause a dataplane disruption. Change-Id: I29d417d459e92f36c1077962b92fa4c43dfaa97d Signed-off-by: Daniel Alvarez --- neutron/agent/linux/dhcp.py | 8 ++++++++ neutron/conf/agent/dhcp.py | 6 ++++++ neutron/tests/unit/agent/linux/test_dhcp.py | 13 ++++++++++++- ..._dhcp_dnsmasq_t1t2_options-3cef427d8109c165.yaml | 11 +++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/add_dhcp_dnsmasq_t1t2_options-3cef427d8109c165.yaml diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index a46bc12f01c..dfac0f360fe 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -403,6 +403,14 @@ class Dnsmasq(DhcpLocalProcess): cmd.append('--dhcp-lease-max=%d' % min(possible_leases, self.conf.dnsmasq_lease_max)) + if self.conf.dhcp_renewal_time > 0: + cmd.append('--dhcp-option-force=option:T1,%ds' % + self.conf.dhcp_renewal_time) + + if self.conf.dhcp_rebinding_time > 0: + cmd.append('--dhcp-option-force=option:T2,%ds' % + self.conf.dhcp_rebinding_time) + cmd.append('--conf-file=%s' % self.conf.dnsmasq_config_file) for server in self.conf.dnsmasq_dns_servers: cmd.append('--server=%s' % server) diff --git a/neutron/conf/agent/dhcp.py b/neutron/conf/agent/dhcp.py index 8433fb7c7bf..7cca7295985 100644 --- a/neutron/conf/agent/dhcp.py +++ b/neutron/conf/agent/dhcp.py @@ -94,6 +94,12 @@ DNSMASQ_OPTS = [ help=_('Limit number of leases to prevent a denial-of-service.')), cfg.BoolOpt('dhcp_broadcast_reply', default=False, help=_("Use broadcast in DHCP replies.")), + cfg.IntOpt('dhcp_renewal_time', default=0, + help=_("DHCP renewal time T1 (in seconds). If set to 0, it " + "will default to half of the lease time.")), + cfg.IntOpt('dhcp_rebinding_time', default=0, + help=_("DHCP rebinding time T2 (in seconds). If set to 0, it " + "will default to 7/8 of the lease time.")), ] diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py index d155cc94c31..eb8edb8bf2c 100644 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@ -1173,7 +1173,7 @@ class TestDnsmasq(TestBase): def _test_spawn(self, extra_options, network=FakeDualNetwork(), max_leases=16777216, lease_duration=86400, has_static=True, no_resolv='--no-resolv', - has_stateless=True): + has_stateless=True, dhcp_t1=0, dhcp_t2=0): def mock_get_conf_file_name(kind): return '/dhcp/%s/%s' % (network.id, kind) @@ -1230,6 +1230,11 @@ class TestDnsmasq(TestBase): expected.append('--dhcp-lease-max=%d' % min( possible_leases, max_leases)) + + if dhcp_t1: + expected.append('--dhcp-option-force=option:T1,%ds' % dhcp_t1) + if dhcp_t2: + expected.append('--dhcp-option-force=option:T2,%ds' % dhcp_t2) expected.extend(extra_options) self.execute.return_value = ('', '') @@ -1361,6 +1366,12 @@ class TestDnsmasq(TestBase): self._test_spawn(['--conf-file=', '--domain=openstacklocal'], network) + def test_spawn_cfg_with_dhcp_timers(self): + self.conf.set_override('dhcp_renewal_time', 30) + self.conf.set_override('dhcp_rebinding_time', 100) + self._test_spawn(['--conf-file=', '--domain=openstacklocal'], + dhcp_t1=30, dhcp_t2=100) + def _test_output_init_lease_file(self, timestamp): expected = [ '00:00:80:aa:bb:cc 192.168.0.2 * *', diff --git a/releasenotes/notes/add_dhcp_dnsmasq_t1t2_options-3cef427d8109c165.yaml b/releasenotes/notes/add_dhcp_dnsmasq_t1t2_options-3cef427d8109c165.yaml new file mode 100644 index 00000000000..c8f6e5a14d2 --- /dev/null +++ b/releasenotes/notes/add_dhcp_dnsmasq_t1t2_options-3cef427d8109c165.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Allow configuration of DHCP renewal (T1) and rebinding (T2) timers in + ``neutron-dhcp-agent``. By allowing these timers to be set (options 58 + and 59 as per RFC2132) in ``dnsmasq`` it allows users to change + other parameters, like MTU, on instances without having to wait for + the lease time to expire. The advantage of changing T1 over the + lease time is that if the DHCP server becomes unreachable within + the lease time, instances will not drop their IP addresses and it + will not cause a dataplane disruption.