diff --git a/etc/quantum.conf b/etc/quantum.conf index 247bdf96eb..92afe41555 100644 --- a/etc/quantum.conf +++ b/etc/quantum.conf @@ -28,9 +28,13 @@ api_paste_config = api-paste.ini # Supported values are 'keystone'(default), 'noauth'. # auth_strategy = keystone -# Base MAC address. The first 3 bytes will remain unchanged. The -# lower 3 bytes will be randomly generated. +# Base MAC address. The first 3 octets will remain unchanged. If the +# 4h octet is not 00, it will also used. The others will be +# randomly generated. +# 3 octet # base_mac = fa:16:3e:00:00:00 +# 4 octet +# base_mac = fa:16:3e:4f:00:00 # Maximum amount of retries to generate a unique MAC address # mac_generation_retries = 16 diff --git a/quantum/db/db_base_plugin_v2.py b/quantum/db/db_base_plugin_v2.py index 438ba090c2..9ad7aa37d3 100644 --- a/quantum/db/db_base_plugin_v2.py +++ b/quantum/db/db_base_plugin_v2.py @@ -49,6 +49,12 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2): sql_connection = 'sqlite:///:memory:' db.configure_db({'sql_connection': sql_connection, 'base': models_v2.model_base.BASEV2}) + self._check_base_mac_format() + + def _check_base_mac_format(self): + base_mac = cfg.CONF.base_mac.split(':') + if len(base_mac) != 6: + raise Exception("illegal base_mac format %s", cfg.CONF.base_mac) def _get_tenant_id_for_create(self, context, resource): if context.is_admin and 'tenant_id' in resource: @@ -138,8 +144,10 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2): max_retries = cfg.CONF.mac_generation_retries for i in range(max_retries): mac = [int(base_mac[0], 16), int(base_mac[1], 16), - int(base_mac[2], 16), random.randint(0x00, 0x7f), + int(base_mac[2], 16), random.randint(0x00, 0xff), random.randint(0x00, 0xff), random.randint(0x00, 0xff)] + if base_mac[3] != '00': + mac[3] = int(base_mac[3], 16) mac_address = ':'.join(map(lambda x: "%02x" % x, mac)) if QuantumDbPluginV2._check_unique_mac(context, network_id, mac_address): diff --git a/quantum/tests/unit/test_db_plugin.py b/quantum/tests/unit/test_db_plugin.py index b23523e762..45f9fc243a 100644 --- a/quantum/tests/unit/test_db_plugin.py +++ b/quantum/tests/unit/test_db_plugin.py @@ -498,6 +498,30 @@ class TestPortsV2(QuantumDbPluginV2TestCase): port2 = self.deserialize(fmt, res) self.assertEquals(res.status_int, 409) + def test_mac_generation(self): + cfg.CONF.set_override('base_mac', "12:34:56:00:00:00") + with self.port() as port: + mac = port['port']['mac_address'] + # check that MAC address matches base MAC + base_mac = cfg.CONF.base_mac + self.assertTrue(mac.startswith("12:34:56")) + + def test_mac_generation_4octet(self): + cfg.CONF.set_override('base_mac', "12:34:56:78:00:00") + with self.port() as port: + mac = port['port']['mac_address'] + # check that MAC address matches base MAC + base_mac = cfg.CONF.base_mac + self.assertTrue(mac.startswith("12:34:56:78")) + + def test_bad_mac_format(self): + cfg.CONF.set_override('base_mac', "bad_mac") + try: + self.plugin._check_base_mac_format() + except: + return + self.fail("No exception for illegal base_mac format") + def test_mac_exhaustion(self): # rather than actually consuming all MAC (would take a LONG time) # we just raise the exception that would result.