Fix bug when checking duplicated subnets for router interface

If user set gateway for router first, and gateway subnet
overlapped with tenant subnet, will cause add router interface
to fail.

Add router interface checking for duplicated subnets should
ingore the gateway network.

This patch also filters gateway network when creating gw port.

Change-Id: Idcc8be221656ace13b12b62f559e4cb9a6af4f32
Closes-Bug: #1697410
This commit is contained in:
Dongcan Ye 2017-06-12 18:39:55 +08:00
parent 01cc2696b7
commit 0415f4f50c
2 changed files with 39 additions and 3 deletions
neutron
db
tests/unit/extensions

@ -463,7 +463,9 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
raise e.errors[0].error
self._check_for_dup_router_subnets(context, router,
new_network_id, subnets)
new_network_id,
subnets,
include_gateway=True)
self._create_router_gw_port(context, router,
new_network_id, ext_ips)
registry.notify(resources.ROUTER_GATEWAY,
@ -578,7 +580,8 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
filters=filters)
def _check_for_dup_router_subnets(self, context, router,
network_id, new_subnets):
network_id, new_subnets,
include_gateway=False):
# It's possible these ports are on the same network, but
# different subnets.
new_subnet_ids = {s['id'] for s in new_subnets}
@ -589,7 +592,10 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
msg = (_("Router already has a port on subnet %s")
% ip['subnet_id'])
raise n_exc.BadRequest(resource='router', msg=msg)
router_subnets.append(ip['subnet_id'])
gw_owner = (p.get('device_owner') == DEVICE_OWNER_ROUTER_GW)
if include_gateway == gw_owner:
router_subnets.append(ip['subnet_id'])
# Ignore temporary Prefix Delegation CIDRs
new_subnets = [s for s in new_subnets
if s['cidr'] != n_const.PROVISIONAL_IPV6_PD_PREFIX]

@ -1580,6 +1580,36 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
expected_code=exc.
HTTPBadRequest.code)
def test_router_add_interface_cidr_overlapped_with_gateway(self):
with self.router() as r:
with self.subnet(cidr='10.0.1.0/24') as s1, self.subnet(
cidr='10.0.0.0/16') as s2:
self._set_net_external(s2['subnet']['network_id'])
self._add_external_gateway_to_router(
r['router']['id'],
s2['subnet']['network_id'])
res = self._router_interface_action('add',
r['router']['id'],
s1['subnet']['id'],
None)
self.assertIn('port_id', res)
def test_router_add_interface_by_port_cidr_overlapped_with_gateway(self):
with self.router() as r:
with self.subnet(cidr='10.0.1.0/24') as s1, self.subnet(
cidr='10.0.0.0/16') as s2:
with self.port(subnet=s1) as p:
self._set_net_external(s2['subnet']['network_id'])
self._add_external_gateway_to_router(
r['router']['id'],
s2['subnet']['network_id'])
res = self._router_interface_action('add',
r['router']['id'],
None,
p['port']['id'])
self.assertIn('port_id', res)
def test_router_add_gateway_dup_subnet1_returns_400(self):
with self.router() as r:
with self.subnet() as s: