commit 922a8bbe1b27b08a703ad51d90773718aa0c55a9 Author: Moshe Levi Date: Tue Jul 28 22:26:15 2020 +0300 support client-id hardware In CentOS 8 dhclient is set by default with send dhcp-client-identifier = hardware. This flag sends client-id in hardware format. In CentOS 7 this flag is not set by default therefore the client-id sent in legacy format. At the moment legacy fromat is broken in CentOS 8 see https://bugzilla.redhat.com/show_bug.cgi?id=1814386. Therefore we add the support for client-id hardware format as config option. This flag will set client-id hardware by default. Guest with CentOS 8 will work without change (dhcp-client-identifier = hardware is set by default) Guest with CentOS 7 will need to set dhcp-client-identifier = hardware to make sure they send the currect client-id Change-Id: I15612bad49946f411e17ed62cbbb631913b89b6b diff --git a/networking_mlnx/plugins/ml2/drivers/mlnx/config.py b/networking_mlnx/plugins/ml2/drivers/mlnx/config.py new file mode 100755 index 0000000..4024e92 --- /dev/null +++ b/networking_mlnx/plugins/ml2/drivers/mlnx/config.py @@ -0,0 +1,24 @@ +# Copyright 2020 Mellanox Technologies, Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_config import cfg + +from networking_mlnx._i18n import _ + +mlnx_opts = [ + cfg.BoolOpt('client_id_hardware', + default="False", + help=_("Generate client-id according to send " + "dhcp-client-identifier = hardware")), +] diff --git a/networking_mlnx/plugins/ml2/drivers/mlnx/mech_mlnx.py b/networking_mlnx/plugins/ml2/drivers/mlnx/mech_mlnx.py index 2cf9606..e85dd78 100644 --- a/networking_mlnx/plugins/ml2/drivers/mlnx/mech_mlnx.py +++ b/networking_mlnx/plugins/ml2/drivers/mlnx/mech_mlnx.py @@ -21,9 +21,16 @@ from neutron_lib.api.definitions import portbindings from neutron_lib import constants as p_constants from neutron_lib.plugins import directory from neutron_lib.plugins.ml2 import api +from oslo_config import cfg + +from networking_mlnx.plugins.ml2.drivers.mlnx import config + +cfg.CONF.register_opts(config.mlnx_opts, "mlnx") AGENT_TYPE_MLNX = 'Mellanox plugin agent' VIF_TYPE_IB_HOSTDEV = 'ib_hostdev' +LEGACY_CLIENT_ID_PREFIX = 'ff:00:00:00:00:00:02:00:00:02:c9:00:' +HARDWARE_CLIENT_ID_PREFIX = '20:' class MlnxMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): @@ -61,12 +68,19 @@ class MlnxMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): self.vif_details) def _gen_client_id(self, port): - _PREFIX = 'ff:00:00:00:00:00:02:00:00:02:c9:00:' + if cfg.CONF.mlnx.client_id_hardware: + return self._gen_client_id_with_prefix(port, + HARDWARE_CLIENT_ID_PREFIX) + else: + return self._gen_client_id_with_prefix(port, + LEGACY_CLIENT_ID_PREFIX) + + def _gen_client_id_with_prefix(self, port, prefix): _MIDDLE = ':00:00:' mac_address = port["mac_address"] mac_first = mac_address[:8] mac_last = mac_address[9:] - client_id = ''.join([_PREFIX, mac_first, _MIDDLE, mac_last]) + client_id = ''.join([prefix, mac_first, _MIDDLE, mac_last]) return client_id def _gen_client_id_opt(self, port): diff --git a/networking_mlnx/tests/unit/ml2/drivers/mlnx/test_mech_mlnx.py b/networking_mlnx/tests/unit/ml2/drivers/mlnx/test_mech_mlnx.py index eff1b61..1343976 100644 --- a/networking_mlnx/tests/unit/ml2/drivers/mlnx/test_mech_mlnx.py +++ b/networking_mlnx/tests/unit/ml2/drivers/mlnx/test_mech_mlnx.py @@ -19,10 +19,16 @@ from neutron.tests.unit.plugins.ml2 import test_plugin from neutron_lib.api.definitions import portbindings from neutron_lib import context from neutron_lib.plugins.ml2 import api +from oslo_config import cfg +from oslo_config import fixture as fixture_config from oslo_utils import uuidutils +from networking_mlnx.plugins.ml2.drivers.mlnx import config from networking_mlnx.plugins.ml2.drivers.mlnx import mech_mlnx +cfg.CONF.import_group("mlnx", + 'networking_mlnx.plugins.ml2.drivers.mlnx') + class MlnxMechanismBaseTestCase(base.AgentMechanismBaseTestCase): VIF_TYPE = mech_mlnx.VIF_TYPE_IB_HOSTDEV @@ -128,11 +134,16 @@ class FakeContext(base.FakePortContext): class MlnxMechanismIbPortTestCase(MlnxMechanismBaseTestCase, test_plugin.Ml2PluginV2TestCase): mechanism_drivers = ['mlnx_infiniband'] - expected_client_id = ( - "ff:00:00:00:00:00:02:00:00:02:c9:00:01:23:45:00:00:67:89:ab") + expected_client_id_hardware = (mech_mlnx.HARDWARE_CLIENT_ID_PREFIX + + '01:23:45:00:00:67:89:ab') + expected_client_id_legacy = (mech_mlnx.LEGACY_CLIENT_ID_PREFIX + + "01:23:45:00:00:67:89:ab") def setUp(self): super(MlnxMechanismIbPortTestCase, self).setUp() + self.conf_fixture = self.useFixture(fixture_config.Config()) + self.conf = self.conf_fixture.conf + self.conf.register_opts(config.mlnx_opts, "mlnx") def _get_context(self): VLAN_SEGMENTS = [{api.ID: 'vlan_segment_id', @@ -153,12 +164,22 @@ class MlnxMechanismIbPortTestCase(MlnxMechanismBaseTestCase, original=original_context, current=current_context) - def test_precommit_same_host_id(self): + def test_precommit_same_host_id_with_client_id_hardware(self): + self.conf.set_override('client_id_hardware', True, "mlnx") + _context = self._get_context() + with mock.patch('neutron_lib.plugins.directory.get_plugin'): + self.driver.update_port_precommit(_context) + self.assertIsNotNone(_context.current.get('extra_dhcp_opts')) + self.assertEqual(self.expected_client_id_hardware, + _context.current['extra_dhcp_opts'][0]['opt_value']) + + def test_precommit_same_host_id_with_client_id_legacy(self): + self.conf.set_override('client_id_hardware', False, "mlnx") _context = self._get_context() with mock.patch('neutron_lib.plugins.directory.get_plugin'): self.driver.update_port_precommit(_context) self.assertIsNotNone(_context.current.get('extra_dhcp_opts')) - self.assertEqual(self.expected_client_id, + self.assertEqual(self.expected_client_id_legacy, _context.current['extra_dhcp_opts'][0]['opt_value']) def test_percommit_migrete_port(self):