]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Calculate stateless IPv6 address
authorDazhao <dzyu@cn.ibm.com>
Wed, 13 Nov 2013 10:24:32 +0000 (18:24 +0800)
committerMark McClain <mmcclain@yahoo-inc.com>
Mon, 17 Mar 2014 19:48:46 +0000 (15:48 -0400)
In order to support stateless IPv6, neutron should calculate IPv6 address base
on IPv6 prefix and MAC address via EUI-64 specification.  This change adds
common library to calculate IPv6 address.

Partially-implements bp ipv6-two-attributes
Co-Authored-By: Xu Han Peng <xuhanp@cn.ibm.com>
Change-Id: I68ccbc42388ec760d6fead242e080822ca753913

neutron/common/ipv6_utils.py [new file with mode: 0644]
neutron/tests/unit/test_ipv6.py [new file with mode: 0644]

diff --git a/neutron/common/ipv6_utils.py b/neutron/common/ipv6_utils.py
new file mode 100644 (file)
index 0000000..6e57bfc
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    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.
+
+"""
+IPv6-related utilities and helper functions.
+"""
+
+import netaddr
+
+
+def get_ipv6_addr_by_EUI64(prefix, mac):
+    # Check if the prefix is IPv4 address
+    isIPv4 = netaddr.valid_ipv4(prefix)
+    if isIPv4:
+        msg = _("Unable to generate IP address by EUI64 for IPv4 prefix")
+        raise TypeError(msg)
+    try:
+        eui64 = int(netaddr.EUI(mac).eui64())
+        prefix = netaddr.IPNetwork(prefix)
+        return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
+    except netaddr.AddrFormatError:
+        raise TypeError(_('Bad prefix or mac format for generating IPv6 '
+                          'address by EUI-64: %(prefix)s, %(mac)s:')
+                        % {'prefix': prefix, 'mac': mac})
+    except TypeError:
+        raise TypeError(_('Bad prefix type for generate IPv6 address by '
+                          'EUI-64: %s') % prefix)
diff --git a/neutron/tests/unit/test_ipv6.py b/neutron/tests/unit/test_ipv6.py
new file mode 100644 (file)
index 0000000..47bfd2a
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    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 neutron.common import ipv6_utils
+from neutron.tests import base
+
+
+class IPv6byEUI64TestCase(base.BaseTestCase):
+    """Unit tests for generate IPv6 by EUI-64 operations."""
+
+    def test_generate_IPv6_by_EUI64(self):
+        addr = ipv6_utils.get_ipv6_addr_by_EUI64('2001:db8::',
+                                                 '00:16:3e:33:44:55')
+        self.assertEqual('2001:db8::216:3eff:fe33:4455', addr.format())
+
+    def test_generate_IPv6_with_IPv4_prefix(self):
+        ipv4_prefix = '10.0.8'
+        mac = '00:16:3e:33:44:55'
+        self.assertRaises(TypeError, lambda:
+                          ipv6_utils.get_ipv6_addr_by_EUI64(ipv4_prefix, mac))
+
+    def test_generate_IPv6_with_bad_mac(self):
+        bad_mac = '00:16:3e:33:44:5Z'
+        prefix = '2001:db8::'
+        self.assertRaises(TypeError, lambda:
+                          ipv6_utils.get_ipv6_addr_by_EUI64(prefix, bad_mac))
+
+    def test_generate_IPv6_with_bad_prefix(self):
+        mac = '00:16:3e:33:44:55'
+        bad_prefix = 'bb'
+        self.assertRaises(TypeError, lambda:
+                          ipv6_utils.get_ipv6_addr_by_EUI64(bad_prefix, mac))
+
+    def test_generate_IPv6_with_error_prefix_type(self):
+        mac = '00:16:3e:33:44:55'
+        prefix = 123
+        self.assertRaises(TypeError, lambda:
+                          ipv6_utils.get_ipv6_addr_by_EUI64(prefix, mac))