Forbid the subnet gateway IP deletion if a router interface is attached

When a router interface is created, the corresponding subnet gateway IP
is tested first [1]. If the subnet has no gateway IP, the router
interface cannot be created. This IP will be assigned to this port.

The Neutron API also prevents from modifying the subnet gateway IP
if assigned to a router interface [2]. However the API is not
preventing the subnet gateway IP deletion. This patch is adding
this check.

This patch is being tested in the neutron-tempest-plugin [3].

[1]de58c1b995/neutron/db/l3_db.py (L902-L904)
[2]de58c1b995/neutron/db/db_base_plugin_v2.py (L715)
[3]https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/904710

Closes-Bug: #2036423
Change-Id: I4c7b399a3a052749abdb88fb50be628ee91b63a0
This commit is contained in:
Rodolfo Alonso Hernandez 2024-01-14 10:20:12 +00:00
parent cd28691d3a
commit f9e40971e9
2 changed files with 28 additions and 15 deletions

View File

@ -688,32 +688,39 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
"supported if enable_dhcp is True.")
raise exc.InvalidInput(error_message=error_message)
if validators.is_attr_set(s.get('gateway_ip')):
self._validate_ip_version(ip_ver, s['gateway_ip'], 'gateway_ip')
if has_cidr:
is_gateway_not_valid = (
ipam.utils.check_gateway_invalid_in_subnet(
s['cidr'], s['gateway_ip']))
if is_gateway_not_valid:
error_message = _("Gateway is not valid on subnet")
raise exc.InvalidInput(error_message=error_message)
# Ensure the gateway IP is not assigned to any port
# skip this check in case of create (s parameter won't have id)
gateway_ip = s.get('gateway_ip', constants.ATTR_NOT_SPECIFIED)
if validators.is_attr_set(gateway_ip) or gateway_ip is None:
# Validate the gateway IP, if defined in the request.
if s['gateway_ip']:
self._validate_ip_version(ip_ver, gateway_ip, 'gateway_ip')
if has_cidr:
is_gateway_not_valid = (
ipam.utils.check_gateway_invalid_in_subnet(
s['cidr'], gateway_ip))
if is_gateway_not_valid:
error_message = _("Gateway is not valid on subnet")
raise exc.InvalidInput(error_message=error_message)
# Ensure the current subnet gateway IP is not assigned to any port.
# The subnet gateway IP cannot be modified or removed if in use
# (assigned to a router interface).
# Skip this check in case of create (s parameter won't have id).
# NOTE(salv-orlando): There is slight chance of a race, when
# a subnet-update and a router-interface-add operation are
# executed concurrently
s_gateway_ip = netaddr.IPAddress(s['gateway_ip'])
s_gateway_ip = (netaddr.IPAddress(gateway_ip) if gateway_ip else
None)
if (cur_subnet and
s_gateway_ip != cur_subnet['gateway_ip'] and
not ipv6_utils.is_ipv6_pd_enabled(s)):
gateway_ip = str(cur_subnet['gateway_ip'])
current_gateway_ip = str(cur_subnet['gateway_ip'])
alloc = port_obj.IPAllocation.get_alloc_routerports(
context, cur_subnet['id'], gateway_ip=gateway_ip,
context, cur_subnet['id'], gateway_ip=current_gateway_ip,
first=True)
if alloc and alloc.port_id:
raise exc.GatewayIpInUse(
ip_address=gateway_ip,
ip_address=current_gateway_ip,
port_id=alloc.port_id)
if validators.is_attr_set(s.get('dns_nameservers')):

View File

@ -0,0 +1,6 @@
---
fixes:
- |
[`bug 2036423 <https://bugs.launchpad.net/neutron/+bug/2036423>`_]
Now it is not possible to delete a subnet gateway IP if that subnet has a
router interface; the subnet gateway IP modification was already forbidden.