Remove stale floating IP addresses from rfp devices
Old versions of the DVR code used to configure floating IP addresses directly on the rfp-* devices in the qrouter namespace. This was changed in Mitaka to use routes, but these stale floating IP addresses were never cleaned-up when the l3-agent was restarted. Add a check for these addresses and remove them at startup if they exist. This can be removed in a cycle since once they are cleaned they will not be added back by the agent. Change-Id: Id512d213cd7ee11da913a4e4b0da20c3ad5420b0 Closes-bug: #1675187
This commit is contained in:
parent
46fef3a26a
commit
f84ce9a57c
@ -23,6 +23,7 @@ from neutron._i18n import _, _LE, _LW
|
|||||||
from neutron.agent.l3 import fip_rule_priority_allocator as frpa
|
from neutron.agent.l3 import fip_rule_priority_allocator as frpa
|
||||||
from neutron.agent.l3 import link_local_allocator as lla
|
from neutron.agent.l3 import link_local_allocator as lla
|
||||||
from neutron.agent.l3 import namespaces
|
from neutron.agent.l3 import namespaces
|
||||||
|
from neutron.agent.l3 import router_info
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
from neutron.agent.linux import iptables_manager
|
from neutron.agent.linux import iptables_manager
|
||||||
from neutron.common import constants
|
from neutron.common import constants
|
||||||
@ -67,6 +68,7 @@ class FipNamespace(namespaces.Namespace):
|
|||||||
self.local_subnets = lla.LinkLocalAllocator(
|
self.local_subnets = lla.LinkLocalAllocator(
|
||||||
path, constants.DVR_FIP_LL_CIDR)
|
path, constants.DVR_FIP_LL_CIDR)
|
||||||
self.destroyed = False
|
self.destroyed = False
|
||||||
|
self._stale_fips_checked = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_ns_name(cls, ext_net_id):
|
def _get_ns_name(cls, ext_net_id):
|
||||||
@ -394,3 +396,17 @@ class FipNamespace(namespaces.Namespace):
|
|||||||
device = ip_lib.IPDevice(rtr_2_fip_interface, namespace=ri.ns_name)
|
device = ip_lib.IPDevice(rtr_2_fip_interface, namespace=ri.ns_name)
|
||||||
if device.exists():
|
if device.exists():
|
||||||
ri.dist_fip_count = len(ri.get_router_cidrs(device))
|
ri.dist_fip_count = len(ri.get_router_cidrs(device))
|
||||||
|
# On upgrade, there could be stale IP addresses configured, check
|
||||||
|
# and remove them once.
|
||||||
|
# TODO(haleyb): this can go away after a cycle or two
|
||||||
|
if not self._stale_fips_checked:
|
||||||
|
stale_cidrs = (
|
||||||
|
ip for ip in router_info.RouterInfo.get_router_cidrs(
|
||||||
|
ri, device)
|
||||||
|
if common_utils.is_cidr_host(ip))
|
||||||
|
for ip_cidr in stale_cidrs:
|
||||||
|
LOG.debug("Removing stale floating ip %s from interface "
|
||||||
|
"%s in namespace %s",
|
||||||
|
ip_cidr, rtr_2_fip_interface, ri.ns_name)
|
||||||
|
device.delete_addr_and_conntrack_state(ip_cidr)
|
||||||
|
self._stale_fips_checked = True
|
||||||
|
@ -20,6 +20,7 @@ from oslo_utils import uuidutils
|
|||||||
from neutron.agent.common import utils
|
from neutron.agent.common import utils
|
||||||
from neutron.agent.l3 import dvr_fip_ns
|
from neutron.agent.l3 import dvr_fip_ns
|
||||||
from neutron.agent.l3 import link_local_allocator as lla
|
from neutron.agent.l3 import link_local_allocator as lla
|
||||||
|
from neutron.agent.l3 import router_info
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
from neutron.agent.linux import iptables_manager
|
from neutron.agent.linux import iptables_manager
|
||||||
from neutron.common import exceptions as n_exc
|
from neutron.common import exceptions as n_exc
|
||||||
@ -311,32 +312,39 @@ class TestDvrFipNs(base.BaseTestCase):
|
|||||||
def test_create_rtr_2_fip_link_and_addr_already_exist(self):
|
def test_create_rtr_2_fip_link_and_addr_already_exist(self):
|
||||||
self._test_create_rtr_2_fip_link(True, True)
|
self._test_create_rtr_2_fip_link(True, True)
|
||||||
|
|
||||||
|
@mock.patch.object(router_info.RouterInfo, 'get_router_cidrs')
|
||||||
@mock.patch.object(ip_lib, 'IPDevice')
|
@mock.patch.object(ip_lib, 'IPDevice')
|
||||||
def _test_scan_fip_ports(self, ri, ip_list, IPDevice):
|
def _test_scan_fip_ports(self, ri, ip_list, stale_list, IPDevice,
|
||||||
|
get_router_cidrs):
|
||||||
IPDevice.return_value = device = mock.Mock()
|
IPDevice.return_value = device = mock.Mock()
|
||||||
device.exists.return_value = True
|
device.exists.return_value = True
|
||||||
ri.get_router_cidrs.return_value = ip_list
|
ri.get_router_cidrs.return_value = ip_list
|
||||||
|
get_router_cidrs.return_value = stale_list
|
||||||
self.fip_ns.get_rtr_ext_device_name = mock.Mock(
|
self.fip_ns.get_rtr_ext_device_name = mock.Mock(
|
||||||
return_value=mock.sentinel.rtr_ext_device_name)
|
return_value=mock.sentinel.rtr_ext_device_name)
|
||||||
self.fip_ns.scan_fip_ports(ri)
|
self.fip_ns.scan_fip_ports(ri)
|
||||||
|
if stale_list:
|
||||||
|
device.delete_addr_and_conntrack_state.assert_called_once_with(
|
||||||
|
stale_list[0])
|
||||||
|
|
||||||
def test_scan_fip_ports_restart_fips(self):
|
def test_scan_fip_ports_restart_fips(self):
|
||||||
ri = mock.Mock()
|
ri = mock.Mock()
|
||||||
ri.dist_fip_count = None
|
ri.dist_fip_count = None
|
||||||
ri.floating_ips_dict = {}
|
ri.floating_ips_dict = {}
|
||||||
ip_list = [{'cidr': '111.2.3.4'}, {'cidr': '111.2.3.5'}]
|
ip_list = [{'cidr': '111.2.3.4'}, {'cidr': '111.2.3.5'}]
|
||||||
self._test_scan_fip_ports(ri, ip_list)
|
stale_list = ['111.2.3.7/32']
|
||||||
|
self._test_scan_fip_ports(ri, ip_list, stale_list)
|
||||||
self.assertEqual(2, ri.dist_fip_count)
|
self.assertEqual(2, ri.dist_fip_count)
|
||||||
|
|
||||||
def test_scan_fip_ports_restart_none(self):
|
def test_scan_fip_ports_restart_none(self):
|
||||||
ri = mock.Mock()
|
ri = mock.Mock()
|
||||||
ri.dist_fip_count = None
|
ri.dist_fip_count = None
|
||||||
ri.floating_ips_dict = {}
|
ri.floating_ips_dict = {}
|
||||||
self._test_scan_fip_ports(ri, [])
|
self._test_scan_fip_ports(ri, [], [])
|
||||||
self.assertEqual(0, ri.dist_fip_count)
|
self.assertEqual(0, ri.dist_fip_count)
|
||||||
|
|
||||||
def test_scan_fip_ports_restart_zero(self):
|
def test_scan_fip_ports_restart_zero(self):
|
||||||
ri = mock.Mock()
|
ri = mock.Mock()
|
||||||
ri.dist_fip_count = 0
|
ri.dist_fip_count = 0
|
||||||
self._test_scan_fip_ports(ri, None)
|
self._test_scan_fip_ports(ri, None, [])
|
||||||
self.assertEqual(0, ri.dist_fip_count)
|
self.assertEqual(0, ri.dist_fip_count)
|
||||||
|
Loading…
Reference in New Issue
Block a user