Merge "net_utils: Add a random mac generator"
This commit is contained in:
commit
168fdca181
@ -11,6 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import itertools
|
||||
import random
|
||||
import socket
|
||||
|
||||
@ -46,6 +47,37 @@ class TestGetRandomMac(base.BaseTestCase):
|
||||
mock_rnd.assert_called_with(8)
|
||||
|
||||
|
||||
class TestRandomMacGenerator(base.BaseTestCase):
|
||||
|
||||
def test_all_macs_generated(self):
|
||||
mac = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff']
|
||||
generator = itertools.islice(net.random_mac_generator(mac), 70000)
|
||||
self.assertEqual(2**16, len(list(generator)))
|
||||
|
||||
@mock.patch.object(random, 'getrandbits', return_value=0xa2)
|
||||
def test_first_generated_mac(self, mock_rnd):
|
||||
mac = ['aa', 'bb', 'cc', '00', 'ee', 'ff']
|
||||
generator = itertools.islice(net.random_mac_generator(mac), 1)
|
||||
self.assertEqual(['aa:bb:cc:a2:a2:a2'], list(generator))
|
||||
mock_rnd.assert_called_with(8)
|
||||
|
||||
@mock.patch.object(random, 'getrandbits', return_value=0xa2)
|
||||
def test_respected_early_zeroes_generated_mac(self, mock_rnd):
|
||||
mac1 = ['00', 'bb', 'cc', '00', 'ee', 'ff']
|
||||
|
||||
generator = itertools.islice(net.random_mac_generator(mac1), 1)
|
||||
self.assertEqual(['00:bb:cc:a2:a2:a2'], list(generator))
|
||||
|
||||
mac2 = ['aa', '00', 'cc', '00', 'ee', 'ff']
|
||||
generator = itertools.islice(net.random_mac_generator(mac2), 1)
|
||||
self.assertEqual(['aa:00:cc:a2:a2:a2'], list(generator))
|
||||
|
||||
mac3 = ['aa', 'bb', '00', '00', 'ee', 'ff']
|
||||
generator = itertools.islice(net.random_mac_generator(mac3), 1)
|
||||
self.assertEqual(['aa:bb:00:a2:a2:a2'], list(generator))
|
||||
mock_rnd.assert_called_with(8)
|
||||
|
||||
|
||||
class TestPortDeviceOwner(base.BaseTestCase):
|
||||
|
||||
def test_is_port_trusted(self):
|
||||
|
@ -43,6 +43,36 @@ def get_random_mac(base_mac):
|
||||
return ':'.join(["%02x" % x for x in mac])
|
||||
|
||||
|
||||
def random_mac_generator(base_mac):
|
||||
"""Generates random mac addresses from a specified base format.
|
||||
|
||||
The first 3 octets of each MAC address will remain unchanged. If the 4th
|
||||
octet is not 00, it will also be used. The others will be randomly
|
||||
generated.
|
||||
|
||||
:param base_mac: Base mac address represented by an array of 6 strings.
|
||||
:returns: A mac address string generator.
|
||||
"""
|
||||
fixed = list(base_mac[0:3])
|
||||
to_generate = 3
|
||||
if base_mac[3] != '00':
|
||||
fixed += base_mac[3]
|
||||
to_generate = 2
|
||||
beginning = ':'.join(fixed) + ':'
|
||||
|
||||
form = '{}' + ':'.join('{:02x}' for _ in range(to_generate))
|
||||
max_macs = 2 ** (to_generate * 8)
|
||||
seen = set()
|
||||
while len(seen) < max_macs:
|
||||
numbers = [random.getrandbits(8) for _ in range(to_generate)]
|
||||
mac = form.format(beginning, *numbers)
|
||||
if mac in seen:
|
||||
continue
|
||||
else:
|
||||
seen.add(mac)
|
||||
yield mac
|
||||
|
||||
|
||||
def is_port_trusted(port):
|
||||
"""Used to determine if port can be trusted not to attack network.
|
||||
|
||||
|
8
releasenotes/notes/mac-generator-f927df2fe57300c0.yaml
Normal file
8
releasenotes/notes/mac-generator-f927df2fe57300c0.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Introduced ``neutron_lib.utils.net.random_mac_generator(basemac)``. It allows
|
||||
you to get a mac address string Python generator from the same kind of
|
||||
basemac that ``neutron_lib.utils.net.get_random_mac(basemac)`` expects. If
|
||||
there are a lot of macs to get, this will speed the process up
|
||||
significantly over generating single macs and testing for collisions.
|
Loading…
x
Reference in New Issue
Block a user