From 8e55efeb9dffa3a72a0101c14eb1849146edd08c Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 16 Dec 2020 11:36:01 +0100 Subject: [PATCH] ovs: fail OVS system interfaces when the db entry gets removed If an OVS system interface that is active in NM gets removed externally from the ovsdb, NM doesn't notice it and keeps the connection active. Let the OVS factory also handle the removal message for system interfaces. In that case, we need to match the removed interface name to the actual device, which can be of any kind. --- src/devices/ovs/nm-ovs-factory.c | 36 ++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c index e0435b1d57..1074b34640 100644 --- a/src/devices/ovs/nm-ovs-factory.c +++ b/src/devices/ovs/nm-ovs-factory.c @@ -140,24 +140,52 @@ ovsdb_device_removed(NMOvsdb * ovsdb, NMDeviceFactory *self) { const NMDeviceType device_type = device_type_i; - NMDevice * device; + NMDevice * device = NULL; NMDeviceState device_state; + gboolean is_system_interface = FALSE; if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE - && !NM_IN_STRSET(subtype, "internal", "patch")) + && !NM_IN_STRSET(subtype, "internal", "patch", "system")) return; - device = nm_manager_get_device(NM_MANAGER_GET, name, device_type); + if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && nm_streq0(subtype, "system")) { + NMDevice * d; + const CList * list; + NMSettingOvsInterface *s_ovs_int; + + /* The device associated to an OVS system interface can be of + * any kind. Find an interface with the same name and which has + * the OVS-interface setting. */ + is_system_interface = TRUE; + nm_manager_for_each_device (NM_MANAGER_GET, d, list) { + if (!nm_streq0(nm_device_get_iface(d), name)) + continue; + s_ovs_int = nm_device_get_applied_setting(d, NM_TYPE_SETTING_OVS_INTERFACE); + if (!s_ovs_int) + continue; + if (!nm_streq0(nm_setting_ovs_interface_get_interface_type(s_ovs_int), "system")) + continue; + device = d; + } + } else { + device = nm_manager_get_device(NM_MANAGER_GET, name, device_type); + } + if (!device) return; device_state = nm_device_get_state(device); + if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && device_state > NM_DEVICE_STATE_DISCONNECTED && device_state < NM_DEVICE_STATE_DEACTIVATING) { nm_device_state_changed(device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); - } else if (device_state == NM_DEVICE_STATE_UNMANAGED) { + return; + } + + /* OVS system interfaces still exist even without the ovsdb entry */ + if (!is_system_interface && device_state == NM_DEVICE_STATE_UNMANAGED) { nm_device_unrealize(device, TRUE, NULL); } }