Browse Source

Merge "New method in netutils: get_mac_addr_by_ipv6"

tags/4.4.0^0
Zuul 2 months ago
committed by Gerrit Code Review
parent
commit
0c2ca1afed
3 changed files with 67 additions and 0 deletions
  1. +29
    -0
      oslo_utils/netutils.py
  2. +33
    -0
      oslo_utils/tests/test_netutils.py
  3. +5
    -0
      releasenotes/notes/netutils-get_mac_addr_by_ipv6-c3ce6a35a69f7c2b.yaml

+ 29
- 0
oslo_utils/netutils.py View File

@@ -193,6 +193,35 @@ def get_ipv6_addr_by_EUI64(prefix, mac):
'EUI-64: %s') % prefix)


def get_mac_addr_by_ipv6(ipv6, dialect=netaddr.mac_unix_expanded):
"""Extract MAC address from interface identifier based IPv6 address.

For example from link-local addresses (fe80::/10) generated from MAC.

:param ipv6: An interface identifier (i.e. mostly MAC) based IPv6
address as a netaddr.IPAddress() object.
:param dialect: The netaddr dialect of the the object returned.
Defaults to netaddr.mac_unix_expanded.
:returns: A MAC address as a netaddr.EUI() object.

See also:
* https://tools.ietf.org/html/rfc4291#appendix-A
* https://tools.ietf.org/html/rfc4291#section-2.5.6

.. versionadded:: 4.3.0
"""
return netaddr.EUI(int(
# out of the lowest 8 bytes (byte positions 8-1)
# delete the middle 2 bytes (5-4, 0xff_fe)
# by shifting the highest 3 bytes to the right by 2 bytes (8-6 -> 6-4)
(((ipv6 & 0xff_ff_ff_00_00_00_00_00) >> 16) +
# adding the lowest 3 bytes as they are (3-1)
(ipv6 & 0xff_ff_ff)) ^
# then invert the universal/local bit
0x02_00_00_00_00_00),
dialect=dialect)


def is_ipv6_enabled():
"""Check if IPv6 support is enabled on the platform.



+ 33
- 0
oslo_utils/tests/test_netutils.py View File

@@ -17,6 +17,7 @@ import contextlib
import socket
from unittest import mock

import netaddr
import netifaces
from oslotest import base as test_base
import six
@@ -357,6 +358,38 @@ class IPv6byEUI64TestCase(test_base.BaseTestCase):
netutils.get_ipv6_addr_by_EUI64(prefix, mac))


class MACbyIPv6TestCase(test_base.BaseTestCase):
"""Unit tests to extract MAC from IPv6."""

def test_reverse_generate_IPv6_by_EUI64(self):
self.assertEqual(
netaddr.EUI('00:16:3e:33:44:55'),
netutils.get_mac_addr_by_ipv6(
netaddr.IPAddress('2001:db8::216:3eff:fe33:4455')),
)

def test_random_qemu_mac(self):
self.assertEqual(
netaddr.EUI('52:54:00:42:02:19'),
netutils.get_mac_addr_by_ipv6(
netaddr.IPAddress('fe80::5054:ff:fe42:219')),
)

def test_local(self):
self.assertEqual(
netaddr.EUI('02:00:00:00:00:00'),
netutils.get_mac_addr_by_ipv6(
netaddr.IPAddress('fe80::ff:fe00:0')),
)

def test_universal(self):
self.assertEqual(
netaddr.EUI('00:00:00:00:00:00'),
netutils.get_mac_addr_by_ipv6(
netaddr.IPAddress('fe80::200:ff:fe00:0')),
)


@contextlib.contextmanager
def mock_file_content(content):
# Allows StringIO to act like a context manager-enabled file.


+ 5
- 0
releasenotes/notes/netutils-get_mac_addr_by_ipv6-c3ce6a35a69f7c2b.yaml View File

@@ -0,0 +1,5 @@
---
features:
- |
New method ``netutils.get_mac_addr_by_ipv6(ipv6, dialect)`` extracts
the MAC address from IPv6 addresses generated from MACs.

Loading…
Cancel
Save