summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-05-11 21:04:40 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2011-05-11 21:04:40 +0000
commitd2b8350a026e0f00eae7cadbacaa15d4b44331af (patch)
tree698480bf825475938004d511b29954987909f61a
parent03b05ec0a01f9a4eded7485433879b6266b4cff7 (diff)
Implement IPv6 address generation that includes account identifier
-rw-r--r--nova/api/ec2/cloud.py3
-rw-r--r--nova/db/sqlalchemy/api.py3
-rw-r--r--nova/ipv6/account_identifier.py45
-rw-r--r--nova/ipv6/api.py7
-rw-r--r--nova/virt/libvirt_conn.py3
-rw-r--r--nova/virt/xenapi/vmops.py3
6 files changed, 57 insertions, 7 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 1b51b5463..63baf8036 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -721,7 +721,8 @@ class CloudController(object):
if instance['fixed_ip']['network'] and 'use_v6' in kwargs:
i['dnsNameV6'] = ipv6.to_global(
instance['fixed_ip']['network']['cidr_v6'],
- instance['mac_address'])
+ instance['mac_address'],
+ instance['project_id'])
i['privateDnsName'] = fixed_addr
i['privateIpAddress'] = fixed_addr
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 6c76248ce..11d07c9e9 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -975,7 +975,8 @@ def instance_get_fixed_address_v6(context, instance_id):
network_ref = network_get_by_instance(context, instance_id)
prefix = network_ref.cidr_v6
mac = instance_ref.mac_address
- return ipv6.to_global(prefix, mac)
+ project_id = instance_ref.project_id
+ return ipv6.to_global(prefix, mac, project_id)
@require_context
diff --git a/nova/ipv6/account_identifier.py b/nova/ipv6/account_identifier.py
new file mode 100644
index 000000000..258678f0a
--- /dev/null
+++ b/nova/ipv6/account_identifier.py
@@ -0,0 +1,45 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# Copyright 2011 Justin Santa Barbara
+# 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 address generation with account identifier embedded"""
+
+import hashlib
+import netaddr
+
+
+def to_global(prefix, mac, project_id):
+ project_hash = netaddr.IPAddress(int(hashlib.sha1(project_id).\
+ hexdigest()[:8], 16) << 32)
+ static_num = netaddr.IPAddress(0xff << 24)
+
+ try:
+ mac_suffix = netaddr.EUI(mac).words[3:]
+ int_addr = int(''.join(['%02x' % i for i in mac_suffix]), 16)
+ mac_addr = netaddr.IPAddress(int_addr)
+ maskIP = netaddr.IPNetwork(prefix).ip
+ return (project_hash ^ static_num ^ mac_addr | maskIP).format()
+ except TypeError:
+ raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac)
+
+
+def to_mac(ipv6_address):
+ address = netaddr.IPAddress(ipv6_address)
+ mask1 = netaddr.IPAddress('::ff:ffff')
+ mac = netaddr.EUI(int(address & mask1)).words
+ return ':'.join(['02', '16', '3e'] + ['%02x' % i for i in mac[3:6]])
diff --git a/nova/ipv6/api.py b/nova/ipv6/api.py
index 95b20c945..b7fa6bd8f 100644
--- a/nova/ipv6/api.py
+++ b/nova/ipv6/api.py
@@ -24,11 +24,12 @@ flags.DEFINE_string('ipv6_backend',
'Backend to use for IPv6 generation')
IMPL = utils.LazyPluggable(FLAGS['ipv6_backend'],
- rfc2462='nova.ipv6.rfc2462')
+ rfc2462='nova.ipv6.rfc2462',
+ account_identifier='nova.ipv6.account_identifier')
-def to_global(prefix, mac):
- return IMPL.to_global(prefix, mac)
+def to_global(prefix, mac, project_id):
+ return IMPL.to_global(prefix, mac, project_id)
def to_mac(ipv6_address):
return IMPL.to_mac(ipv6_address)
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index cde864b0d..80e1a1f85 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -185,8 +185,9 @@ def _get_network_info(instance):
def ip6_dict():
prefix = network['cidr_v6']
mac = instance['mac_address']
+ project_id = instance['project_id']
return {
- 'ip': ipv6.to_global(prefix, mac),
+ 'ip': ipv6.to_global(prefix, mac, project_id),
'netmask': network['netmask_v6'],
'enabled': '1'}
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 0b05e702a..cc2b54331 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -810,7 +810,8 @@ class VMOps(object):
def ip6_dict():
return {
"ip": ipv6.to_global(network['cidr_v6'],
- instance['mac_address']),
+ instance['mac_address'],
+ instance['project_id']),
"netmask": network['netmask_v6'],
"enabled": "1"}