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
(cherry picked from commit f84ce9a57c
)
This commit is contained in:
parent
d599b97b40
commit
a1186b9ddc
@ -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 link_local_allocator as lla
|
||||
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 iptables_manager
|
||||
from neutron.common import constants
|
||||
@ -67,6 +68,7 @@ class FipNamespace(namespaces.Namespace):
|
||||
self.local_subnets = lla.LinkLocalAllocator(
|
||||
path, constants.DVR_FIP_LL_CIDR)
|
||||
self.destroyed = False
|
||||
self._stale_fips_checked = False
|
||||
|
||||
@classmethod
|
||||
def _get_ns_name(cls, ext_net_id):
|
||||
@ -395,3 +397,17 @@ class FipNamespace(namespaces.Namespace):
|
||||
device = ip_lib.IPDevice(rtr_2_fip_interface, namespace=ri.ns_name)
|
||||
if device.exists():
|
||||
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.l3 import dvr_fip_ns
|
||||
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 iptables_manager
|
||||
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):
|
||||
self._test_create_rtr_2_fip_link(True, True)
|
||||
|
||||
@mock.patch.object(router_info.RouterInfo, 'get_router_cidrs')
|
||||
@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()
|
||||
device.exists.return_value = True
|
||||
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(
|
||||
return_value=mock.sentinel.rtr_ext_device_name)
|
||||
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):
|
||||
ri = mock.Mock()
|
||||
ri.dist_fip_count = None
|
||||
ri.floating_ips_dict = {}
|
||||
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)
|
||||
|
||||
def test_scan_fip_ports_restart_none(self):
|
||||
ri = mock.Mock()
|
||||
ri.dist_fip_count = None
|
||||
ri.floating_ips_dict = {}
|
||||
self._test_scan_fip_ports(ri, [])
|
||||
self._test_scan_fip_ports(ri, [], [])
|
||||
self.assertEqual(0, ri.dist_fip_count)
|
||||
|
||||
def test_scan_fip_ports_restart_zero(self):
|
||||
ri = mock.Mock()
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user