summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp>2011-01-12 21:55:36 +0900
committerHisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp>2011-01-12 21:55:36 +0900
commitb945fed7779bddf799aa4a180d44745052d2da8c (patch)
tree2075e3d34170f3ef34cfd75b923787cf5d094145
parenta6a2a057d8a027781e4270c9abc4f815c67293ec (diff)
downloadnova-b945fed7779bddf799aa4a180d44745052d2da8c.tar.gz
nova-b945fed7779bddf799aa4a180d44745052d2da8c.tar.xz
nova-b945fed7779bddf799aa4a180d44745052d2da8c.zip
Support IPv6 firewall with IptablesFirewallDriver
-rw-r--r--nova/db/sqlalchemy/api.py2
-rw-r--r--nova/virt/libvirt_conn.py66
2 files changed, 52 insertions, 16 deletions
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']