From e5080c733076f5098f85952051878f41d47f8181 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 8 Feb 2017 10:43:03 +0000 Subject: [PATCH] libvirt: Ignore 'use_ipv6' for port filters The libvirt driver provides port filtering capability. This capability is enabled when the following is true: - The IPTables firewall driver is enabled - Security groups are disabled - Neutron port filtering is disabled - An IPTables-compatible interface is used, e.g. hybrid mode, where the VIF is a tap device When enabled, libvirt applies IPTables rules that provide MAC, IP, and ARP spoofing protection. At present, setting the 'use_ipv6' config option to False prevents the generation of IPv6 rules even when there are IPv6 subnets available. This is fine when using nova-network, where the same config option is used to control generation of these subnets. However, a mismatch between this nova option and equivalent IPv6 options in neutron would result in IPv6 packets being dropped. Seeing as there is no apparent reason for not allowing IPv6 traffic when the network is IPv6-capable, we can ignore this option. Instead, we use the availability of IPv6-capable subnets as an indicator that IPv6 rules should be added. This paves the way for deprecating the 'use_ipv6' option, which is now only used for two deprecated features: nova-network and file injection. Change-Id: Idcfdaf3b163ba852c9a2c45d5e0c6c35e643c7f5 Implements: blueprint centralize-config-options-pike --- nova/tests/unit/virt/libvirt/test_firewall.py | 10 +------ nova/virt/libvirt/firewall.py | 23 +++++++------- ...wall-ignore-use_ipv6-c555f95799f991fd.yaml | 30 +++++++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 releasenotes/notes/libvirt-firewall-ignore-use_ipv6-c555f95799f991fd.yaml diff --git a/nova/tests/unit/virt/libvirt/test_firewall.py b/nova/tests/unit/virt/libvirt/test_firewall.py index 12954d8bf0c2..bccb453217a5 100644 --- a/nova/tests/unit/virt/libvirt/test_firewall.py +++ b/nova/tests/unit/virt/libvirt/test_firewall.py @@ -314,20 +314,12 @@ class IptablesFirewallTestCase(test.NoDBTestCase): self.assertGreater(len(match_rules), 0, "TCP port 80/81 acceptance rule wasn't added") - def test_filters_for_instance_with_ip_v6(self): - self.flags(use_ipv6=True) + def test_filters_for_instance(self): network_info = _fake_network_info(self, 1) rulesv4, rulesv6 = self.fw._filters_for_instance("fake", network_info) self.assertEqual(len(rulesv4), 2) self.assertEqual(len(rulesv6), 1) - def test_filters_for_instance_without_ip_v6(self): - self.flags(use_ipv6=False) - network_info = _fake_network_info(self, 1) - rulesv4, rulesv6 = self.fw._filters_for_instance("fake", network_info) - self.assertEqual(len(rulesv4), 2) - self.assertEqual(len(rulesv6), 0) - @mock.patch.object(objects.SecurityGroupRuleList, "get_by_instance") def test_multinic_iptables(self, mock_secrule): mock_secrule.return_value = objects.SecurityGroupRuleList() diff --git a/nova/virt/libvirt/firewall.py b/nova/virt/libvirt/firewall.py index 207b3b945b16..dcc6f4a25b00 100644 --- a/nova/virt/libvirt/firewall.py +++ b/nova/virt/libvirt/firewall.py @@ -155,12 +155,12 @@ class NWFilterFirewall(base_firewall.FirewallDriver): dhcp_server = subnet.get_meta('dhcp_server') if dhcp_server: parameters.append(format_parameter('DHCPSERVER', dhcp_server)) - if CONF.use_ipv6: - for subnet in v6_subnets: - gateway = subnet.get('gateway') - if gateway: - ra_server = gateway['address'] + "/128" - parameters.append(format_parameter('RASERVER', ra_server)) + + for subnet in v6_subnets: + gateway = subnet.get('gateway') + if gateway: + ra_server = gateway['address'] + "/128" + parameters.append(format_parameter('RASERVER', ra_server)) if CONF.allow_same_net_traffic: for subnet in v4_subnets: @@ -169,12 +169,11 @@ class NWFilterFirewall(base_firewall.FirewallDriver): parameters.append(format_parameter('PROJNET', net)) parameters.append(format_parameter('PROJMASK', mask)) - if CONF.use_ipv6: - for subnet in v6_subnets: - ipv6_cidr = subnet['cidr'] - net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) - parameters.append(format_parameter('PROJNET6', net)) - parameters.append(format_parameter('PROJMASK6', prefix)) + for subnet in v6_subnets: + ipv6_cidr = subnet['cidr'] + net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) + parameters.append(format_parameter('PROJNET6', net)) + parameters.append(format_parameter('PROJMASK6', prefix)) return parameters diff --git a/releasenotes/notes/libvirt-firewall-ignore-use_ipv6-c555f95799f991fd.yaml b/releasenotes/notes/libvirt-firewall-ignore-use_ipv6-c555f95799f991fd.yaml new file mode 100644 index 000000000000..bf1ac0e051a4 --- /dev/null +++ b/releasenotes/notes/libvirt-firewall-ignore-use_ipv6-c555f95799f991fd.yaml @@ -0,0 +1,30 @@ +--- +upgrade: + - | + The libvirt driver port filtering feature will now ignore the ``use_ipv6`` + config option. + + The libvirt driver provides port filtering capability. This capability + is enabled when the following is true: + + - The ``nova.virt.libvirt.firewall.IptablesFirewallDriver`` firewall driver + is enabled + - Security groups are disabled + - Neutron port filtering is disabled/unsupported + - An IPTables-compatible interface is used, e.g. an OVS VIF in hybrid mode, + where the VIF is a tap device connected to OVS with a bridge + + When enabled, libvirt applies IPTables rules to all interface ports that + provide MAC, IP, and ARP spoofing protection. + + Previously, setting the ``use_ipv6`` config option to ``False`` prevented + the generation of IPv6 rules even when there were IPv6 subnets available. + This was fine when using nova-network, where the same config option was + used to control generation of these subnets. However, a mismatch between + this nova option and equivalent IPv6 options in neutron would have resulted + in IPv6 packets being dropped. + + Seeing as there was no apparent reason for not allowing IPv6 traffic when + the network is IPv6-capable, we now ignore this option. Instead, we use the + availability of IPv6-capable subnets as an indicator that IPv6 rules should + be added.