Auto allocate gateway_ip even for SLAAC subnets

For a SLAAC subnet that is created without specifying the gateway_ip,
Neutron currently allocates (If0c48a7287a828eef4a0f0b0859d4f898d2937bd)
the gateway_ip at a later stage (i.e., neutron router_interface_add).
In order to keep the API consistent between IPv4 and IPv6, it is
recommended to allocate the gateway_ip during subnet_create stage itself.

Closes-Bug: #1402407
Closes-Bug: #1394112
Partial-Bug: #1377985
Change-Id: I965232930502c21b605fe360bb138bb6ea73d2b0
(cherry picked from commit 66dcb8b935)
This commit is contained in:
sridhargaddam 2014-11-20 07:39:54 +00:00
parent b3295989d6
commit 2f97180833
5 changed files with 20 additions and 14 deletions

View File

@ -1083,10 +1083,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
s = subnet['subnet']
if s['gateway_ip'] is attributes.ATTR_NOT_SPECIFIED:
if s['ip_version'] == 6 and ipv6_utils.is_slaac_subnet(s):
s['gateway_ip'] = None
else:
s['gateway_ip'] = str(netaddr.IPAddress(net.first + 1))
s['gateway_ip'] = str(netaddr.IPAddress(net.first + 1))
if s['allocation_pools'] == attributes.ATTR_NOT_SPECIFIED:
s['allocation_pools'] = self._allocate_pools_for_subnet(context, s)

View File

@ -21,7 +21,6 @@ from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api
from neutron.api.v2 import attributes
from neutron.common import constants as l3_constants
from neutron.common import exceptions as n_exc
from neutron.common import ipv6_utils
from neutron.common import rpc as n_rpc
from neutron.common import utils
from neutron.db import model_base
@ -462,19 +461,15 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
def _add_interface_by_subnet(self, context, router, subnet_id, owner):
subnet = self._core_plugin._get_subnet(context, subnet_id)
if (not subnet['gateway_ip']
and not ipv6_utils.is_slaac_subnet(subnet)):
if not subnet['gateway_ip']:
msg = _('Subnet for router interface must have a gateway IP')
raise n_exc.BadRequest(resource='router', msg=msg)
self._check_for_dup_router_subnet(context, router,
subnet['network_id'],
subnet_id,
subnet['cidr'])
if subnet['gateway_ip']:
fixed_ip = {'ip_address': subnet['gateway_ip'],
'subnet_id': subnet['id']}
else:
fixed_ip = {'subnet_id': subnet['id']}
fixed_ip = {'ip_address': subnet['gateway_ip'],
'subnet_id': subnet['id']}
return self._core_plugin.create_port(context, {
'port':

View File

@ -102,6 +102,9 @@ class TestOneConvergenceL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase):
_plugin_name = PLUGIN_NAME
def setUp(self):
if 'v6' in self._testMethodName:
self.skipTest("NVSD Plugin does not support IPV6.")
def mocked_oneconvergence_init(self):
def side_effect(*args, **kwargs):
return {'id': str(uuid.uuid4())}

View File

@ -2900,8 +2900,8 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
cidr=cidr, ip_version=6,
ipv6_ra_mode=constants.DHCPV6_STATEFUL,
ipv6_address_mode=constants.DHCPV6_STATEFUL)
# Gateway not specified for IPv6 SLAAC subnet
expected = {'gateway_ip': None,
# If gateway_ip is not specified, allocate first IP from the subnet
expected = {'gateway_ip': gateway,
'cidr': cidr}
self._test_create_subnet(expected=expected,
cidr=cidr, ip_version=6,

View File

@ -769,6 +769,17 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
# nsx metadata access case
self.assertIn(payload['tenant_id'], [stid, ''])
def test_router_add_interface_ipv6_subnet_without_gateway_ip(self):
with self.router() as r:
with self.subnet(ip_version=6, cidr='fe80::/64',
gateway_ip=None) as s:
error_code = exc.HTTPBadRequest.code
self._router_interface_action('add',
r['router']['id'],
s['subnet']['id'],
None,
expected_code=error_code)
def test_router_add_interface_subnet_with_bad_tenant_returns_404(self):
with mock.patch('neutron.context.Context.to_dict') as tdict:
tenant_id = _uuid()