summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Nikanorov <enikanorov@mirantis.com>2014-08-25 00:59:02 +0400
committerKyle Mestery <mestery@mestery.com>2014-10-07 16:04:48 +0000
commita56a35572d7b7d4b534825fe7b4f681028121a74 (patch)
treeb35ce9c0e14246d4b470b1818871c2152c00b9aa
parent205162f58050fcb94db53cd51b674d2093dfe700 (diff)
downloadneutron-a56a35572d7b7d4b534825fe7b4f681028121a74.tar.gz
Raise exception if ipv6 prefix is inappropriate for address mode
Address prefix to use with slaac and stateless ipv6 address modes should be equal to 64 in order to work properly. The patch adds corresponding validation and fixes unit tests accordingly. Change-Id: I6c344b21a69f85f2885a72377171f70309b26775 Closes-Bug: #1357084 (cherry picked from commit 0d8911115e1b722da2f1e92f444e53b22223ee32)
-rw-r--r--neutron/db/db_base_plugin_v2.py15
-rw-r--r--neutron/tests/unit/test_db_plugin.py30
2 files changed, 36 insertions, 9 deletions
diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py
index c7e82d5bc4..155b9f3995 100644
--- a/neutron/db/db_base_plugin_v2.py
+++ b/neutron/db/db_base_plugin_v2.py
@@ -758,6 +758,21 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
if ra_mode_set and address_mode_set:
self._validate_ipv6_combination(subnet['ipv6_ra_mode'],
subnet['ipv6_address_mode'])
+ if address_mode_set:
+ self._validate_eui64_applicable(subnet)
+
+ def _validate_eui64_applicable(self, subnet):
+ # Per RFC 4862, section 5.5.3, prefix length and interface
+ # id together should be equal to 128. Currently neutron supports
+ # EUI64 interface id only, thus limiting the prefix
+ # length to be 64 only.
+ if self._check_if_subnet_uses_eui64(subnet):
+ if netaddr.IPNetwork(subnet['cidr']).prefixlen != 64:
+ msg = _('Invalid CIDR %s for IPv6 address mode. '
+ 'OpenStack uses the EUI-64 address format, '
+ 'which requires the prefix to be /64.')
+ raise n_exc.InvalidInput(
+ error_message=(msg % subnet['cidr']))
def _validate_ipv6_combination(self, ra_mode, address_mode):
if ra_mode != address_mode:
diff --git a/neutron/tests/unit/test_db_plugin.py b/neutron/tests/unit/test_db_plugin.py
index f6b8204886..a391eefcc7 100644
--- a/neutron/tests/unit/test_db_plugin.py
+++ b/neutron/tests/unit/test_db_plugin.py
@@ -1392,13 +1392,13 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
self._delete('ports', port3['port']['id'])
self._delete('ports', port4['port']['id'])
- def test_ip_allocation_for_ipv6_subnet_slaac_adddress_mode(self):
+ def test_ip_allocation_for_ipv6_subnet_slaac_address_mode(self):
res = self._create_network(fmt=self.fmt, name='net',
admin_state_up=True)
network = self.deserialize(self.fmt, res)
v6_subnet = self._make_subnet(self.fmt, network,
gateway='fe80::1',
- cidr='fe80::/80',
+ cidr='fe80::/64',
ip_version=6,
ipv6_ra_mode=None,
ipv6_address_mode=constants.IPV6_SLAAC)
@@ -2361,6 +2361,18 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
res = subnet_req.get_response(self.api)
self.assertEqual(res.status_int, webob.exc.HTTPClientError.code)
+ def test_create_subnet_V6_slaac_big_prefix(self):
+ with self.network() as network:
+ data = {'subnet': {'network_id': network['network']['id'],
+ 'cidr': '2014::/65',
+ 'ip_version': '6',
+ 'tenant_id': network['network']['tenant_id'],
+ 'gateway_ip': 'fe80::1',
+ 'ipv6_address_mode': 'slaac'}}
+ subnet_req = self.new_create_request('subnets', data)
+ res = subnet_req.get_response(self.api)
+ self.assertEqual(webob.exc.HTTPClientError.code, res.status_int)
+
def test_create_2_subnets_overlapping_cidr_allowed_returns_200(self):
cidr_1 = '10.0.0.0/23'
cidr_2 = '10.0.0.0/24'
@@ -3028,7 +3040,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
def test_create_subnet_ipv6_attributes(self):
gateway_ip = 'fe80::1'
- cidr = 'fe80::/80'
+ cidr = 'fe80::/64'
for mode in constants.IPV6_MODES:
self._test_create_subnet(gateway_ip=gateway_ip,
@@ -3060,7 +3072,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
def test_create_subnet_ipv6_attributes_no_dhcp_enabled(self):
gateway_ip = 'fe80::1'
- cidr = 'fe80::/80'
+ cidr = 'fe80::/64'
with testlib_api.ExpectedException(
webob.exc.HTTPClientError) as ctx_manager:
for mode in constants.IPV6_MODES:
@@ -3110,7 +3122,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
def test_create_subnet_ipv6_single_attribute_set(self):
gateway_ip = 'fe80::1'
- cidr = 'fe80::/80'
+ cidr = 'fe80::/64'
for mode in constants.IPV6_MODES:
self._test_create_subnet(gateway_ip=gateway_ip,
cidr=cidr, ip_version=6,
@@ -3301,7 +3313,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
webob.exc.HTTPConflict.code)
def test_update_subnet_ipv6_attributes(self):
- with self.subnet(ip_version=6, cidr='fe80::/80',
+ with self.subnet(ip_version=6, cidr='fe80::/64',
ipv6_ra_mode=constants.IPV6_SLAAC,
ipv6_address_mode=constants.IPV6_SLAAC) as subnet:
data = {'subnet': {'ipv6_ra_mode': constants.DHCPV6_STATEFUL,
@@ -3315,7 +3327,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
data['subnet']['ipv6_address_mode'])
def test_update_subnet_ipv6_inconsistent_ra_attribute(self):
- with self.subnet(ip_version=6, cidr='fe80::/80',
+ with self.subnet(ip_version=6, cidr='fe80::/64',
ipv6_ra_mode=constants.IPV6_SLAAC,
ipv6_address_mode=constants.IPV6_SLAAC) as subnet:
data = {'subnet': {'ipv6_ra_mode': constants.DHCPV6_STATEFUL}}
@@ -3326,7 +3338,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
webob.exc.HTTPClientError.code)
def test_update_subnet_ipv6_inconsistent_address_attribute(self):
- with self.subnet(ip_version=6, cidr='fe80::/80',
+ with self.subnet(ip_version=6, cidr='fe80::/64',
ipv6_ra_mode=constants.IPV6_SLAAC,
ipv6_address_mode=constants.IPV6_SLAAC) as subnet:
data = {'subnet': {'ipv6_address_mode': constants.DHCPV6_STATEFUL}}
@@ -3337,7 +3349,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
webob.exc.HTTPClientError.code)
def test_update_subnet_ipv6_inconsistent_enable_dhcp(self):
- with self.subnet(ip_version=6, cidr='fe80::/80',
+ with self.subnet(ip_version=6, cidr='fe80::/64',
ipv6_ra_mode=constants.IPV6_SLAAC,
ipv6_address_mode=constants.IPV6_SLAAC) as subnet:
data = {'subnet': {'enable_dhcp': False}}