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: #
1394112
Change-Id: I965232930502c21b605fe360bb138bb6ea73d2b0
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)
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
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':
_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())}
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,
# 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()