From 5fb947208e7141e572d7e2e95165c715f23b5fda Mon Sep 17 00:00:00 2001 From: Ante Karamatic Date: Sat, 20 Apr 2013 10:50:14 +0200 Subject: Destroy conntrack table on source host during migration If a VM migrates from hostA to hostB, there will still be connections in the conntrack table of the hostA. If, for any reason, VM is migrated back to the hostA, while those connections are still in conntrack table, persistent connections (such is ssh) to VM, from outside, will get dropped. They get dropped cause hostA was expecting different packets and cause of that requires establishing new connection. By dropping conntrack table entries for VM we make sure that connection flow is not interupted by old packets. Change-Id: If8e146e05914e9febd6fc40a1d8085306c1244ea --- etc/nova/rootwrap.d/network.filters | 3 +++ nova/network/floating_ips.py | 4 ++++ nova/network/l3.py | 9 +++++++++ nova/network/linux_net.py | 8 ++++++++ nova/tests/network/test_manager.py | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/etc/nova/rootwrap.d/network.filters b/etc/nova/rootwrap.d/network.filters index c58bc77e7..f29bd16d2 100644 --- a/etc/nova/rootwrap.d/network.filters +++ b/etc/nova/rootwrap.d/network.filters @@ -76,3 +76,6 @@ brctl: CommandFilter, brctl, root # nova/network/linux_net.py: 'sysctl', .... sysctl: CommandFilter, /sbin/sysctl, root + +# nova/network/linux_net.py: 'conntrack' +conntrack: CommandFilter, conntrack, root diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py index c35dc85f9..bc8c05d26 100644 --- a/nova/network/floating_ips.py +++ b/nova/network/floating_ips.py @@ -548,6 +548,10 @@ class FloatingIP(object): interface, fixed_ip['network']) + # NOTE(ivoks): Destroy conntrack entries on source compute + # host. + self.l3driver.clean_conntrack(fixed_ip['address']) + # NOTE(wenjianhn): Make this address will not be bound to public # interface when restarts nova-network on dest compute node self.db.floating_ip_update(context, diff --git a/nova/network/l3.py b/nova/network/l3.py index 7511f7ba4..a7961f0c9 100644 --- a/nova/network/l3.py +++ b/nova/network/l3.py @@ -66,6 +66,9 @@ class L3Driver(object): def remove_vpn(self, public_ip, port, private_ip): raise NotImplementedError() + def clean_conntrack(self, fixed_ip): + raise NotImplementedError() + def teardown(self): raise NotImplementedError() @@ -125,6 +128,9 @@ class LinuxNetL3(L3Driver): # the VPN forwarding rules pass + def clean_conntrack(self, fixed_ip): + linux_net.clean_conntrack(fixed_ip) + def teardown(self): pass @@ -165,5 +171,8 @@ class NullL3(L3Driver): def remove_vpn(self, public_ip, port, private_ip): pass + def clean_conntrack(self, fixed_ip): + pass + def teardown(self): pass diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 3ee5d7400..bf4b04f85 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -767,6 +767,14 @@ def floating_forward_rules(floating_ip, fixed_ip, device): return rules +def clean_conntrack(fixed_ip): + try: + _execute('conntrack', '-D', '-r', fixed_ip, run_as_root=True, + check_exit_code=[0, 1]) + except exception.ProcessExecutionError: + LOG.exception(_('Error deleting conntrack entries for %s'), fixed_ip) + + def initialize_gateway_device(dev, network_ref): if not network_ref: return diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index f0d8e58a9..7fa347ceb 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -2161,6 +2161,10 @@ class FloatingIPTestCase(test.TestCase): network): called['count'] += 1 + def fake_clean_conntrack(fixed_ip): + if not fixed_ip == "10.0.0.2": + raise exception.FixedIpInvalid(address=fixed_ip) + def fake_floating_ip_update(context, address, args): pass @@ -2173,6 +2177,8 @@ class FloatingIPTestCase(test.TestCase): fake_floating_ip_update) self.stubs.Set(self.network.l3driver, 'remove_floating_ip', fake_remove_floating_ip) + self.stubs.Set(self.network.l3driver, 'clean_conntrack', + fake_clean_conntrack) self.mox.ReplayAll() addresses = ['172.24.4.23', '172.24.4.24', '172.24.4.25'] self.network.migrate_instance_start(self.context, -- cgit