DVR: Fix check multiprefix when delete ipv4 router interface

Current code will prevent from deleting router centralized snat port,
when there is a ipv6 subnet attatched to DVR.

This is correct when deleting a v6 router centralized snat port, because
multiple v6 subnets share one router port.

But it is not correct when deleteing a v4 router centralized snat port,
because v4 subnet doesn't share router port with v6 subnet. Deleteing a
v4 router centralized snat port should be allowed no matter if there is
v6 subnet attached to DVR.

Change-Id: I2d06c8c79f9ff9a9300a94bcbbae13569e4d963e
Closes-bug: #1581348
This commit is contained in:
Hong Hui Xiao 2016-05-13 07:12:57 +00:00
parent c4f03418cc
commit 084173338e
2 changed files with 60 additions and 0 deletions

View File

@ -358,6 +358,12 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
[fixedip for fixedip in
cs_port['port']['fixed_ips']
if fixedip['subnet_id'] != subnet_id])
if len(fixed_ips) == len(cs_port['port']['fixed_ips']):
# The subnet being detached from router is not part of
# ipv6 router port. No need to update the multiprefix.
return False
if fixed_ips:
# multiple prefix port - delete prefix from port
self._core_plugin.update_port(

View File

@ -526,6 +526,60 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
self.ctx, filters=dvr_filters)
self.assertEqual(1, len(dvr_ports))
def test_remove_router_interface_csnat_ports_removal_with_ipv6(self):
router_dict = {'name': 'test_router', 'admin_state_up': True,
'distributed': True}
router = self._create_router(router_dict)
plugin = mock.MagicMock()
with self.network() as net_ext, self.network() as net_int:
ext_net_id = net_ext['network']['id']
self.core_plugin.update_network(
self.ctx, ext_net_id,
{'network': {'router:external': True}})
self.mixin.update_router(
self.ctx, router['id'],
{'router': {'external_gateway_info':
{'network_id': ext_net_id}}})
with self.subnet(
network=net_int, cidr='20.0.0.0/24') as subnet_v4,\
self.subnet(
network=net_int, cidr='fe80::/64',
gateway_ip='fe80::1', ip_version=6) as subnet_v6:
self.mixin.add_router_interface(self.ctx, router['id'],
{'subnet_id': subnet_v4['subnet']['id']})
self.mixin.add_router_interface(self.ctx, router['id'],
{'subnet_id': subnet_v6['subnet']['id']})
csnat_filters = {'device_owner':
[l3_const.DEVICE_OWNER_ROUTER_SNAT]}
csnat_ports = self.core_plugin.get_ports(
self.ctx, filters=csnat_filters)
self.assertEqual(2, len(csnat_ports))
dvr_filters = {'device_owner':
[l3_const.DEVICE_OWNER_DVR_INTERFACE]}
dvr_ports = self.core_plugin.get_ports(
self.ctx, filters=dvr_filters)
self.assertEqual(2, len(dvr_ports))
with mock.patch.object(
manager.NeutronManager,
'get_service_plugins') as get_svc_plugin:
get_svc_plugin.return_value = {
plugin_const.L3_ROUTER_NAT: plugin}
self.mixin.manager = manager
self.mixin.remove_router_interface(
self.ctx, router['id'],
{'subnet_id': subnet_v4['subnet']['id']})
csnat_ports = self.core_plugin.get_ports(
self.ctx, filters=csnat_filters)
self.assertEqual(1, len(csnat_ports))
self.assertEqual(
subnet_v6['subnet']['id'],
csnat_ports[0]['fixed_ips'][0]['subnet_id'])
dvr_ports = self.core_plugin.get_ports(
self.ctx, filters=dvr_filters)
self.assertEqual(1, len(dvr_ports))
def test__validate_router_migration_notify_advanced_services(self):
router = {'name': 'foo_router', 'admin_state_up': False}
router_db = self._create_router(router)