for d in ns_ip.get_devices(exclude_loopback=True):
if d.name.startswith(FIP_2_ROUTER_DEV_PREFIX):
# internal link between IRs and FIP NS
- # TODO(mrsmith): remove IR interfaces (IP pool?)
- pass
+ ns_ip.del_veth(d.name)
elif d.name.startswith(FIP_EXT_DEV_PREFIX):
# single port from FIP NS to br-ext
# TODO(mrsmith): remove br-ext interface
# device is on default bridge
self.driver.unplug(d.name, namespace=ns,
prefix=INTERNAL_DEV_PREFIX)
+ elif d.name.startswith(ROUTER_2_FIP_DEV_PREFIX):
+ ns_ip.del_veth(d.name)
elif d.name.startswith(EXTERNAL_DEV_PREFIX):
self.driver.unplug(d.name,
bridge=self.conf.external_network_bridge,
#remove default route entry
device = ip_lib.IPDevice(rtr_2_fip_name, self.root_helper,
namespace=ri.ns_name)
+ ns_ip = ip_lib.IPWrapper(self.root_helper, namespace=fip_ns_name)
device.route.delete_gateway(ri.fip_2_rtr, table=FIP_RT_TBL)
self.local_ips.add(ri.rtr_2_fip.rsplit('.', 1)[1])
ri.rtr_2_fip = None
self.local_ips.add(ri.fip_2_rtr.rsplit('.', 1)[1])
ri.fip_2_rtr = None
- # TODO(mrsmith): remove interface
+ ns_ip.del_veth(fip_2_rtr_name)
# clean up fip-namespace if this is the last FIP
self.agent_fip_count = self.agent_fip_count - 1
if self.agent_fip_count == 0:
return (IPDevice(name1, self.root_helper, self.namespace),
IPDevice(name2, self.root_helper, namespace2))
+ def del_veth(self, name):
+ """Delete a virtual interface between two namespaces."""
+ self._as_root('', 'link', ('del', name))
+
def ensure_namespace(self, name):
if not self.netns.exists(name):
ip = self.netns.add(name)
namespaces = ['qrouter-foo', 'qrouter-bar']
self.mock_ip.get_namespaces.return_value = namespaces
- self.mock_ip.get_devices.return_value = [FakeDev('fr-aaaa'),
+ self.mock_ip.get_devices.return_value = [FakeDev('fpr-aaaa'),
FakeDev('fg-aaaa')]
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
agent._destroy_fip_namespace(namespaces[0])
- # TODO(mrsmith): update for fr interface
- self.assertEqual(self.mock_driver.unplug.call_count, 1)
- self.mock_driver.unplug.assert_called_with('fg-aaaa', bridge='br-ex',
- prefix='fg-',
- namespace='qrouter-foo')
+ self.mock_driver.unplug.assert_called_once_with('fg-aaaa',
+ bridge='br-ex',
+ prefix='fg-',
+ namespace='qrouter'
+ '-foo')
+ self.mock_ip.del_veth.assert_called_once_with('fpr-aaaa')
+
+ def test_destroy_namespace(self):
+ class FakeDev(object):
+ def __init__(self, name):
+ self.name = name
+
+ namespace = 'qrouter-bar'
+
+ self.mock_ip.get_namespaces.return_value = [namespace]
+ self.mock_ip.get_devices.return_value = [FakeDev('qr-aaaa'),
+ FakeDev('rfp-aaaa')]
+
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+
+ agent._destroy_namespace(namespace)
+ self.mock_driver.unplug.assert_called_once_with('qr-aaaa',
+ prefix='qr-',
+ namespace='qrouter'
+ '-bar')
+ self.mock_ip.del_veth.assert_called_once_with('rfp-aaaa')
def test_destroy_router_namespace_skips_ns_removal(self):
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
'network_id': _uuid(),
'mac_address': 'ca:fe:de:ad:be:ef',
'ip_cidr': '20.0.0.30/24'}
-
fip_cidr = '11.22.33.44/24'
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
ri.dist_fip_count = 2
ri.floating_ips_dict['11.22.33.44'] = FIP_PRI
+ ri.fip_2_rtr = '11.22.33.42'
+ ri.rtr_2_fip = '11.22.33.40'
agent.agent_gateway_port = agent_gw_port
agent.floating_ip_removed_dist(ri, fip_cidr)
self.mock_rule.delete_rule_priority.assert_called_with(FIP_PRI)
self.mock_ip_dev.route.delete_route.assert_called_with(fip_cidr,
ri.rtr_2_fip)
- # TODO(mrsmith): test ri.dist_fip_count == 0
- # TODO(mrsmith): test agent_fip_count == 0 case
+ with mock.patch.object(agent, '_destroy_fip_namespace') as f:
+ ri.dist_fip_count = 1
+ agent.agent_fip_count = 1
+ fip_ns_name = agent.get_fip_ns_name(
+ str(agent._fetch_external_net_id()))
+ agent.floating_ip_removed_dist(ri, fip_cidr)
+ self.mock_ip.del_veth.assert_called_once_with(
+ agent.get_fip_int_device_name(router['id']))
+ self.mock_ip_dev.route.delete_gateway.assert_called_once_with(
+ '11.22.33.42', table=16)
+ f.assert_called_once_with(fip_ns_name)
class TestL3AgentEventHandler(base.BaseTestCase):