From 59bc19c14a84283adad555dce8536fd7198b82b3 Mon Sep 17 00:00:00 2001 From: Hamdy Khader Date: Thu, 10 May 2018 15:58:42 +0300 Subject: [PATCH] Use Param DHCP_OPT_CLIENT_ID_NUM Ironic is sending 'client-id' as a number (61) to meet rfc4776 [1], due to this change Neutron DHCP should support this option as well. [1] https://github.com/openstack/ironic/commit/228a2a7885e1b04d4180fe8daa2992884decaf6d Closes-Bug: #1770932 Change-Id: I9728354d5f9e08a0dc23900b2bc22b4a0aedb737 --- neutron/agent/linux/dhcp.py | 9 +++++++-- neutron/tests/unit/agent/linux/test_dhcp.py | 20 +++++++++++++++++++ ...-dhcp-allocation-fix-a4ebe8b55bb2c065.yaml | 8 ++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/ib-dhcp-allocation-fix-a4ebe8b55bb2c065.yaml diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index 55ba783fde5..e54442628cf 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -61,6 +61,9 @@ DNSMASQ_SERVICE_NAME = 'dnsmasq' DHCP_RELEASE_TRIES = 3 DHCP_RELEASE_TRIES_SLEEP = 0.3 +# this variable will be removed when neutron-lib is updated with this value +DHCP_OPT_CLIENT_ID_NUM = 61 + class DictModel(dict): """Convert dict into an object that provides attribute access to values.""" @@ -733,7 +736,8 @@ class Dnsmasq(DhcpLocalProcess): def _get_client_id(self, port): if self._get_port_extra_dhcp_opts(port): for opt in port.extra_dhcp_opts: - if opt.opt_name == edo_ext.DHCP_OPT_CLIENT_ID: + if opt.opt_name in (edo_ext.DHCP_OPT_CLIENT_ID, + DHCP_OPT_CLIENT_ID_NUM): return opt.opt_value def _read_hosts_file_leases(self, filename): @@ -1021,7 +1025,8 @@ class Dnsmasq(DhcpLocalProcess): [netaddr.IPAddress(ip.ip_address).version for ip in port.fixed_ips]) for opt in port.extra_dhcp_opts: - if opt.opt_name == edo_ext.DHCP_OPT_CLIENT_ID: + if opt.opt_name in (edo_ext.DHCP_OPT_CLIENT_ID, + DHCP_OPT_CLIENT_ID_NUM): continue opt_ip_version = opt.ip_version if opt_ip_version in port_ip_versions: diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py index 1773166bedf..0808c10a487 100644 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@ -356,6 +356,13 @@ class FakePortMultipleAgents2(object): self.extra_dhcp_opts = [] +class FakePortWithClientIdNum(object): + def __init__(self): + self.extra_dhcp_opts = [ + DhcpOpt(opt_name=dhcp.DHCP_OPT_CLIENT_ID_NUM, + opt_value='test_client_id_num')] + + class FakeV4HostRoute(object): def __init__(self): self.destination = '20.0.0.1/24' @@ -623,6 +630,14 @@ class FakeV4NetworkClientId(object): self.namespace = 'qdhcp-ns' +class FakeV4NetworkClientIdNum(object): + def __init__(self): + self.id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' + self.subnets = [FakeV4Subnet()] + self.ports = [FakePortWithClientIdNum()] + self.namespace = 'qdhcp-ns' + + class FakeV6Network(object): def __init__(self): self.id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb' @@ -2621,6 +2636,11 @@ class TestDnsmasq(TestBase): self._test__generate_opts_per_subnet_helper( config, True, network_class=FakeNonLocalSubnets) + def test_client_id_num(self): + dm = self._get_dnsmasq(FakeV4NetworkClientIdNum()) + self.assertEqual('test_client_id_num', + dm._get_client_id(FakePortWithClientIdNum())) + class TestDeviceManager(TestConfBase): def setUp(self): diff --git a/releasenotes/notes/ib-dhcp-allocation-fix-a4ebe8b55bb2c065.yaml b/releasenotes/notes/ib-dhcp-allocation-fix-a4ebe8b55bb2c065.yaml new file mode 100644 index 00000000000..7ddfa60466b --- /dev/null +++ b/releasenotes/notes/ib-dhcp-allocation-fix-a4ebe8b55bb2c065.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + For Infiniband support, Ironic needs to send the 'client-id' DHCP option + as a number in order for IP address assignment to work. + This is now supported in Neutron, and can be specified as option number + 61 as defined in RFC 4776. For more information see bug + `1770932 `_ \ No newline at end of file