Merge "Cleanup stale DHCP ports not bound to host"

This commit is contained in:
Zuul 2026-01-09 16:10:54 +00:00 committed by Gerrit Code Review
commit 944f3a9326
3 changed files with 36 additions and 2 deletions

View file

@ -26,6 +26,7 @@ import time
import netaddr
from neutron_lib.api.definitions import extra_dhcp_opt as edo_ext
from neutron_lib.api.definitions import portbindings
from neutron_lib import constants
from neutron_lib import exceptions
from neutron_lib.utils import file as file_utils
@ -1778,6 +1779,22 @@ class DeviceManager:
for port in network.ports}
hw_ports = {d.name for d in ns_ip.get_devices()}
for port in network.ports:
dev_name = self.driver.get_device_name(port)
if dev_name not in hw_ports:
continue
host_id = port.get(portbindings.HOST_ID)
if host_id and host_id != self.conf.host:
LOG.warning(f"Found stale port {port.id} for network "
f"{network.id} bound to {host_id} that is "
f"not us {self.conf.host}, deleting")
try:
self.unplug(dev_name, network)
except Exception:
LOG.exception("Exception during stale dhcp bound "
"device cleanup")
for dev_name in hw_ports - db_ports:
if dev_name != skip_dev_name:
LOG.warning("Found stale device %s, deleting", dev_name)

View file

@ -54,11 +54,18 @@ class TestDhcp(functional_base.BaseSudoTestCase):
'fixed_ips': [tests_base.AttributeDict(
{'subnet_id': 'subnet_foo_id4', 'ip_address': '10.0.0.4'})]
})
wrong_port = tests_base.AttributeDict({
'id': 'foo_id5',
'binding:host_id': 'wrong',
'mac_address': '10:22:33:44:55:71',
'fixed_ips': [tests_base.AttributeDict(
{'subnet_id': 'subnet_foo_id4', 'ip_address': '10.0.0.7'})]
})
network = {
'id': 'foo_id',
'project_id': 'foo_project',
'namespace': 'qdhcp-foo_id',
'ports': [dhcp_port4],
'ports': [dhcp_port4, wrong_port],
'subnets': [tests_base.AttributeDict({'id': 'subnet_foo_id',
'enable_dhcp': True,
'ipv6_address_mode': None,
@ -91,11 +98,16 @@ class TestDhcp(functional_base.BaseSudoTestCase):
"tapfoo_id4",
"10:22:33:44:55:70",
namespace="qdhcp-foo_id")
dev_mgr.driver.plug("foo_id",
"foo_id5",
"tapfoo_id5",
"10:22:33:44:55:71",
namespace="qdhcp-foo_id")
ipw = ip_lib.IPWrapper(namespace="qdhcp-foo_id")
devices = ipw.get_devices()
self.addCleanup(ipw.netns.delete, 'qdhcp-foo_id')
self.assertEqual(sorted(["tapfoo_id2", "tapfoo_id3",
"tapfoo_id4"]),
"tapfoo_id4", "tapfoo_id5"]),
sorted(map(str, devices)))
# setting up dhcp for the network
dev_mgr.setup(tests_base.AttributeDict(network))

View file

@ -0,0 +1,5 @@
---
fixes:
- |
Partially fixed `bug #2130885 <https://bugs.launchpad.net/neutron/+bug/2130885>`__ where
a DHCP port for neutron-dhcp-agent bound on the wrong host was not cleaned up correctly.