Merge "Fix validation of IPv6 subnets with external RAs" into stable/rocky
This commit is contained in:
commit
7bc6864626
|
@ -116,6 +116,15 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||||
if l3plugin and port_check:
|
if l3plugin and port_check:
|
||||||
l3plugin.prevent_l3_port_deletion(context, port_id)
|
l3plugin.prevent_l3_port_deletion(context, port_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _validate_subnet_address_mode(subnet):
|
||||||
|
if (subnet['ip_version'] == 6 and subnet['ipv6_ra_mode'] is None and
|
||||||
|
subnet['ipv6_address_mode'] is not None):
|
||||||
|
msg = (_('IPv6 subnet %s configured to receive RAs from an '
|
||||||
|
'external router cannot be added to Neutron Router.') %
|
||||||
|
subnet['id'])
|
||||||
|
raise n_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _is_dns_integration_supported(self):
|
def _is_dns_integration_supported(self):
|
||||||
if self._dns_integration is None:
|
if self._dns_integration is None:
|
||||||
|
@ -703,6 +712,13 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||||
if not port['fixed_ips']:
|
if not port['fixed_ips']:
|
||||||
msg = _('Router port must have at least one fixed IP')
|
msg = _('Router port must have at least one fixed IP')
|
||||||
raise n_exc.BadRequest(resource='router', msg=msg)
|
raise n_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
|
||||||
|
fixed_ips = [ip for ip in port['fixed_ips']]
|
||||||
|
for fixed_ip in fixed_ips:
|
||||||
|
subnet = self._core_plugin.get_subnet(
|
||||||
|
context, fixed_ip['subnet_id'])
|
||||||
|
self._validate_subnet_address_mode(subnet)
|
||||||
|
|
||||||
return port
|
return port
|
||||||
|
|
||||||
def _validate_port_in_range_or_admin(self, context, subnets, port):
|
def _validate_port_in_range_or_admin(self, context, subnets, port):
|
||||||
|
@ -827,12 +843,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
||||||
msg = (_('Cannot add interface to router because subnet %s is not '
|
msg = (_('Cannot add interface to router because subnet %s is not '
|
||||||
'owned by project making the request') % subnet_id)
|
'owned by project making the request') % subnet_id)
|
||||||
raise n_exc.BadRequest(resource='router', msg=msg)
|
raise n_exc.BadRequest(resource='router', msg=msg)
|
||||||
if (subnet['ip_version'] == 6 and subnet['ipv6_ra_mode'] is None and
|
self._validate_subnet_address_mode(subnet)
|
||||||
subnet['ipv6_address_mode'] is not None):
|
|
||||||
msg = (_('IPv6 subnet %s configured to receive RAs from an '
|
|
||||||
'external router cannot be added to Neutron Router.') %
|
|
||||||
subnet['id'])
|
|
||||||
raise n_exc.BadRequest(resource='router', msg=msg)
|
|
||||||
self._check_for_dup_router_subnets(context, router,
|
self._check_for_dup_router_subnets(context, router,
|
||||||
subnet['network_id'], [subnet])
|
subnet['network_id'], [subnet])
|
||||||
fixed_ip = {'ip_address': subnet['gateway_ip'],
|
fixed_ip = {'ip_address': subnet['gateway_ip'],
|
||||||
|
|
|
@ -1418,6 +1418,33 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
|
||||||
None,
|
None,
|
||||||
p['port']['id'])
|
p['port']['id'])
|
||||||
|
|
||||||
|
def test_update_router_interface_port_ipv6_subnet_ext_ra(self):
|
||||||
|
use_cases = [{'msg': 'IPv6 Subnet Modes (none, slaac)',
|
||||||
|
'ra_mode': None,
|
||||||
|
'address_mode': lib_constants.IPV6_SLAAC},
|
||||||
|
{'msg': 'IPv6 Subnet Modes (none, dhcpv6-stateful)',
|
||||||
|
'ra_mode': None,
|
||||||
|
'address_mode': lib_constants.DHCPV6_STATEFUL},
|
||||||
|
{'msg': 'IPv6 Subnet Modes (none, dhcpv6-stateless)',
|
||||||
|
'ra_mode': None,
|
||||||
|
'address_mode': lib_constants.DHCPV6_STATELESS}]
|
||||||
|
for uc in use_cases:
|
||||||
|
with self.network() as network, self.router() as router:
|
||||||
|
with self.subnet(
|
||||||
|
network=network, cidr='fd00::/64',
|
||||||
|
ip_version=lib_constants.IP_VERSION_6,
|
||||||
|
ipv6_ra_mode=uc['ra_mode'],
|
||||||
|
ipv6_address_mode=uc['address_mode']) as subnet:
|
||||||
|
fixed_ips = [{'subnet_id': subnet['subnet']['id']}]
|
||||||
|
with self.port(subnet=subnet, fixed_ips=fixed_ips) as port:
|
||||||
|
self._router_interface_action(
|
||||||
|
'add',
|
||||||
|
router['router']['id'],
|
||||||
|
None,
|
||||||
|
port['port']['id'],
|
||||||
|
expected_code=exc.HTTPBadRequest.code,
|
||||||
|
msg=uc['msg'])
|
||||||
|
|
||||||
def _assert_body_port_id_and_update_port(self, body, mock_update_port,
|
def _assert_body_port_id_and_update_port(self, body, mock_update_port,
|
||||||
port_id, device_id):
|
port_id, device_id):
|
||||||
self.assertNotIn('port_id', body)
|
self.assertNotIn('port_id', body)
|
||||||
|
|
Loading…
Reference in New Issue