From c5c58cb20def79401a374f863983a343139b53f3 Mon Sep 17 00:00:00 2001 From: "NTT PF Lab." Date: Fri, 24 Dec 2010 20:38:49 +0900 Subject: Support IPv6 --- nova/api/ec2/cloud.py | 9 +++- nova/db/api.py | 9 ++++ nova/db/sqlalchemy/api.py | 23 ++++++++++ nova/db/sqlalchemy/models.py | 4 ++ nova/network/linux_net.py | 88 +++++++++++++++++++++++++++++++++++++ nova/network/manager.py | 30 +++++++++++-- nova/test.py | 3 +- nova/tests/api_unittest.py | 67 ++++++++++++++++++++++++++++ nova/tests/network_unittest.py | 21 +++++++++ nova/utils.py | 39 ++++++++++++++++ nova/virt/libvirt.qemu.xml.template | 1 + nova/virt/libvirt.uml.xml.template | 1 + nova/virt/libvirt_conn.py | 68 ++++++++++++++++++++++++---- 13 files changed, 349 insertions(+), 14 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index ebb13aedc..ff7a2f3cd 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -31,7 +31,7 @@ import time from nova import context import IPy - +import urllib from nova import crypto from nova import db from nova import exception @@ -307,6 +307,7 @@ class CloudController(object): values['group_id'] = source_security_group['id'] elif cidr_ip: # If this fails, it throws an exception. This is what we want. + cidr_ip = urllib.unquote(cidr_ip).decode() IPy.IP(cidr_ip) values['cidr'] = cidr_ip else: @@ -635,10 +636,16 @@ class CloudController(object): if instance['fixed_ip']['floating_ips']: fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] + if instance['fixed_ip']['network'] and FLAGS.use_ipv6: + i['dnsNameV6'] = utils.to_global_ipv6( + instance['fixed_ip']['network']['cidr_v6'], + instance['mac_address']) + i['privateDnsName'] = fixed_addr i['publicDnsName'] = floating_addr i['dnsName'] = i['publicDnsName'] or i['privateDnsName'] i['keyName'] = instance['key_name'] + if context.user.is_admin(): i['keyName'] = '%s (%s, %s)' % (i['keyName'], instance['project_id'], diff --git a/nova/db/api.py b/nova/db/api.py index 8f9dc2443..caee0b7b8 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -240,6 +240,9 @@ def fixed_ip_get_instance(context, address): """Get an instance for a fixed ip by address.""" return IMPL.fixed_ip_get_instance(context, address) +def fixed_ip_get_instance_v6(context, address): + return IMPL.fixed_ip_get_instance_v6(context, address) + def fixed_ip_get_network(context, address): """Get a network for a fixed ip by address.""" @@ -298,6 +301,9 @@ def instance_get_fixed_address(context, instance_id): """Get the fixed ip address of an instance.""" return IMPL.instance_get_fixed_address(context, instance_id) +def instance_get_fixed_address_v6(context, instance_id): + return IMPL.instance_get_fixed_address_v6(context, instance_id) + def instance_get_floating_address(context, instance_id): """Get the first floating ip address of an instance.""" @@ -476,6 +482,9 @@ def project_get_network(context, project_id): """ return IMPL.project_get_network(context, project_id) +def project_get_network_v6(context, project_id): + return IMPL.project_get_network_v6(context, project_id) + ################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 55036d1d1..29f3cdee1 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -504,6 +504,16 @@ def fixed_ip_get_instance(context, address): fixed_ip_ref = fixed_ip_get_by_address(context, address) return fixed_ip_ref.instance +@require_context +def fixed_ip_get_instance_v6(context, address): + session = get_session() + mac = utils.to_mac(address) + + result = session.query(models.Instance + ).filter_by(mac_address=mac + ).first() + return result + @require_admin_context def fixed_ip_get_network(context, address): @@ -692,6 +702,15 @@ def instance_get_fixed_address(context, instance_id): return None return instance_ref.fixed_ip['address'] +@require_context +def instance_get_fixed_address_v6(context, instance_id): + session = get_session() + with session.begin(): + instance_ref = instance_get(context, instance_id, session=session) + network_ref = project_get_network(context, context.project_id) + prefix = network_ref.cidr_v6 + mac = instance_ref.mac_address + return utils.to_global_ipv6(prefix, mac) @require_context def instance_get_floating_address(context, instance_id): @@ -1004,6 +1023,10 @@ def project_get_network(context, project_id): first() return rv +@require_context +def project_get_network_v6(context, project_id): + return project_get_network(context, project_id) + ################### diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index fe0a9a921..c81ef68f1 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -389,6 +389,10 @@ class Network(BASE, NovaBase): injected = Column(Boolean, default=False) cidr = Column(String(255), unique=True) + cidr_v6 = Column(String(255), unique=True) + + ra_server = Column(String(255)) + netmask = Column(String(255)) bridge = Column(String(255)) gateway = Column(String(255)) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 0fefd9415..a2ec731cd 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -53,6 +53,7 @@ flags.DEFINE_string('routing_source_ip', '127.0.0.1', flags.DEFINE_bool('use_nova_chains', False, 'use the nova_ routing chains instead of default') + DEFAULT_PORTS = [("tcp", 80), ("tcp", 22), ("udp", 1194), ("tcp", 443)] @@ -75,6 +76,11 @@ def init_host(): FLAGS.fixed_range) _confirm_rule("POSTROUTING", "-t nat -s %(range)s -d %(range)s -j ACCEPT" % {'range': FLAGS.fixed_range}) + if(FLAGS.use_ipv6): + _execute('sudo bash -c ' + + '"echo 1 > /proc/sys/net/ipv6/conf/all/forwarding"') + _execute('sudo bash -c ' + + '"echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra"') def bind_floating_ip(floating_ip): @@ -158,6 +164,10 @@ def ensure_bridge(bridge, interface, net_attrs=None): net_attrs['gateway'], net_attrs['broadcast'], net_attrs['netmask'])) + if(FLAGS.use_ipv6): + _execute("sudo ifconfig %s add %s up" % \ + (bridge, + net_attrs['cidr_v6'])) else: _execute("sudo ifconfig %s up" % bridge) _confirm_rule("FORWARD", "--in-interface %s -j ACCEPT" % bridge) @@ -213,6 +223,50 @@ def update_dhcp(context, network_id): _execute(command, addl_env=env) +def update_ra(context, network_id): + network_ref = db.network_get(context, network_id) + + conffile = _ra_file(network_ref['bridge'], 'conf') + with open(conffile, 'w') as f: + conf_str = """ +interface %s +{ + AdvSendAdvert on; + MinRtrAdvInterval 3; + MaxRtrAdvInterval 10; + prefix %s + { + AdvOnLink on; + AdvAutonomous on; + }; +}; +""" % (network_ref['bridge'], network_ref['cidr_v6']) + f.write(conf_str) + + # Make sure dnsmasq can actually read it (it setuid()s to "nobody") + os.chmod(conffile, 0644) + + pid = _ra_pid_for(network_ref['bridge']) + + # if dnsmasq is already running, then tell it to reload + if pid: + out, _err = _execute('cat /proc/%d/cmdline' + % pid, check_exit_code=False) + if conffile in out: + try: + _execute('sudo kill -HUP %d' % pid) + return + except Exception as exc: # pylint: disable-msg=W0703 + logging.debug("Hupping radvd threw %s", exc) + else: + logging.debug("Pid %d is stale, relaunching radvd", pid) + command = _ra_cmd(network_ref) + _execute(command) + db.network_update(context, network_id, + {"ra_server": + utils.get_my_linklocal(network_ref['bridge'])}) + + def _host_dhcp(fixed_ip_ref): """Return a host string for an address""" instance_ref = fixed_ip_ref['instance'] @@ -268,6 +322,15 @@ def _dnsmasq_cmd(net): return ''.join(cmd) +def _ra_cmd(net): + """Builds dnsmasq command""" + cmd = ['sudo -E radvd', +# ' -u nobody', + ' -C %s' % _ra_file(net['bridge'], 'conf'), + ' -p %s' % _ra_file(net['bridge'], 'pid')] + return ''.join(cmd) + + def _stop_dnsmasq(network): """Stops the dnsmasq instance for a given network""" pid = _dnsmasq_pid_for(network) @@ -289,6 +352,16 @@ def _dhcp_file(bridge, kind): kind)) +def _ra_file(bridge, kind): + """Return path to a pid, leases or conf file for a bridge""" + + if not os.path.exists(FLAGS.networks_path): + os.makedirs(FLAGS.networks_path) + return os.path.abspath("%s/nova-ra-%s.%s" % (FLAGS.networks_path, + bridge, + kind)) + + def _dnsmasq_pid_for(bridge): """Returns the pid for prior dnsmasq instance for a bridge @@ -302,3 +375,18 @@ def _dnsmasq_pid_for(bridge): if os.path.exists(pid_file): with open(pid_file, 'r') as f: return int(f.read()) + + +def _ra_pid_for(bridge): + """Returns the pid for prior dnsmasq instance for a bridge + + Returns None if no pid file exists + + If machine has rebooted pid might be incorrect (caller should check) + """ + + pid_file = _ra_file(bridge, 'pid') + + if os.path.exists(pid_file): + with open(pid_file, 'r') as f: + return int(f.read()) diff --git a/nova/network/manager.py b/nova/network/manager.py index a7298b47f..ceea6966f 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -80,6 +80,7 @@ flags.DEFINE_integer('network_size', 256, flags.DEFINE_string('floating_range', '4.4.4.0/24', 'Floating IP address block') flags.DEFINE_string('fixed_range', '10.0.0.0/8', 'Fixed IP address block') +flags.DEFINE_string('fixed_range_v6', 'fd00::/48', 'Fixed IPv6 address block') flags.DEFINE_integer('cnt_vpn_clients', 5, 'Number of addresses reserved for vpn clients') flags.DEFINE_string('network_driver', 'nova.network.linux_net', @@ -88,6 +89,8 @@ flags.DEFINE_bool('update_dhcp_on_disassociate', False, 'Whether to update dhcp when fixed_ip is disassociated') flags.DEFINE_integer('fixed_ip_disassociate_timeout', 600, 'Seconds after which a deallocated ip is disassociated') +flags.DEFINE_bool('use_ipv6', True, + 'use the ipv6') class AddressAlreadyAllocated(exception.Error): @@ -217,7 +220,7 @@ class NetworkManager(manager.Manager): """Get the network for the current context.""" raise NotImplementedError() - def create_networks(self, context, num_networks, network_size, + def create_networks(self, context, num_networks, network_size, cidr_v6, *args, **kwargs): """Create networks based on parameters.""" raise NotImplementedError() @@ -307,9 +310,11 @@ class FlatManager(NetworkManager): pass def create_networks(self, context, cidr, num_networks, network_size, - *args, **kwargs): + cidr_v6, *args, **kwargs): """Create networks based on parameters.""" fixed_net = IPy.IP(cidr) + fixed_net_v6 = IPy.IP(cidr_v6) + significant_bits_v6 = 64 for index in range(num_networks): start = index * network_size significant_bits = 32 - int(math.log(network_size, 2)) @@ -322,7 +327,13 @@ class FlatManager(NetworkManager): net['gateway'] = str(project_net[1]) net['broadcast'] = str(project_net.broadcast()) net['dhcp_start'] = str(project_net[2]) + + if(FLAGS.use_ipv6): + cidr_v6 = "%s/%s" % (fixed_net_v6[0], significant_bits_v6) + net['cidr_v6'] = cidr_v6 + network_ref = self.db.network_create_safe(context, net) + if network_ref: self._create_fixed_ips(context, network_ref['id']) @@ -466,12 +477,16 @@ class VlanManager(NetworkManager): pass def create_networks(self, context, cidr, num_networks, network_size, - vlan_start, vpn_start): + vlan_start, vpn_start, cidr_v6): """Create networks based on parameters.""" fixed_net = IPy.IP(cidr) + fixed_net_v6 = IPy.IP(cidr_v6) + network_size_v6 = 1 << 64 + significant_bits_v6 = 64 for index in range(num_networks): vlan = vlan_start + index start = index * network_size + start_v6 = index * network_size_v6 significant_bits = 32 - int(math.log(network_size, 2)) cidr = "%s/%s" % (fixed_net[start], significant_bits) project_net = IPy.IP(cidr) @@ -484,6 +499,13 @@ class VlanManager(NetworkManager): net['dhcp_start'] = str(project_net[3]) net['vlan'] = vlan net['bridge'] = 'br%s' % vlan + if(FLAGS.use_ipv6): + cidr_v6 = "%s/%s" % ( + fixed_net_v6[start_v6], + significant_bits_v6 + ) + net['cidr_v6'] = cidr_v6 + # NOTE(vish): This makes ports unique accross the cloud, a more # robust solution would be to make them unique per ip net['vpn_public_port'] = vpn_start + index @@ -506,6 +528,8 @@ class VlanManager(NetworkManager): network_ref['bridge'], network_ref) self.driver.update_dhcp(context, network_id) + if(FLAGS.use_ipv6): + self.driver.update_ra(context, network_id) @property def _bottom_reserved_ips(self): diff --git a/nova/test.py b/nova/test.py index 5c2a72819..ee2fc2720 100644 --- a/nova/test.py +++ b/nova/test.py @@ -70,7 +70,8 @@ class TrialTestCase(unittest.TestCase): FLAGS.fixed_range, 5, 16, FLAGS.vlan_start, - FLAGS.vpn_start) + FLAGS.vpn_start, + FLAGS.fixed_range_v6) # emulate some of the mox stuff, we can't use the metaclass # because it screws with our generators diff --git a/nova/tests/api_unittest.py b/nova/tests/api_unittest.py index 33d4cb294..a508235c4 100644 --- a/nova/tests/api_unittest.py +++ b/nova/tests/api_unittest.py @@ -24,6 +24,7 @@ import httplib import random import StringIO import webob +import logging from nova import context from nova import flags @@ -265,6 +266,72 @@ class ApiEc2TestCase(test.TrialTestCase): return + def test_authorize_revoke_security_group_cidr_v6(self): + """ + Test that we can add and remove CIDR based rules + to a security group for IPv6 + """ + self.expect_http() + self.mox.ReplayAll() + user = self.manager.create_user('fake', 'fake', 'fake') + project = self.manager.create_project('fake', 'fake', 'fake') + + # At the moment, you need both of these to actually be netadmin + self.manager.add_role('fake', 'netadmin') + project.add_role('fake', 'netadmin') + + security_group_name = "".join(random.choice("sdiuisudfsdcnpaqwertasd") + for x in range(random.randint(4, 8))) + + group = self.ec2.create_security_group(security_group_name, + 'test group') + + self.expect_http() + self.mox.ReplayAll() + group.connection = self.ec2 + + group.authorize('tcp', 80, 81, '::/0') + + self.expect_http() + self.mox.ReplayAll() + + rv = self.ec2.get_all_security_groups() + # I don't bother checkng that we actually find it here, + # because the create/delete unit test further up should + # be good enough for that. + for group in rv: + if group.name == security_group_name: + self.assertEquals(len(group.rules), 1) + self.assertEquals(int(group.rules[0].from_port), 80) + self.assertEquals(int(group.rules[0].to_port), 81) + self.assertEquals(len(group.rules[0].grants), 1) + self.assertEquals(str(group.rules[0].grants[0]), '::/0') + + self.expect_http() + self.mox.ReplayAll() + group.connection = self.ec2 + + group.revoke('tcp', 80, 81, '::/0') + + self.expect_http() + self.mox.ReplayAll() + + self.ec2.delete_security_group(security_group_name) + + self.expect_http() + self.mox.ReplayAll() + group.connection = self.ec2 + + rv = self.ec2.get_all_security_groups() + + self.assertEqual(len(rv), 1) + self.assertEqual(rv[0].name, 'default') + + self.manager.delete_project(project) + self.manager.delete_user(user) + + return + def test_authorize_revoke_security_group_foreign_group(self): """ Test that we can grant and revoke another security group access diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py index 6f4705719..0a4b50e96 100644 --- a/nova/tests/network_unittest.py +++ b/nova/tests/network_unittest.py @@ -97,6 +97,27 @@ class NetworkTestCase(test.TrialTestCase): self.context.project_id = self.projects[project_num].id self.network.deallocate_fixed_ip(self.context, address) + def test_private_ipv6(self): + """Make sure ipv6 is OK""" + if FLAGS.use_ipv6: + instance_ref = self._create_instance(1) + network_ref = db.project_get_network( + self.context, + self.context.project_id) + address_v6 = db.instance_get_fixed_address_v6( + self.context, + instance_ref['id']) + self.assertEqual(instance_ref['mac_address'], + utils.to_mac(address_v6)) + instance_ref2 = db.fixed_ip_get_instance_v6( + self.context, + address_v6) + self.assertEqual(instance_ref['id'], instance_ref2['id']) + self.assertEqual(address_v6, + utils.to_global_ipv6( + network_ref['cidr_v6'], + instance_ref['mac_address'])) + def test_public_network_association(self): """Makes sure that we can allocaate a public ip""" # TODO(vish): better way of adding floating ips diff --git a/nova/utils.py b/nova/utils.py index 142584df8..211a2cb75 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -30,6 +30,8 @@ import subprocess import socket import sys from xml.sax import saxutils +import re +import netaddr from twisted.internet.threads import deferToThread @@ -45,10 +47,14 @@ TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" def import_class(import_str): """Returns a class from a string including module and class""" mod_str, _sep, class_str = import_str.rpartition('.') + logging.debug(import_str) try: __import__(mod_str) return getattr(sys.modules[mod_str], class_str) except (ImportError, ValueError, AttributeError): + logging.debug(ImportError) + logging.debug(ValueError) + logging.debug(AttributeError) raise exception.NotFound('Class %s cannot be found' % class_str) @@ -165,6 +171,39 @@ def get_my_ip(): return "127.0.0.1" +def get_my_linklocal(interface): + if getattr(FLAGS, 'fake_tests', None): + return 'fe00::' + try: + if_str = execute("ifconfig %s" % interface) + condition = "\s+inet6\s+addr:\s+([0-9a-f:]+/\d+)\s+Scope:Link" + links = [re.search(condition, x) for x in if_str[0].split('\n')] + address = [w.group(1) for w in links if w is not None] + if address[0] is not None: + return address[0] + else: + return None + except RuntimeError as ex: + logging.warn("Couldn't get Link Local IP of %s :%s", interface, ex) + return None + + +def to_global_ipv6(prefix, mac): + mac64 = netaddr.EUI(mac).eui64().words + int_addr = int(''.join(['%02x' % i for i in mac64]), 16) + mac64_addr = netaddr.IPAddress(int_addr) + maskIP = netaddr.IPNetwork(prefix).ip + return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).format() + + +def to_mac(ipv6_address): + address = netaddr.IPAddress(ipv6_address) + mask1 = netaddr.IPAddress("::ffff:ffff:ffff:ffff") + mask2 = netaddr.IPAddress("::0200:0:0:0") + mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words + return ":".join(["%02x" % i for i in mac64[0:3] + mac64[5:8]]) + + def isotime(at=None): if not at: at = datetime.datetime.utcnow() diff --git a/nova/virt/libvirt.qemu.xml.template b/nova/virt/libvirt.qemu.xml.template index 2538b1ade..0ffe17e8d 100644 --- a/nova/virt/libvirt.qemu.xml.template +++ b/nova/virt/libvirt.qemu.xml.template @@ -23,6 +23,7 @@ + diff --git a/nova/virt/libvirt.uml.xml.template b/nova/virt/libvirt.uml.xml.template index bb8b47911..0d355b81c 100644 --- a/nova/virt/libvirt.uml.xml.template +++ b/nova/virt/libvirt.uml.xml.template @@ -17,6 +17,7 @@ + diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 18085089f..71d9f781d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -514,6 +514,8 @@ class LibvirtConnection(object): instance['id']) # Assume that the gateway also acts as the dhcp server. dhcp_server = network['gateway'] + #TODO ipv6 + ra_server = network['ra_server'] xml_info = {'type': FLAGS.libvirt_type, 'name': instance['name'], 'basepath': os.path.join(FLAGS.instances_path, @@ -523,11 +525,13 @@ class LibvirtConnection(object): 'bridge_name': network['bridge'], 'mac_address': instance['mac_address'], 'ip_address': ip_address, - 'dhcp_server': dhcp_server} + 'dhcp_server': dhcp_server, + 'ra_server': ra_server} if rescue: libvirt_xml = self.rescue_xml % xml_info else: libvirt_xml = self.libvirt_xml % xml_info + logging.debug('instance %s: finished toXML method', instance['name']) return libvirt_xml @@ -701,6 +705,7 @@ class NWFilterFirewall(object): + ''' @@ -722,6 +727,14 @@ class NWFilterFirewall(object): ''' + nova_ra_filter = ''' + d707fa71-4fb5-4b27-9ab7-ba5ca19c8804 + + + + ''' + def nova_base_ipv4_filter(self): retval = "" for protocol in ['tcp', 'udp', 'icmp']: @@ -736,13 +749,13 @@ class NWFilterFirewall(object): def nova_base_ipv6_filter(self): retval = "" - for protocol in ['tcp', 'udp', 'icmp']: + for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']: for direction, action, priority in [('out', 'accept', 399), ('inout', 'drop', 400)]: retval += """ - <%s-ipv6 /> + <%s /> """ % (action, direction, - priority, protocol) + priority, protocol) retval += '' return retval @@ -755,6 +768,15 @@ class NWFilterFirewall(object): retval += '' return retval + def nova_project_filter_v6(self, project, net, mask): + retval = "" % project + for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']: + retval += """ + <%s srcipaddr='%s' srcipmask='%s' /> + """ % (protocol, net, mask) + retval += '' + return retval + def _define_filter(self, xml): if callable(xml): xml = xml() @@ -766,6 +788,11 @@ class NWFilterFirewall(object): net = IPy.IP(cidr) return str(net.net()), str(net.netmask()) + @staticmethod + def _get_ip_version(cidr): + net = IPy.IP(cidr) + return int(net.version()) + @defer.inlineCallbacks def setup_nwfilters_for_instance(self, instance): """ @@ -777,6 +804,7 @@ class NWFilterFirewall(object): yield self._define_filter(self.nova_base_ipv4_filter) yield self._define_filter(self.nova_base_ipv6_filter) yield self._define_filter(self.nova_dhcp_filter) + yield self._define_filter(self.nova_ra_filter) yield self._define_filter(self.nova_base_filter) nwfilter_xml = "\n" \ @@ -787,12 +815,22 @@ class NWFilterFirewall(object): network_ref = db.project_get_network(context.get_admin_context(), instance['project_id']) net, mask = self._get_net_and_mask(network_ref['cidr']) + if(FLAGS.use_ipv6): + net_v6, mask_v6 = self._get_net_and_mask( + network_ref['cidr_v6']) project_filter = self.nova_project_filter(instance['project_id'], net, mask) yield self._define_filter(project_filter) - nwfilter_xml += " \n" % \ instance['project_id'] + if(FLAGS.use_ipv6): + project_filter_v6 = self.nova_project_filter_v6( + instance['project_id'], + net_v6, mask_v6) + yield self._define_filter(project_filter_v6) + nwfilter_xml += \ + " \n" % \ + instance['project_id'] for security_group in instance.security_groups: yield self.ensure_security_group_filter(security_group['id']) @@ -812,12 +850,21 @@ class NWFilterFirewall(object): security_group = db.security_group_get(context.get_admin_context(), security_group_id) rule_xml = "" + version = 4 + v6protocol = {'tcp':'tcp-ipv6', 'udp':'udp-ipv6', 'icmp':'icmpv6'} for rule in security_group.rules: rule_xml += "" if rule.cidr: + version = self._get_ip_version(rule.cidr) net, mask = self._get_net_and_mask(rule.cidr) - rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ - (rule.protocol, net, mask) + if(FLAGS.use_ipv6 and version == 6): + rule_xml += "<%s " % v6protocol[rule.protocol] + rule_xml += "srcipaddr='%s' " % net + rule_xml += "srcipmask='%s' " % mask + else: + rule_xml += "<%s " % rule.protocol + rule_xml += "srcipaddr='%s' " % net + rule_xml += "srcipmask='%s' " % mask if rule.protocol in ['tcp', 'udp']: rule_xml += "dstportstart='%s' dstportend='%s' " % \ (rule.from_port, rule.to_port) @@ -832,6 +879,9 @@ class NWFilterFirewall(object): rule_xml += '/>\n' rule_xml += "\n" - xml = "%s" % \ - (security_group_id, rule_xml,) + xml = " Date: Tue, 4 Jan 2011 04:21:50 -0500 Subject: Fixed conflict with r515 --- nova/virt/libvirt.uml.xml.template | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 nova/virt/libvirt.uml.xml.template (limited to 'nova') diff --git a/nova/virt/libvirt.uml.xml.template b/nova/virt/libvirt.uml.xml.template deleted file mode 100644 index 0d355b81c..000000000 --- a/nova/virt/libvirt.uml.xml.template +++ /dev/null @@ -1,27 +0,0 @@ - - %(name)s - %(memory_kb)s - - %(type)s - /usr/bin/linux - /dev/ubda1 - - - - - - - - - - - - - - - - - - - - -- cgit From 96facdeee025cdf33df0b16abeeeb97f9ec87e70 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Tue, 4 Jan 2011 04:27:39 -0500 Subject: Fixed for pep8 --- nova/virt/libvirt_conn.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 9a99b1a51..c656931d6 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -550,7 +550,7 @@ class LibvirtConnection(object): "\n" "\n") % (net, mask,net_v6,mask_v6) + "value=\"%s\" />\n") % (net, mask, net_v6, mask_v6) else: extra_params = "\n" @@ -777,7 +777,6 @@ class NWFilterFirewall(object): ''' - nova_ra_filter = ''' d707fa71-4fb5-4b27-9ab7-ba5ca19c8804 ''' - nova_vpn_filter = ''' 2086015e-cf03-11df-8c5d-080027c27973 @@ -795,7 +793,6 @@ class NWFilterFirewall(object): ''' - def nova_base_ipv4_filter(self): retval = "" for protocol in ['tcp', 'udp', 'icmp']: @@ -832,8 +829,9 @@ class NWFilterFirewall(object): def nova_project_filter_v6(self): retval = "" % project for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']: - retval += """ - <%s srcipaddr='$PROJNETV6' srcipmask='$PROJMASKV6' /> + retval += """ + <%s srcipaddr='$PROJNETV6' + srcipmask='$PROJMASKV6' /> """ % (protocol) retval += '' return retval @@ -872,7 +870,7 @@ class NWFilterFirewall(object): if FLAGS.allow_project_net_traffic: nwfilter_xml += " \n" if(FLAGS.use_ipv6): - nwfilter_xml += " \n" + nwfilter_xml += " \n" for security_group in instance.security_groups: self.ensure_security_group_filter(security_group['id']) @@ -892,7 +890,7 @@ class NWFilterFirewall(object): security_group_id) rule_xml = "" version = 4 - v6protocol = {'tcp':'tcp-ipv6', 'udp':'udp-ipv6', 'icmp':'icmpv6'} + v6protocol = {'tcp': 'tcp-ipv6', 'udp': 'udp-ipv6', 'icmp': 'icmpv6'} for rule in security_group.rules: rule_xml += "" if rule.cidr: @@ -904,7 +902,6 @@ class NWFilterFirewall(object): else: rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ (rule.protocol, net, mask) - if rule.protocol in ['tcp', 'udp']: rule_xml += "dstportstart='%s' dstportend='%s' " % \ (rule.from_port, rule.to_port) -- cgit From 505becef0704cc801f957d2931c8b994e2df92ca Mon Sep 17 00:00:00 2001 From: nova Date: Tue, 4 Jan 2011 05:00:21 -0500 Subject: Fixed bug --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c656931d6..de7f6341f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -827,7 +827,7 @@ class NWFilterFirewall(object): return retval def nova_project_filter_v6(self): - retval = "" % project + retval = "" for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']: retval += """ <%s srcipaddr='$PROJNETV6' -- cgit From c528be81a5d0acaea5077c183ec4d15356d457d5 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Tue, 4 Jan 2011 05:35:13 -0500 Subject: Fixed bug in libvirt --- nova/virt/libvirt_conn.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index de7f6341f..f95544188 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -114,6 +114,9 @@ def _get_net_and_mask(cidr): net = IPy.IP(cidr) return str(net.net()), str(net.netmask()) +def _get_ip_version(cidr): + net = IPy.IP(cidr) + return int(net.version()) class LibvirtConnection(object): @@ -484,7 +487,8 @@ class LibvirtConnection(object): 'netmask': network_ref['netmask'], 'gateway': network_ref['gateway'], 'broadcast': network_ref['broadcast'], - 'dns': network_ref['dns']} + 'dns': network_ref['dns'], + 'ra_server': network_ref['ra_server']} if key or net: if key: logging.info(_('instance %s: injecting key into image %s'), @@ -541,8 +545,8 @@ class LibvirtConnection(object): if FLAGS.allow_project_net_traffic: net, mask = _get_net_and_mask(network['cidr']) - net_v6, mask_v6 = self._get_net_and_mask( - network_ref['cidr_v6']) + net_v6, mask_v6 = _get_net_and_mask( + network['cidr_v6']) extra_params = ("\n" " Date: Tue, 4 Jan 2011 07:40:29 -0500 Subject: Some Bug Fix --- nova/utils.py | 4 +--- nova/virt/libvirt.xml.template | 2 +- nova/virt/libvirt_conn.py | 16 +++++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'nova') diff --git a/nova/utils.py b/nova/utils.py index 0eab4b152..c5e2f7517 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -211,8 +211,6 @@ def get_my_ip(): def get_my_linklocal(interface): - if getattr(FLAGS, 'fake_tests', None): - return 'fe00::' try: if_str = execute("ifconfig %s" % interface) condition = "\s+inet6\s+addr:\s+([0-9a-f:]+/\d+)\s+Scope:Link" @@ -224,7 +222,7 @@ def get_my_linklocal(interface): return None except RuntimeError as ex: logging.warn("Couldn't get Link Local IP of %s :%s", interface, ex) - return None + return 'fe00::' def to_global_ipv6(prefix, mac): diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index f0f56fc62..52c95ee57 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -66,7 +66,7 @@ - + #if $getVar('extra_params', False) ${extra_params} #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f95544188..521ac97fc 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -114,6 +114,10 @@ def _get_net_and_mask(cidr): net = IPy.IP(cidr) return str(net.net()), str(net.netmask()) +def _get_net_and_prefixlen(cidr): + net = IPy.IP(cidr) + return str(net.net()), str(net.prefixlen()) + def _get_ip_version(cidr): net = IPy.IP(cidr) return int(net.version()) @@ -354,6 +358,7 @@ class LibvirtConnection(object): power_state.NOSTATE, 'launching') NWFilterFirewall(self._conn).setup_nwfilters_for_instance(instance) + self._create_image(instance, xml) self._conn.createXML(xml, 0) logging.debug(_("instance %s: is running"), instance['name']) @@ -545,7 +550,7 @@ class LibvirtConnection(object): if FLAGS.allow_project_net_traffic: net, mask = _get_net_and_mask(network['cidr']) - net_v6, mask_v6 = _get_net_and_mask( + net_v6, prefixlen_v6 = _get_net_and_prefixlen( network['cidr_v6']) extra_params = ("\n" @@ -554,7 +559,7 @@ class LibvirtConnection(object): "\n" "\n") % (net, mask, net_v6, mask_v6) + "value=\"%s\" />\n") % (net, mask, net_v6, prefixlen_v6) else: extra_params = "\n" @@ -882,7 +887,7 @@ class NWFilterFirewall(object): nwfilter_xml += (" \n") % security_group['id'] nwfilter_xml += "" - + logging.debug(nwfilter_xml) self._define_filter(nwfilter_xml) def ensure_security_group_filter(self, security_group_id): @@ -899,11 +904,12 @@ class NWFilterFirewall(object): rule_xml += "" if rule.cidr: version = _get_ip_version(rule.cidr) - net, mask = _get_net_and_mask(rule.cidr) if(FLAGS.use_ipv6 and version == 6): + net, prefixlen = _get_net_and_prefixlen(rule.cidr) rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ - (v6protocol[rrule.protocol], net, mask) + (v6protocol[rrule.protocol], net, prefixlen) else: + net, mask = _get_net_and_mask(rule.cidr) rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ (rule.protocol, net, mask) if rule.protocol in ['tcp', 'udp']: -- cgit From 28bf4e2df324db79a81a853d39cb5912985c2e45 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 10:25:16 -0500 Subject: Fixed bug in nova_project_filter_v6 --- nova/virt/libvirt_conn.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 521ac97fc..a592f5d6b 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -114,14 +114,17 @@ def _get_net_and_mask(cidr): net = IPy.IP(cidr) return str(net.net()), str(net.netmask()) + def _get_net_and_prefixlen(cidr): net = IPy.IP(cidr) return str(net.net()), str(net.prefixlen()) + def _get_ip_version(cidr): net = IPy.IP(cidr) return int(net.version()) + class LibvirtConnection(object): def __init__(self, read_only): @@ -559,7 +562,8 @@ class LibvirtConnection(object): "\n" "\n") % (net, mask, net_v6, prefixlen_v6) + "value=\"%s\" />\n") % \ + (net, mask, net_v6, prefixlen_v6) else: extra_params = "\n" @@ -838,7 +842,8 @@ class NWFilterFirewall(object): def nova_project_filter_v6(self): retval = "" for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']: - retval += """ + retval += """ <%s srcipaddr='$PROJNETV6' srcipmask='$PROJMASKV6' /> """ % (protocol) -- cgit From b47f37d0f9c06f2c4bc5adcf3afcececa2354324 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 10:35:15 -0500 Subject: Fixed misspelled variable --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index a592f5d6b..1f3c69f65 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -912,7 +912,7 @@ class NWFilterFirewall(object): if(FLAGS.use_ipv6 and version == 6): net, prefixlen = _get_net_and_prefixlen(rule.cidr) rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ - (v6protocol[rrule.protocol], net, prefixlen) + (v6protocol[rule.protocol], net, prefixlen) else: net, mask = _get_net_and_mask(rule.cidr) rule_xml += "<%s srcipaddr='%s' srcipmask='%s' " % \ -- cgit From 69b7a0d69c3ac79b84c2bda19d379606c5a323ab Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 10:42:15 -0500 Subject: Removed debug message which is not needed. --- nova/virt/libvirt_conn.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 1f3c69f65..4fba164a9 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -892,7 +892,6 @@ class NWFilterFirewall(object): nwfilter_xml += (" \n") % security_group['id'] nwfilter_xml += "" - logging.debug(nwfilter_xml) self._define_filter(nwfilter_xml) def ensure_security_group_filter(self, security_group_id): -- cgit From 40b156f74e90a94abb255950f29d714f4bc4c428 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 12:36:47 -0500 Subject: Fixed:Create instance fails when use_ipv6=False --- nova/virt/libvirt_conn.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 4fba164a9..8197342df 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -490,13 +490,16 @@ class LibvirtConnection(object): if network_ref['injected']: admin_context = context.get_admin_context() address = db.instance_get_fixed_address(admin_context, inst['id']) + ra_server = network_ref['ra_server'] + if not ra_server: + ra_server = "fd00::" with open(FLAGS.injected_network_template) as f: net = f.read() % {'address': address, 'netmask': network_ref['netmask'], 'gateway': network_ref['gateway'], 'broadcast': network_ref['broadcast'], 'dns': network_ref['dns'], - 'ra_server': network_ref['ra_server']} + 'ra_server': ra_server} if key or net: if key: logging.info(_('instance %s: injecting key into image %s'), @@ -550,12 +553,14 @@ class LibvirtConnection(object): # Assume that the gateway also acts as the dhcp server. dhcp_server = network['gateway'] ra_server = network['ra_server'] - + if not ra_server: + ra_server = 'fd00::' if FLAGS.allow_project_net_traffic: - net, mask = _get_net_and_mask(network['cidr']) - net_v6, prefixlen_v6 = _get_net_and_prefixlen( + if FLAGS.use_ipv6: + net, mask = _get_net_and_mask(network['cidr']) + net_v6, prefixlen_v6 = _get_net_and_prefixlen( network['cidr_v6']) - extra_params = ("\n" "\n" @@ -564,6 +569,13 @@ class LibvirtConnection(object): "\n") % \ (net, mask, net_v6, prefixlen_v6) + else: + net, mask = _get_net_and_mask(network['cidr']) + extra_params = ("\n" + "\n") % \ + (net, mask) else: extra_params = "\n" @@ -860,12 +872,14 @@ class NWFilterFirewall(object): self._define_filter(self.nova_base_ipv4_filter) self._define_filter(self.nova_base_ipv6_filter) self._define_filter(self.nova_dhcp_filter) - self._define_filter(self.nova_ra_filter) + if FLAGS.use_ipv6: + self._define_filter(self.nova_ra_filter) self._define_filter(self.nova_base_filter) self._define_filter(self.nova_vpn_filter) if FLAGS.allow_project_net_traffic: self._define_filter(self.nova_project_filter) - self._define_filter(self.nova_project_filter_v6) + if FLAGS.use_ipv6: + self._define_filter(self.nova_project_filter_v6) def setup_nwfilters_for_instance(self, instance): """ -- cgit From 90ced5f211c3a53389d2f5d7413f9289770b279a Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 12:38:34 -0500 Subject: Fixed for pep8 --- nova/virt/libvirt_conn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 8197342df..b19988822 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -490,9 +490,9 @@ class LibvirtConnection(object): if network_ref['injected']: admin_context = context.get_admin_context() address = db.instance_get_fixed_address(admin_context, inst['id']) - ra_server = network_ref['ra_server'] + ra_server = network_ref['ra_server'] if not ra_server: - ra_server = "fd00::" + ra_server = "fd00::" with open(FLAGS.injected_network_template) as f: net = f.read() % {'address': address, 'netmask': network_ref['netmask'], @@ -554,7 +554,7 @@ class LibvirtConnection(object): dhcp_server = network['gateway'] ra_server = network['ra_server'] if not ra_server: - ra_server = 'fd00::' + ra_server = 'fd00::' if FLAGS.allow_project_net_traffic: if FLAGS.use_ipv6: net, mask = _get_net_and_mask(network['cidr']) -- cgit From f85eba86b04253612e2272b3eb6a9fd79fab6567 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 5 Jan 2011 12:39:35 -0500 Subject: missing _() --- nova/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/utils.py b/nova/utils.py index c5e2f7517..afe7422d9 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -221,7 +221,7 @@ def get_my_linklocal(interface): else: return None except RuntimeError as ex: - logging.warn("Couldn't get Link Local IP of %s :%s", interface, ex) + logging.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) return 'fe00::' -- cgit From c14425541a1e77eb2049b94060bc0c4cd1df578f Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 12 Jan 2011 02:15:09 -0500 Subject: changed exception class --- nova/utils.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/utils.py b/nova/utils.py index afe7422d9..888ebfd81 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -219,10 +219,13 @@ def get_my_linklocal(interface): if address[0] is not None: return address[0] else: - return None - except RuntimeError as ex: - logging.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) - return 'fe00::' + return 'fe00::' + except IndexError as ex: + logging.warn(_("Couldn't parse command from get Link Local IP of %s :%s"), interface, ex) + except ProcessExecutionError as ex: + logging.warn(_("Couldn't execute command to get Link Local IP of %s :%s"), interface, ex) + except: + return 'fe00::' def to_global_ipv6(prefix, mac): -- cgit From 1629dcf935a29c01d4e4ad509e33356daa93b051 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 12 Jan 2011 11:26:22 +0900 Subject: Fixed for pep8 Remove temporary debugging --- nova/db/api.py | 3 +++ nova/db/sqlalchemy/api.py | 4 ++++ nova/utils.py | 1 - 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/db/api.py b/nova/db/api.py index 8684a3aef..03e800466 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -284,6 +284,7 @@ def fixed_ip_get_instance(context, address): """Get an instance for a fixed ip by address.""" return IMPL.fixed_ip_get_instance(context, address) + def fixed_ip_get_instance_v6(context, address): return IMPL.fixed_ip_get_instance_v6(context, address) @@ -345,6 +346,7 @@ def instance_get_fixed_address(context, instance_id): """Get the fixed ip address of an instance.""" return IMPL.instance_get_fixed_address(context, instance_id) + def instance_get_fixed_address_v6(context, instance_id): return IMPL.instance_get_fixed_address_v6(context, instance_id) @@ -543,6 +545,7 @@ def project_get_network(context, project_id, associate=True): return IMPL.project_get_network(context, project_id) + def project_get_network_v6(context, project_id): return IMPL.project_get_network_v6(context, project_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index ffc0ec221..7c3afa4ad 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -585,6 +585,7 @@ def fixed_ip_get_instance(context, address): fixed_ip_ref = fixed_ip_get_by_address(context, address) return fixed_ip_ref.instance + @require_context def fixed_ip_get_instance_v6(context, address): session = get_session() @@ -801,6 +802,7 @@ def instance_get_fixed_address(context, instance_id): return None return instance_ref.fixed_ip['address'] + @require_context def instance_get_fixed_address_v6(context, instance_id): session = get_session() @@ -811,6 +813,7 @@ def instance_get_fixed_address_v6(context, instance_id): mac = instance_ref.mac_address return utils.to_global_ipv6(prefix, mac) + @require_context def instance_get_floating_address(context, instance_id): session = get_session() @@ -1150,6 +1153,7 @@ def project_get_network(context, project_id, associate=True): first() return result + @require_context def project_get_network_v6(context, project_id): return project_get_network(context, project_id) diff --git a/nova/utils.py b/nova/utils.py index 888ebfd81..b08d5d620 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -47,7 +47,6 @@ TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" def import_class(import_str): """Returns a class from a string including module and class""" mod_str, _sep, class_str = import_str.rpartition('.') - logging.debug(import_str) try: __import__(mod_str) return getattr(sys.modules[mod_str], class_str) -- cgit From d368d182d7fa4b0f0cd9c7c5ad1e804b19365b26 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 12 Jan 2011 12:05:27 +0900 Subject: Add DescribeInstanceV6 for backward compatibility --- nova/api/ec2/cloud.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 8c925ffee..3d071782c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -643,15 +643,21 @@ class CloudController(object): def describe_instances(self, context, **kwargs): return self._format_describe_instances(context) + def describe_instances_v6(self, context, **kwargs): + return self._format_describe_instances(context) + def _format_describe_instances(self, context): return {'reservationSet': self._format_instances(context)} + def _format_describe_instances_v6(self, context): + return {'reservationSet': self._format_instances(context,None,True)} + def _format_run_instances(self, context, reservation_id): i = self._format_instances(context, reservation_id) assert len(i) == 1 return i[0] - def _format_instances(self, context, reservation_id=None): + def _format_instances(self, context, reservation_id=None,use_v6=False): reservations = {} if reservation_id: instances = db.instance_get_all_by_reservation(context, @@ -677,7 +683,7 @@ class CloudController(object): if instance['fixed_ip']['floating_ips']: fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] - if instance['fixed_ip']['network'] and FLAGS.use_ipv6: + if instance['fixed_ip']['network'] and use_v6: i['dnsNameV6'] = utils.to_global_ipv6( instance['fixed_ip']['network']['cidr_v6'], instance['mac_address']) -- cgit From 7a6b7c32ed25d1edc58b924ce5621dc0d8de9686 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 12 Jan 2011 03:50:09 -0500 Subject: Fixed bug --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 3d071782c..d6f164b5c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -644,7 +644,7 @@ class CloudController(object): return self._format_describe_instances(context) def describe_instances_v6(self, context, **kwargs): - return self._format_describe_instances(context) + return self._format_describe_instances_v6(context) def _format_describe_instances(self, context): return {'reservationSet': self._format_instances(context)} -- cgit From 04cd3241f442f1c6a9fd030ab47b4d15e79ec032 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 12 Jan 2011 18:37:18 +0900 Subject: Change command to get link local address Remove superfluous code --- nova/utils.py | 4 ++-- nova/virt/libvirt_conn.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'nova') diff --git a/nova/utils.py b/nova/utils.py index 02bafc6c8..a13fa214c 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -212,8 +212,8 @@ def get_my_ip(): def get_my_linklocal(interface): try: - if_str = execute("ifconfig %s" % interface) - condition = "\s+inet6\s+addr:\s+([0-9a-f:]+/\d+)\s+Scope:Link" + if_str = execute("ip -f inet6 -o addr show %s" % interface) + condition = "\s+inet6\s+([0-9a-f:]+/\d+)\s+scope:link" links = [re.search(condition, x) for x in if_str[0].split('\n')] address = [w.group(1) for w in links if w is not None] if address[0] is not None: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index c6827edbe..e5f61f9aa 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1024,7 +1024,6 @@ class NWFilterFirewall(FirewallDriver): security_group = db.security_group_get(context.get_admin_context(), security_group_id) rule_xml = "" - version = 4 v6protocol = {'tcp': 'tcp-ipv6', 'udp': 'udp-ipv6', 'icmp': 'icmpv6'} for rule in security_group.rules: rule_xml += "" -- cgit From a6a2a057d8a027781e4270c9abc4f815c67293ec Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Wed, 12 Jan 2011 10:12:18 -0500 Subject: Fixed syntax errors --- nova/api/ec2/cloud.py | 2 +- nova/utils.py | 2 +- nova/virt/libvirt_conn.py | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'nova') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 72d7bcc95..c5c99f132 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -610,7 +610,7 @@ class CloudController(object): def describe_instances_v6(self, context, **kwargs): kwargs['use_v6'] = True - return self._format_describe_instances_v6(context, **kwargs) + return self._format_describe_instances(context, **kwargs) def _format_describe_instances(self, context, **kwargs): return {'reservationSet': self._format_instances(context, **kwargs)} diff --git a/nova/utils.py b/nova/utils.py index 49344699a..09c9a5f89 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -218,7 +218,7 @@ def get_my_ip(): def get_my_linklocal(interface): try: if_str = execute("ip -f inet6 -o addr show %s" % interface) - condition = "\s+inet6\s+([0-9a-f:]+/\d+)\s+scope:link" + condition = "\s+inet6\s+([0-9a-f:]+/\d+)\s+scope\s+link" links = [re.search(condition, x) for x in if_str[0].split('\n')] address = [w.group(1) for w in links if w is not None] if address[0] is not None: diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index ec17e4db0..263138710 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -940,8 +940,8 @@ class NWFilterFirewall(FirewallDriver): ['no-mac-spoofing', 'no-ip-spoofing', 'no-arp-spoofing', - 'allow-dhcp-server', - 'allow-ra-server'])) + 'allow-dhcp-server' + ])) self._define_filter(self.nova_base_ipv4_filter) self._define_filter(self.nova_base_ipv6_filter) self._define_filter(self.nova_dhcp_filter) @@ -1035,6 +1035,8 @@ class NWFilterFirewall(FirewallDriver): instance_secgroup_filter_children = ['nova-base-ipv4', 'nova-base-ipv6', 'nova-allow-dhcp-server'] + if FLAGS.use_ipv6: + instance_secgroup_filter_children += ['nova-allow-ra-server'] ctxt = context.get_admin_context() -- cgit From b945fed7779bddf799aa4a180d44745052d2da8c Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 12 Jan 2011 21:55:36 +0900 Subject: Support IPv6 firewall with IptablesFirewallDriver --- nova/db/sqlalchemy/api.py | 2 +- nova/virt/libvirt_conn.py | 66 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 16 deletions(-) (limited to 'nova') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 3b3a88170..2ca16283f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -798,7 +798,7 @@ def instance_get_fixed_address_v6(context, instance_id): session = get_session() with session.begin(): instance_ref = instance_get(context, instance_id, session=session) - network_ref = project_get_network(context, context.project_id) + network_ref = network_get_by_instance(context, instance_id) prefix = network_ref.cidr_v6 mac = instance_ref.mac_address return utils.to_global_ipv6(prefix, mac) diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 263138710..f2ffbf180 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1131,11 +1131,17 @@ class IptablesFirewallDriver(FirewallDriver): def apply_ruleset(self): current_filter, _ = self.execute('sudo iptables-save -t filter') current_lines = current_filter.split('\n') - new_filter = self.modify_rules(current_lines) + new_filter = self.modify_rules(current_lines, 4) self.execute('sudo iptables-restore', process_input='\n'.join(new_filter)) + if(FLAGS.use_ipv6): + current_filter, _ = self.execute('sudo ip6tables-save -t filter') + current_lines = current_filter.split('\n') + new_filter = self.modify_rules(current_lines, 6) + self.execute('sudo ip6tables-restore', + process_input='\n'.join(new_filter)) - def modify_rules(self, current_lines): + def modify_rules(self, current_lines, ip_version): ctxt = context.get_admin_context() # Remove any trace of nova rules. new_filter = filter(lambda l: 'nova-' not in l, current_lines) @@ -1149,8 +1155,8 @@ class IptablesFirewallDriver(FirewallDriver): if not new_filter[rules_index].startswith(':'): break - our_chains = [':nova-ipv4-fallback - [0:0]'] - our_rules = ['-A nova-ipv4-fallback -j DROP'] + our_chains = [':nova-fallback - [0:0]'] + our_rules = ['-A nova-fallback -j DROP'] our_chains += [':nova-local - [0:0]'] our_rules += ['-A FORWARD -j nova-local'] @@ -1160,7 +1166,10 @@ class IptablesFirewallDriver(FirewallDriver): # First, we add instance chains and rules for instance in self.instances: chain_name = self._instance_chain_name(instance) - ip_address = self._ip_for_instance(instance) + if(ip_version == 4): + ip_address = self._ip_for_instance(instance) + elif(ip_version == 6): + ip_address = self._ip_for_instance_v6(instance) our_chains += [':%s - [0:0]' % chain_name] @@ -1186,13 +1195,19 @@ class IptablesFirewallDriver(FirewallDriver): our_rules += ['-A %s -j %s' % (chain_name, sg_chain_name)] - # Allow DHCP responses - dhcp_server = self._dhcp_server_for_instance(instance) - our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68' % - (chain_name, dhcp_server)] + if(ip_version == 4): + # Allow DHCP responses + dhcp_server = self._dhcp_server_for_instance(instance) + our_rules += ['-A %s -s %s -p udp --sport 67 --dport 68' % + (chain_name, dhcp_server)] + elif(ip_version == 6): + # Allow RA responses + ra_server = self._ra_server_for_instance(instance) + our_rules += ['-A %s -s %s -p icmpv6' % + (chain_name, ra_server)] # If nothing matches, jump to the fallback chain - our_rules += ['-A %s -j nova-ipv4-fallback' % (chain_name,)] + our_rules += ['-A %s -j nova-fallback' % (chain_name,)] # then, security group chains and rules for security_group in security_groups: @@ -1205,15 +1220,22 @@ class IptablesFirewallDriver(FirewallDriver): for rule in rules: logging.info('%r', rule) - args = ['-A', chain_name, '-p', rule.protocol] - if rule.cidr: - args += ['-s', rule.cidr] - else: + if not rule.cidr: # Eventually, a mechanism to grant access for security # groups will turn up here. It'll use ipsets. continue + version = _get_ip_version(rule.cidr) + if version != ip_version: + continue + + protocol = rule.protocol + if version == 6 and rule.protocol == 'icmp': + protocol = 'icmpv6' + + args = ['-A', chain_name, '-p', protocol, '-s', rule.cidr] + if rule.protocol in ['udp', 'tcp']: if rule.from_port == rule.to_port: args += ['--dport', '%s' % (rule.from_port,)] @@ -1233,7 +1255,12 @@ class IptablesFirewallDriver(FirewallDriver): icmp_type_arg += '/%s' % icmp_code if icmp_type_arg: - args += ['-m', 'icmp', '--icmp-type', icmp_type_arg] + if(ip_version == 4): + args += ['-m', 'icmp', '--icmp-type', + icmp_type_arg] + elif(ip_version == 6): + args += ['-m', 'icmp6', '--icmpv6-type', + icmp_type_arg] args += ['-j ACCEPT'] our_rules += [' '.join(args)] @@ -1259,7 +1286,16 @@ class IptablesFirewallDriver(FirewallDriver): return db.instance_get_fixed_address(context.get_admin_context(), instance['id']) + def _ip_for_instance_v6(self, instance): + return db.instance_get_fixed_address_v6(context.get_admin_context(), + instance['id']) + def _dhcp_server_for_instance(self, instance): network = db.project_get_network(context.get_admin_context(), instance['project_id']) return network['gateway'] + + def _ra_server_for_instance(self, instance): + network = db.project_get_network(context.get_admin_context(), + instance['project_id']) + return network['ra_server'] -- cgit From df0be0318cf22d250bdf9abdd9ed3b91bb83f0ea Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Thu, 13 Jan 2011 09:10:44 +0900 Subject: fixed method signature of modify_rules fixed unit_test for ipv6 --- nova/tests/test_network.py | 17 +++++++++-------- nova/virt/libvirt_conn.py | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'nova') diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py index 407dbc769..00f9323f3 100644 --- a/nova/tests/test_network.py +++ b/nova/tests/test_network.py @@ -99,23 +99,24 @@ class NetworkTestCase(test.TestCase): def test_private_ipv6(self): """Make sure ipv6 is OK""" if FLAGS.use_ipv6: - instance_ref = self._create_instance(1) + instance_ref = self._create_instance(0) + address = self._create_address(0, instance_ref['id']) network_ref = db.project_get_network( - self.context, + context.get_admin_context(), self.context.project_id) address_v6 = db.instance_get_fixed_address_v6( - self.context, - instance_ref['id']) + context.get_admin_context(), + instance_ref['id']) self.assertEqual(instance_ref['mac_address'], utils.to_mac(address_v6)) instance_ref2 = db.fixed_ip_get_instance_v6( - self.context, - address_v6) + context.get_admin_context(), + address_v6) self.assertEqual(instance_ref['id'], instance_ref2['id']) self.assertEqual(address_v6, utils.to_global_ipv6( - network_ref['cidr_v6'], - instance_ref['mac_address'])) + network_ref['cidr_v6'], + instance_ref['mac_address'])) def test_public_network_association(self): """Makes sure that we can allocaate a public ip""" diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index f2ffbf180..191292a9d 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -1141,7 +1141,7 @@ class IptablesFirewallDriver(FirewallDriver): self.execute('sudo ip6tables-restore', process_input='\n'.join(new_filter)) - def modify_rules(self, current_lines, ip_version): + def modify_rules(self, current_lines, ip_version=4): ctxt = context.get_admin_context() # Remove any trace of nova rules. new_filter = filter(lambda l: 'nova-' not in l, current_lines) -- cgit From a5026320b4ae14f0171ee450fe79ea687ab5647a Mon Sep 17 00:00:00 2001 From: Koji Iida Date: Thu, 13 Jan 2011 15:58:05 +0900 Subject: Fixed missing _(). Fixed to follow logging to LOG changes. Fixed merge miss (get_fixed_ip was moved away). Update some missing comments. --- nova/network/linux_net.py | 14 +++++++------- nova/tests/test_api.py | 1 - nova/utils.py | 17 ++--------------- 3 files changed, 9 insertions(+), 23 deletions(-) (limited to 'nova') diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 50256db2d..677931603 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -292,12 +292,12 @@ interface %s """ % (network_ref['bridge'], network_ref['cidr_v6']) f.write(conf_str) - # Make sure dnsmasq can actually read it (it setuid()s to "nobody") + # Make sure radvd can actually read it (it setuid()s to "nobody") os.chmod(conffile, 0644) pid = _ra_pid_for(network_ref['bridge']) - # if dnsmasq is already running, then tell it to reload + # if radvd is already running, then tell it to reload if pid: out, _err = _execute('cat /proc/%d/cmdline' % pid, check_exit_code=False) @@ -306,9 +306,9 @@ interface %s _execute('sudo kill -HUP %d' % pid) return except Exception as exc: # pylint: disable-msg=W0703 - logging.debug("Hupping radvd threw %s", exc) + LOG.debug(_("Hupping radvd threw %s"), exc) else: - logging.debug("Pid %d is stale, relaunching radvd", pid) + LOG.debug(_("Pid %d is stale, relaunching radvd"), pid) command = _ra_cmd(network_ref) _execute(command) db.network_update(context, network_id, @@ -378,7 +378,7 @@ def _dnsmasq_cmd(net): def _ra_cmd(net): - """Builds dnsmasq command""" + """Builds radvd command""" cmd = ['sudo -E radvd', # ' -u nobody', ' -C %s' % _ra_file(net['bridge'], 'conf'), @@ -408,7 +408,7 @@ def _dhcp_file(bridge, kind): def _ra_file(bridge, kind): - """Return path to a pid, leases or conf file for a bridge""" + """Return path to a pid or conf file for a bridge""" if not os.path.exists(FLAGS.networks_path): os.makedirs(FLAGS.networks_path) @@ -433,7 +433,7 @@ def _dnsmasq_pid_for(bridge): def _ra_pid_for(bridge): - """Returns the pid for prior dnsmasq instance for a bridge + """Returns the pid for prior radvd instance for a bridge Returns None if no pid file exists diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py index a508235c4..d22d7beb1 100644 --- a/nova/tests/test_api.py +++ b/nova/tests/test_api.py @@ -24,7 +24,6 @@ import httplib import random import StringIO import webob -import logging from nova import context from nova import flags diff --git a/nova/utils.py b/nova/utils.py index 09c9a5f89..27589c30c 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -202,19 +202,6 @@ def last_octet(address): return int(address.split(".")[-1]) -def get_my_ip(): - """Returns the actual ip of the local machine.""" - try: - csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - csock.connect(('8.8.8.8', 80)) - (addr, port) = csock.getsockname() - csock.close() - return addr - except socket.gaierror as ex: - logging.warn(_("Couldn't get IP, using 127.0.0.1 %s"), ex) - return "127.0.0.1" - - def get_my_linklocal(interface): try: if_str = execute("ip -f inet6 -o addr show %s" % interface) @@ -226,9 +213,9 @@ def get_my_linklocal(interface): else: return 'fe00::' except IndexError as ex: - logging.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) + LOG.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) except ProcessExecutionError as ex: - logging.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) + LOG.warn(_("Couldn't get Link Local IP of %s :%s"), interface, ex) except: return 'fe00::' -- cgit From bc0c5ba5026610013759fa731d21e2287e3d709a Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Fri, 14 Jan 2011 06:25:41 +0900 Subject: Moved commands which needs sudo to nova.sh --- nova/network/linux_net.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'nova') diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 677931603..891e9bc1d 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -124,11 +124,6 @@ def init_host(): (FLAGS.fixed_range, FLAGS.dmz_cidr)) _confirm_rule("POSTROUTING", "-t nat -s %(range)s -d %(range)s -j ACCEPT" % {'range': FLAGS.fixed_range}) - if(FLAGS.use_ipv6): - _execute('sudo bash -c ' + - '"echo 1 > /proc/sys/net/ipv6/conf/all/forwarding"') - _execute('sudo bash -c ' + - '"echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra"') def bind_floating_ip(floating_ip, check_exit_code=True): -- cgit