From 0436cbdb882b532f0d01c41108508c6d4da3544e Mon Sep 17 00:00:00 2001 From: Takashi Sogabe Date: Wed, 3 Oct 2012 17:19:20 +0900 Subject: handle IPv6 race condition due to hairpin mode bug 1011134 When using IPv6 an instance sees its own neighbour advertisement, because of the reflective property of the hairpin mode. Because of this the trigger-happy duplicate address detection in the instance's kernel deconfigures the IPv6 address on the interface, resulting in no IPv6 connectivity. Approach of this commit is to to add an nwfilter to libvirt which identifies this particular scenario and filters it. Change-Id: I28f9b49cee4b2ab6ff591fae4feee623955f845f --- nova/virt/libvirt/firewall.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/nova/virt/libvirt/firewall.py b/nova/virt/libvirt/firewall.py index b3c6106ff..819a8ec0c 100644 --- a/nova/virt/libvirt/firewall.py +++ b/nova/virt/libvirt/firewall.py @@ -57,6 +57,23 @@ class NWFilterFirewall(base_firewall.FirewallDriver): return self._libvirt_get_connection() _conn = property(_get_connection) + @staticmethod + def nova_no_nd_reflection_filter(): + """ + This filter protects false positives on IPv6 Duplicate Address + Detection(DAD). + """ + return ''' + + + + + + + ''' + @staticmethod def nova_dhcp_filter(): """The standard allow-dhcp-server filter is an one, so it uses @@ -122,15 +139,15 @@ class NWFilterFirewall(base_firewall.FirewallDriver): if self.static_filters_configured: return - self._define_filter(self._filter_container('nova-base', - ['no-mac-spoofing', - 'no-ip-spoofing', - 'no-arp-spoofing', - 'allow-dhcp-server'])) - self._define_filter(self._filter_container('nova-nodhcp', - ['no-mac-spoofing', - 'no-ip-spoofing', - 'no-arp-spoofing'])) + filter_set = ['no-mac-spoofing', + 'no-ip-spoofing', + 'no-arp-spoofing'] + if FLAGS.use_ipv6: + self._define_filter(self.nova_no_nd_reflection_filter) + filter_set.append('nova-no-nd-reflection') + self._define_filter(self._filter_container('nova-nodhcp', filter_set)) + filter_set.append('allow-dhcp-server') + self._define_filter(self._filter_container('nova-base', filter_set)) self._define_filter(self._filter_container('nova-vpn', ['allow-dhcp-server'])) self._define_filter(self.nova_dhcp_filter) -- cgit