]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Raise exception if ipv6 prefix is inappropriate for address mode
authorEugene Nikanorov <enikanorov@mirantis.com>
Sun, 24 Aug 2014 20:59:02 +0000 (00:59 +0400)
committerEugene Nikanorov <enikanorov@mirantis.com>
Sun, 28 Sep 2014 18:03:46 +0000 (22:03 +0400)
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

neutron/db/db_base_plugin_v2.py
neutron/tests/unit/test_db_plugin.py

index c7e82d5bc41a551550497a88f50ed02c8b04bf5a..155b9f3995d07e3449c6b4ec4e7ee62c320ffd15 100644 (file)
@@ -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:
index 7754cc2b12d6a4a03f75d80a4b44df0c791f5202..2db224339561dae299e11b603d1cb58a7cdc3d58 100644 (file)
@@ -1390,13 +1390,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)
@@ -2359,6 +2359,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'
@@ -3026,7 +3038,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,
@@ -3058,7 +3070,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:
@@ -3108,7 +3120,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,
@@ -3299,7 +3311,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,
@@ -3313,7 +3325,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}}
@@ -3324,7 +3336,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}}
@@ -3335,7 +3347,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}}