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.
This commit is contained in:
Beniamino Galvani
2020-12-16 11:36:01 +01:00
parent c288a338f9
commit 8e55efeb9d

View File

@@ -140,24 +140,52 @@ ovsdb_device_removed(NMOvsdb * ovsdb,
NMDeviceFactory *self) NMDeviceFactory *self)
{ {
const NMDeviceType device_type = device_type_i; const NMDeviceType device_type = device_type_i;
NMDevice * device; NMDevice * device = NULL;
NMDeviceState device_state; NMDeviceState device_state;
gboolean is_system_interface = FALSE;
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE
&& !NM_IN_STRSET(subtype, "internal", "patch")) && !NM_IN_STRSET(subtype, "internal", "patch", "system"))
return; 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) if (!device)
return; return;
device_state = nm_device_get_state(device); device_state = nm_device_get_state(device);
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && device_state > NM_DEVICE_STATE_DISCONNECTED if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && device_state > NM_DEVICE_STATE_DISCONNECTED
&& device_state < NM_DEVICE_STATE_DEACTIVATING) { && device_state < NM_DEVICE_STATE_DEACTIVATING) {
nm_device_state_changed(device, nm_device_state_changed(device,
NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); 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); nm_device_unrealize(device, TRUE, NULL);
} }
} }