summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2010-12-22 20:59:16 +0000
committerVishvananda Ishaya <vishvananda@gmail.com>2010-12-22 20:59:16 +0000
commit2504643977e40a0f37101280118df8d3c5dc3b1c (patch)
tree6547167885f3bc7fa6e92d3627893aad326f4aab
parentcd460a1f661eea7e050891f50a8218fdf24f2c6f (diff)
parentff1575e782fb08fb3923a09cb1a18d703b33be4a (diff)
Optimize nwfilter creation and project filter
-rw-r--r--nova/compute/manager.py6
-rw-r--r--nova/tests/virt_unittest.py4
-rw-r--r--nova/virt/fake.py6
-rw-r--r--nova/virt/libvirt.qemu.xml.template1
-rw-r--r--nova/virt/libvirt.rescue.qemu.xml.template1
-rw-r--r--nova/virt/libvirt.rescue.uml.xml.template5
-rw-r--r--nova/virt/libvirt.uml.xml.template1
-rw-r--r--nova/virt/libvirt_conn.py77
8 files changed, 71 insertions, 30 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 7eb60e262..59d4fb29d 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -65,6 +65,12 @@ class ComputeManager(manager.Manager):
self.volume_manager = utils.import_object(FLAGS.volume_manager)
super(ComputeManager, self).__init__(*args, **kwargs)
+ def init_host(self):
+ """Do any initialization that needs to be run if this is a
+ standalone service.
+ """
+ self.driver.init_host()
+
def _update_state(self, context, instance_id):
"""Update the state of an instance from the driver info."""
# FIXME(ja): include other fields from state?
diff --git a/nova/tests/virt_unittest.py b/nova/tests/virt_unittest.py
index 85e569858..d190cdabf 100644
--- a/nova/tests/virt_unittest.py
+++ b/nova/tests/virt_unittest.py
@@ -252,7 +252,7 @@ class NWFilterTestCase(test.TestCase):
self.security_group.id)
instance = db.instance_get(self.context, inst_id)
- d = self.fw.setup_nwfilters_for_instance(instance)
+ self.fw.setup_base_nwfilters()
+ self.fw.setup_nwfilters_for_instance(instance)
_ensure_all_called()
self.teardown_security_group()
- return d
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 77bc926c2..76a04f18f 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -76,6 +76,12 @@ class FakeConnection(object):
cls._instance = cls()
return cls._instance
+ def init_host(self):
+ """
+ Initialize anything that is necessary for the driver to function
+ """
+ return
+
def list_instances(self):
"""
Return the names of all the instances known to the virtualization
diff --git a/nova/virt/libvirt.qemu.xml.template b/nova/virt/libvirt.qemu.xml.template
index 2538b1ade..d90afea81 100644
--- a/nova/virt/libvirt.qemu.xml.template
+++ b/nova/virt/libvirt.qemu.xml.template
@@ -23,6 +23,7 @@
<filterref filter="nova-instance-%(name)s">
<parameter name="IP" value="%(ip_address)s" />
<parameter name="DHCPSERVER" value="%(dhcp_server)s" />
+ %(extra_params)s
</filterref>
</interface>
<serial type="file">
diff --git a/nova/virt/libvirt.rescue.qemu.xml.template b/nova/virt/libvirt.rescue.qemu.xml.template
index c0ffbdcee..a3b88106c 100644
--- a/nova/virt/libvirt.rescue.qemu.xml.template
+++ b/nova/virt/libvirt.rescue.qemu.xml.template
@@ -27,6 +27,7 @@
<filterref filter="nova-instance-%(name)s">
<parameter name="IP" value="%(ip_address)s" />
<parameter name="DHCPSERVER" value="%(dhcp_server)s" />
+ %(extra_params)s
</filterref>
</interface>
<serial type="file">
diff --git a/nova/virt/libvirt.rescue.uml.xml.template b/nova/virt/libvirt.rescue.uml.xml.template
index 836f47532..a254692d4 100644
--- a/nova/virt/libvirt.rescue.uml.xml.template
+++ b/nova/virt/libvirt.rescue.uml.xml.template
@@ -18,6 +18,11 @@
<interface type='bridge'>
<source bridge='%(bridge_name)s'/>
<mac address='%(mac_address)s'/>
+ <filterref filter="nova-instance-%(name)s">
+ <parameter name="IP" value="%(ip_address)s" />
+ <parameter name="DHCPSERVER" value="%(dhcp_server)s" />
+ %(extra_params)s
+ </filterref>
</interface>
<console type="file">
<source path='%(basepath)s/console.log'/>
diff --git a/nova/virt/libvirt.uml.xml.template b/nova/virt/libvirt.uml.xml.template
index bb8b47911..506f2ef72 100644
--- a/nova/virt/libvirt.uml.xml.template
+++ b/nova/virt/libvirt.uml.xml.template
@@ -17,6 +17,7 @@
<filterref filter="nova-instance-%(name)s">
<parameter name="IP" value="%(ip_address)s" />
<parameter name="DHCPSERVER" value="%(dhcp_server)s" />
+ %(extra_params)s
</filterref>
</interface>
<console type="file">
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 5a8c71850..0d42ce2f8 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -117,6 +117,11 @@ def get_connection(read_only):
return LibvirtConnection(read_only)
+def _get_net_and_mask(cidr):
+ net = IPy.IP(cidr)
+ return str(net.net()), str(net.netmask())
+
+
class LibvirtConnection(object):
def __init__(self, read_only):
(self.libvirt_uri,
@@ -128,6 +133,9 @@ class LibvirtConnection(object):
self._wrapped_conn = None
self.read_only = read_only
+ def init_host(self):
+ NWFilterFirewall(self._conn).setup_base_nwfilters()
+
@property
def _conn(self):
if not self._wrapped_conn or not self._test_connection():
@@ -496,6 +504,15 @@ class LibvirtConnection(object):
instance['id'])
# Assume that the gateway also acts as the dhcp server.
dhcp_server = network['gateway']
+
+ if FLAGS.allow_project_net_traffic:
+ net, mask = _get_net_and_mask(network['cidr'])
+ extra_params = ("<parameter name=\"PROJNET\" value=\"%s\" />\n"
+ "<parameter name=\"PROJMASK\" value=\"%s\" />\n"
+ ) % (net, mask)
+ else:
+ extra_params = "\n"
+
xml_info = {'type': FLAGS.libvirt_type,
'name': instance['name'],
'basepath': os.path.join(FLAGS.instances_path,
@@ -505,7 +522,8 @@ class LibvirtConnection(object):
'bridge_name': network['bridge'],
'mac_address': instance['mac_address'],
'ip_address': ip_address,
- 'dhcp_server': dhcp_server}
+ 'dhcp_server': dhcp_server,
+ 'extra_params': extra_params}
if rescue:
libvirt_xml = self.rescue_xml % xml_info
else:
@@ -704,6 +722,14 @@ class NWFilterFirewall(object):
</rule>
</filter>'''
+ nova_vpn_filter = '''<filter name='nova-vpn' chain='root'>
+ <uuid>2086015e-cf03-11df-8c5d-080027c27973</uuid>
+ <filterref filter='allow-dhcp-server'/>
+ <filterref filter='nova-allow-dhcp-server'/>
+ <filterref filter='nova-base-ipv4'/>
+ <filterref filter='nova-base-ipv6'/>
+ </filter>'''
+
def nova_base_ipv4_filter(self):
retval = "<filter name='nova-base-ipv4' chain='ipv4'>"
for protocol in ['tcp', 'udp', 'icmp']:
@@ -728,12 +754,12 @@ class NWFilterFirewall(object):
retval += '</filter>'
return retval
- def nova_project_filter(self, project, net, mask):
- retval = "<filter name='nova-project-%s' chain='ipv4'>" % project
+ def nova_project_filter(self):
+ retval = "<filter name='nova-project' chain='ipv4'>"
for protocol in ['tcp', 'udp', 'icmp']:
retval += """<rule action='accept' direction='in' priority='200'>
- <%s srcipaddr='%s' srcipmask='%s' />
- </rule>""" % (protocol, net, mask)
+ <%s srcipaddr='$PROJNET' srcipmask='$PROJMASK' />
+ </rule>""" % protocol
retval += '</filter>'
return retval
@@ -744,10 +770,14 @@ class NWFilterFirewall(object):
# execute in a native thread and block current greenthread until done
tpool.execute(self._conn.nwfilterDefineXML, xml)
- @staticmethod
- def _get_net_and_mask(cidr):
- net = IPy.IP(cidr)
- return str(net.net()), str(net.netmask())
+ def setup_base_nwfilters(self):
+ 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_base_filter)
+ self._define_filter(self.nova_vpn_filter)
+ if FLAGS.allow_project_net_traffic:
+ self._define_filter(self.nova_project_filter)
def setup_nwfilters_for_instance(self, instance):
"""
@@ -756,31 +786,22 @@ class NWFilterFirewall(object):
the base filter are all in place.
"""
- 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_base_filter)
+ nwfilter_xml = ("<filter name='nova-instance-%s' chain='root'>\n"
+ ) % instance['name']
- nwfilter_xml = "<filter name='nova-instance-%s' chain='root'>\n" \
- " <filterref filter='nova-base' />\n" % \
- instance['name']
+ if instance['image_id'] == FLAGS.vpn_image_id:
+ nwfilter_xml += " <filterref filter='nova-vpn' />\n"
+ else:
+ nwfilter_xml += " <filterref filter='nova-base' />\n"
if FLAGS.allow_project_net_traffic:
- network_ref = db.project_get_network(context.get_admin_context(),
- instance['project_id'])
- net, mask = self._get_net_and_mask(network_ref['cidr'])
- project_filter = self.nova_project_filter(instance['project_id'],
- net, mask)
- self._define_filter(project_filter)
-
- nwfilter_xml += " <filterref filter='nova-project-%s' />\n" % \
- instance['project_id']
+ nwfilter_xml += " <filterref filter='nova-project' />\n"
for security_group in instance.security_groups:
self.ensure_security_group_filter(security_group['id'])
- nwfilter_xml += " <filterref filter='nova-secgroup-%d' />\n" % \
- security_group['id']
+ nwfilter_xml += (" <filterref filter='nova-secgroup-%d' />\n"
+ ) % security_group['id']
nwfilter_xml += "</filter>"
self._define_filter(nwfilter_xml)
@@ -796,7 +817,7 @@ class NWFilterFirewall(object):
for rule in security_group.rules:
rule_xml += "<rule action='accept' direction='in' priority='300'>"
if rule.cidr:
- net, mask = self._get_net_and_mask(rule.cidr)
+ 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']: