Subnet mapping broken with overlapping ips

This is a workaround that checks if a given subnet allocated for
an EPG overlaps with any other existing subnet in the related
L3_Policy context.

Not a solutuion to the subnet allocation problem.

Workarounds bug #1383947

Change-Id: I1c00a7452a0417c4f63ded79d6fc0b35c8df8828
This commit is contained in:
Ivar Lazzaro
2014-10-28 18:03:19 -07:00
parent 62e8818cf2
commit bba2a768ab
2 changed files with 34 additions and 0 deletions

View File

@@ -555,7 +555,21 @@ class ResourceMappingDriver(api.PolicyDriver):
l3p_id = l2p['l3_policy_id']
l3p = context._plugin.get_l3_policy(context._plugin_context, l3p_id)
pool = netaddr.IPNetwork(l3p['ip_pool'])
l2ps = context._plugin.get_l2_policies(
context._plugin_context, filters={'l3_policy_id': [l3p['id']]})
epgs = context._plugin.get_endpoint_groups(
context._plugin_context,
filters={'l2_policy_id': [x['id'] for x in l2ps]})
subnets = []
for epg in epgs:
subnets.extend(epg['subnets'])
subnets = self._core_plugin.get_subnets(context._plugin_context,
filters={'id': subnets})
for cidr in pool.subnet(l3p['subnet_prefix_length']):
if not self._validate_subnet_overlap_for_l3p(subnets,
cidr.__str__()):
continue
try:
attrs = {'tenant_id': context.current['tenant_id'],
'name': 'epg_' + context.current['name'],
@@ -593,6 +607,13 @@ class ResourceMappingDriver(api.PolicyDriver):
pass
raise exc.NoSubnetAvailable()
def _validate_subnet_overlap_for_l3p(self, subnets, subnet_cidr):
new_subnet_ipset = netaddr.IPSet([subnet_cidr])
for subnet in subnets:
if (netaddr.IPSet([subnet['cidr']]) & new_subnet_ipset):
return False
return True
def _use_explicit_subnet(self, plugin_context, subnet_id, router_id):
interface_info = {'subnet_id': subnet_id}
if router_id:

View File

@@ -46,6 +46,7 @@ class ResourceMappingTestCase(
config.cfg.CONF.set_override('policy_drivers',
['implicit_policy', 'resource_mapping'],
group='group_policy')
config.cfg.CONF.set_override('allow_overlapping_ips', True)
super(ResourceMappingTestCase, self).setUp(core_plugin=CORE_PLUGIN)
@@ -267,6 +268,18 @@ class TestEndpointGroup(ResourceMappingTestCase):
self.assertNotEqual(subnet1['subnet']['cidr'],
subnet2['subnet']['cidr'])
def test_no_extra_subnets_created(self):
count = len(self._get_all_subnets())
self.create_endpoint_group()
self.create_endpoint_group()
new_count = len(self._get_all_subnets())
self.assertEqual(count + 2, new_count)
def _get_all_subnets(self):
req = self.new_list_request('subnets', fmt=self.fmt)
return self.deserialize(self.fmt,
req.get_response(self.api))['subnets']
# TODO(rkukura): Test ip_pool exhaustion.