summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2021-01-27 16:12:47 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2021-01-27 16:12:47 +0100
commit0a05e39e0b5a5a7a1489615c3b4310108d91cb0c (patch)
treeed0b9258879989f07406774c5ebe49d843873737
parent5f9d4e23a3097e365812bc2de473a57d16b71247 (diff)
parente2b4417570391596e6c2642310aa7e39f2ffca66 (diff)
downloadNetworkManager-0a05e39e0b5a5a7a1489615c3b4310108d91cb0c.tar.gz
ovs: merge branch 'bg/ovs-cleanup-pt2'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/734
-rw-r--r--src/devices/ovs/nm-device-ovs-interface.c51
-rw-r--r--src/devices/ovs/nm-ovs-factory.c63
-rw-r--r--src/devices/ovs/nm-ovsdb.c172
-rw-r--r--src/devices/ovs/nm-ovsdb.h3
-rw-r--r--src/nm-manager.c12
-rw-r--r--src/nm-manager.h2
-rw-r--r--src/nm-policy.c24
-rw-r--r--src/nm-policy.h2
8 files changed, 281 insertions, 48 deletions
diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c
index e73ddebb52..b9d3d509e9 100644
--- a/src/devices/ovs/nm-device-ovs-interface.c
+++ b/src/devices/ovs/nm-device-ovs-interface.c
@@ -22,7 +22,8 @@
/*****************************************************************************/
typedef struct {
- bool waiting_for_interface : 1;
+ NMOvsdb *ovsdb;
+ bool waiting_for_interface : 1;
} NMDeviceOvsInterfacePrivate;
struct _NMDeviceOvsInterface {
@@ -70,7 +71,10 @@ get_generic_capabilities(NMDevice *device)
static gboolean
is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
- return TRUE;
+ NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device);
+ NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
+
+ return nm_ovsdb_is_ready(priv->ovsdb);
}
static gboolean
@@ -152,6 +156,9 @@ set_platform_mtu_cb(GError *error, gpointer user_data)
static gboolean
set_platform_mtu(NMDevice *device, guint32 mtu)
{
+ NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device);
+ NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
+
/*
* If the MTU is not set in ovsdb, Open vSwitch will change
* the MTU of an internal interface to match the minimum of
@@ -162,7 +169,7 @@ set_platform_mtu(NMDevice *device, guint32 mtu)
* it can be stopped during shutdown.
*/
if (_is_internal_interface(device)) {
- nm_ovsdb_set_interface_mtu(nm_ovsdb_get(),
+ nm_ovsdb_set_interface_mtu(priv->ovsdb,
nm_device_get_ip_iface(device),
mtu,
set_platform_mtu_cb,
@@ -361,8 +368,41 @@ can_update_from_platform_link(NMDevice *device, const NMPlatformLink *plink)
/*****************************************************************************/
static void
+ovsdb_ready(NMOvsdb *ovsdb, NMDeviceOvsInterface *self)
+{
+ NMDevice *device = NM_DEVICE(self);
+
+ nm_device_queue_recheck_available(device,
+ NM_DEVICE_STATE_REASON_NONE,
+ NM_DEVICE_STATE_REASON_NONE);
+ nm_device_recheck_available_connections(device);
+ nm_device_emit_recheck_auto_activate(device);
+}
+
+static void
nm_device_ovs_interface_init(NMDeviceOvsInterface *self)
-{}
+{
+ NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
+
+ priv->ovsdb = g_object_ref(nm_ovsdb_get());
+
+ if (!nm_ovsdb_is_ready(priv->ovsdb))
+ g_signal_connect(priv->ovsdb, NM_OVSDB_READY, G_CALLBACK(ovsdb_ready), self);
+}
+
+static void
+dispose(GObject *object)
+{
+ NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(object);
+ NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
+
+ if (priv->ovsdb) {
+ g_signal_handlers_disconnect_by_func(priv->ovsdb, G_CALLBACK(ovsdb_ready), self);
+ g_clear_object(&priv->ovsdb);
+ }
+
+ G_OBJECT_CLASS(nm_device_ovs_interface_parent_class)->dispose(object);
+}
static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
@@ -374,9 +414,12 @@ static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = {
static void
nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass)
{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDeviceClass * device_class = NM_DEVICE_CLASS(klass);
+ object_class->dispose = dispose;
+
dbus_object_class->interface_infos =
NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_interface);
diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c
index 9eb79d3b3f..10b6d7f419 100644
--- a/src/devices/ovs/nm-ovs-factory.c
+++ b/src/devices/ovs/nm-ovs-factory.c
@@ -106,11 +106,24 @@ new_device_from_type(const char *name, NMDeviceType device_type)
}
static void
-ovsdb_device_added(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self)
+ovsdb_device_added(NMOvsdb * ovsdb,
+ const char * name,
+ guint device_type_i,
+ const char * subtype,
+ NMDeviceFactory *self)
{
const NMDeviceType device_type = device_type_i;
NMDevice * device;
+ if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE
+ && !NM_IN_STRSET(subtype, "internal", "patch")) {
+ /* system interfaces refer to kernel devices and
+ * don't need to be created by this factory. Ignore
+ * anything that is not an internal or patch
+ * interface. */
+ return;
+ }
+
device = new_device_from_type(name, device_type);
if (!device)
return;
@@ -120,23 +133,59 @@ ovsdb_device_added(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDevi
}
static void
-ovsdb_device_removed(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self)
+ovsdb_device_removed(NMOvsdb * ovsdb,
+ const char * name,
+ guint device_type_i,
+ const char * subtype,
+ 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", "system"))
+ return;
+
+ 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);
+ }
- 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
+
+ if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && nm_device_get_act_request(device)
&& 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) {
+ NM_DEVICE_STATE_REASON_REMOVED);
+ 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);
}
}
diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c
index cd14920784..de54a2e6c9 100644
--- a/src/devices/ovs/nm-ovsdb.c
+++ b/src/devices/ovs/nm-ovsdb.c
@@ -15,6 +15,7 @@
#include "nm-core-utils.h"
#include "nm-core-internal.h"
#include "devices/nm-device.h"
+#include "nm-manager.h"
#include "nm-setting-ovs-external-ids.h"
/*****************************************************************************/
@@ -106,7 +107,13 @@ typedef struct {
/*****************************************************************************/
-enum { DEVICE_ADDED, DEVICE_REMOVED, INTERFACE_FAILED, LAST_SIGNAL };
+enum {
+ DEVICE_ADDED,
+ DEVICE_REMOVED,
+ INTERFACE_FAILED,
+ READY,
+ LAST_SIGNAL,
+};
static guint signals[LAST_SIGNAL] = {0};
@@ -127,6 +134,8 @@ typedef struct {
GHashTable *bridges; /* bridge uuid => OpenvswitchBridge */
char * db_uuid;
guint num_failures;
+ guint num_pending_deletions;
+ bool ready : 1;
} NMOvsdbPrivate;
struct _NMOvsdb {
@@ -316,26 +325,24 @@ _free_interface(OpenvswitchInterface *ovs_interface)
nm_g_slice_free(ovs_interface);
}
-static gboolean
-_openvswitch_interface_should_emit_signal(const OpenvswitchInterface *ovs_interface)
-{
- /* Currently, the factory only creates NMDevices for
- * internal interfaces. We ignore the rest. */
- return nm_streq0(ovs_interface->type, "internal");
-}
-
/*****************************************************************************/
static void
-_signal_emit_device_added(NMOvsdb *self, const char *name, NMDeviceType device_type)
+_signal_emit_device_added(NMOvsdb * self,
+ const char * name,
+ NMDeviceType device_type,
+ const char * device_subtype)
{
- g_signal_emit(self, signals[DEVICE_ADDED], 0, name, (guint) device_type);
+ g_signal_emit(self, signals[DEVICE_ADDED], 0, name, (guint) device_type, device_subtype);
}
static void
-_signal_emit_device_removed(NMOvsdb *self, const char *name, NMDeviceType device_type)
+_signal_emit_device_removed(NMOvsdb * self,
+ const char * name,
+ NMDeviceType device_type,
+ const char * device_subtype)
{
- g_signal_emit(self, signals[DEVICE_REMOVED], 0, name, (guint) device_type);
+ g_signal_emit(self, signals[DEVICE_REMOVED], 0, name, (guint) device_type, device_subtype);
}
static void
@@ -1630,11 +1637,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ",
ovs_interface->connection_uuid,
""));
- if (_openvswitch_interface_should_emit_signal(ovs_interface)) {
- _signal_emit_device_removed(self,
- ovs_interface->name,
- NM_DEVICE_TYPE_OVS_INTERFACE);
- }
+ _signal_emit_device_removed(self,
+ ovs_interface->name,
+ NM_DEVICE_TYPE_OVS_INTERFACE,
+ ovs_interface->type);
_free_interface(ovs_interface);
continue;
}
@@ -1645,11 +1651,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
&& (!nm_streq0(ovs_interface->name, name) || !nm_streq0(ovs_interface->type, type))) {
if (!g_hash_table_steal(priv->interfaces, ovs_interface))
nm_assert_not_reached();
- if (_openvswitch_interface_should_emit_signal(ovs_interface)) {
- _signal_emit_device_removed(self,
- ovs_interface->name,
- NM_DEVICE_TYPE_OVS_INTERFACE);
- }
+ _signal_emit_device_removed(self,
+ ovs_interface->name,
+ NM_DEVICE_TYPE_OVS_INTERFACE,
+ ovs_interface->type);
nm_clear_pointer(&ovs_interface, _free_interface);
}
@@ -1700,8 +1705,10 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_interface->connection_uuid,
""),
(strtmp = _external_ids_to_string(ovs_interface->external_ids)));
- if (_openvswitch_interface_should_emit_signal(ovs_interface))
- _signal_emit_device_added(self, ovs_interface->name, NM_DEVICE_TYPE_OVS_INTERFACE);
+ _signal_emit_device_added(self,
+ ovs_interface->name,
+ NM_DEVICE_TYPE_OVS_INTERFACE,
+ ovs_interface->type);
}
/* The error is a string. No error is indicated by an empty set,
@@ -1747,7 +1754,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ",
ovs_port->connection_uuid,
""));
- _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT);
+ _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
_free_port(ovs_port);
continue;
}
@@ -1757,7 +1764,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
if (ovs_port && !nm_streq0(ovs_port->name, name)) {
if (!g_hash_table_steal(priv->ports, ovs_port))
nm_assert_not_reached();
- _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT);
+ _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
nm_clear_pointer(&ovs_port, _free_port);
}
@@ -1811,7 +1818,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_port->connection_uuid,
""),
(strtmp = _external_ids_to_string(ovs_port->external_ids)));
- _signal_emit_device_added(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT);
+ _signal_emit_device_added(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
}
}
@@ -1852,7 +1859,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
", ",
ovs_bridge->connection_uuid,
""));
- _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE);
+ _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
_free_bridge(ovs_bridge);
continue;
}
@@ -1862,7 +1869,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
if (ovs_bridge && !nm_streq0(ovs_bridge->name, name)) {
if (!g_hash_table_steal(priv->bridges, ovs_bridge))
nm_assert_not_reached();
- _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE);
+ _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
nm_clear_pointer(&ovs_bridge, _free_bridge);
}
@@ -1916,7 +1923,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
ovs_bridge->connection_uuid,
""),
(strtmp = _external_ids_to_string(ovs_bridge->external_ids)));
- _signal_emit_device_added(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE);
+ _signal_emit_device_added(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
}
}
}
@@ -2221,6 +2228,9 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing)
_LOGD("disconnecting from ovsdb, retry %d", retry);
+ /* FIXME(shutdown): NMOvsdb should process the pending calls before
+ * shutting down, and cancel the remaining calls after the timeout. */
+
if (retry) {
if (!c_list_is_empty(&priv->calls_lst_head)) {
call = c_list_first_entry(&priv->calls_lst_head, OvsdbMethodCall, calls_lst);
@@ -2250,6 +2260,76 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing)
}
static void
+_check_ready(NMOvsdb *self)
+{
+ NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
+
+ nm_assert(!priv->ready);
+
+ if (priv->num_pending_deletions == 0) {
+ priv->ready = TRUE;
+ g_signal_emit(self, signals[READY], 0);
+ nm_manager_unblock_failed_ovs_interfaces(nm_manager_get());
+ }
+}
+
+static void
+_del_initial_iface_cb(GError *error, gpointer user_data)
+{
+ NMOvsdb * self;
+ gs_free char * ifname = NULL;
+ NMOvsdbPrivate *priv;
+
+ nm_utils_user_data_unpack(user_data, &self, &ifname);
+
+ if (nm_utils_error_is_cancelled_or_disposing(error))
+ return;
+
+ priv = NM_OVSDB_GET_PRIVATE(self);
+ nm_assert(priv->num_pending_deletions > 0);
+ priv->num_pending_deletions--;
+
+ _LOGD("delete initial interface '%s': %s %s%s%s, pending %u",
+ ifname,
+ error ? "error" : "success",
+ error ? "(" : "",
+ error ? error->message : "",
+ error ? ")" : "",
+ priv->num_pending_deletions);
+
+ _check_ready(self);
+}
+
+static void
+ovsdb_cleanup_initial_interfaces(NMOvsdb *self)
+{
+ NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self);
+ const OpenvswitchInterface *interface;
+ NMUtilsUserData * data;
+ GHashTableIter iter;
+
+ if (priv->ready || priv->num_pending_deletions != 0)
+ return;
+
+ /* Delete OVS interfaces added by NM. Bridges and ports and
+ * not considered because they are deleted automatically
+ * when no interface is present. */
+ g_hash_table_iter_init(&iter, self->_priv.interfaces);
+ while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &interface)) {
+ if (interface->connection_uuid) {
+ priv->num_pending_deletions++;
+ _LOGD("deleting initial interface '%s' (pending: %u)",
+ interface->name,
+ priv->num_pending_deletions);
+ data = nm_utils_user_data_pack(self, g_strdup(interface->name));
+ nm_ovsdb_del_interface(self, interface->name, _del_initial_iface_cb, data);
+ }
+ }
+
+ _check_ready(self);
+}
+
+static void
_monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_data)
{
if (error) {
@@ -2263,6 +2343,8 @@ _monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_
/* Treat the first response the same as the subsequent "update"
* messages we eventually get. */
ovsdb_got_update(self, result);
+
+ ovsdb_cleanup_initial_interfaces(self);
}
static void
@@ -2382,6 +2464,14 @@ ovsdb_call_new(NMOvsdbCallback callback, gpointer user_data)
return call;
}
+gboolean
+nm_ovsdb_is_ready(NMOvsdb *self)
+{
+ NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
+
+ return priv->ready;
+}
+
void
nm_ovsdb_add_interface(NMOvsdb * self,
NMConnection * bridge,
@@ -2525,9 +2615,10 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
NULL,
NULL,
G_TYPE_NONE,
- 2,
+ 3,
G_TYPE_STRING,
- G_TYPE_UINT);
+ G_TYPE_UINT,
+ G_TYPE_STRING);
signals[DEVICE_REMOVED] = g_signal_new(NM_OVSDB_DEVICE_REMOVED,
G_OBJECT_CLASS_TYPE(object_class),
@@ -2537,9 +2628,10 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
NULL,
NULL,
G_TYPE_NONE,
- 2,
+ 3,
G_TYPE_STRING,
- G_TYPE_UINT);
+ G_TYPE_UINT,
+ G_TYPE_STRING);
signals[INTERFACE_FAILED] = g_signal_new(NM_OVSDB_INTERFACE_FAILED,
G_OBJECT_CLASS_TYPE(object_class),
@@ -2553,4 +2645,14 @@ nm_ovsdb_class_init(NMOvsdbClass *klass)
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING);
+
+ signals[READY] = g_signal_new(NM_OVSDB_READY,
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
}
diff --git a/src/devices/ovs/nm-ovsdb.h b/src/devices/ovs/nm-ovsdb.h
index 533b23450a..d0b4d19d45 100644
--- a/src/devices/ovs/nm-ovsdb.h
+++ b/src/devices/ovs/nm-ovsdb.h
@@ -16,6 +16,7 @@
#define NM_OVSDB_DEVICE_ADDED "device-added"
#define NM_OVSDB_DEVICE_REMOVED "device-removed"
#define NM_OVSDB_INTERFACE_FAILED "interface-failed"
+#define NM_OVSDB_READY "ready"
typedef struct _NMOvsdb NMOvsdb;
typedef struct _NMOvsdbClass NMOvsdbClass;
@@ -55,4 +56,6 @@ void nm_ovsdb_set_external_ids(NMOvsdb * self,
struct _NMSettingOvsExternalIDs *s_exid_old,
struct _NMSettingOvsExternalIDs *s_exid_new);
+gboolean nm_ovsdb_is_ready(NMOvsdb *self);
+
#endif /* __NETWORKMANAGER_OVSDB_H__ */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 7f590f3826..550ac5e6ce 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -4927,11 +4927,11 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
if (master_device) {
g_prefix_error(error,
"Master device '%s' can't be activated: ",
- nm_device_get_ip_iface(device));
+ nm_device_get_ip_iface(master_device));
} else {
g_prefix_error(error,
"Master connection '%s' can't be activated: ",
- nm_settings_connection_get_id(sett_conn));
+ nm_settings_connection_get_id(master_connection));
}
return FALSE;
}
@@ -7582,6 +7582,14 @@ periodic_update_active_connection_timestamps(gpointer user_data)
return G_SOURCE_CONTINUE;
}
+void
+nm_manager_unblock_failed_ovs_interfaces(NMManager *self)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
+
+ nm_policy_unblock_failed_ovs_interfaces(priv->policy);
+}
+
/*****************************************************************************/
void
diff --git a/src/nm-manager.h b/src/nm-manager.h
index 0585857ea1..e3f71b8055 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -209,4 +209,6 @@ void nm_manager_device_auth_request(NMManager * self,
NMManagerDeviceAuthRequestFunc callback,
gpointer user_data);
+void nm_manager_unblock_failed_ovs_interfaces(NMManager *self);
+
#endif /* __NETWORKMANAGER_MANAGER_H__ */
diff --git a/src/nm-policy.c b/src/nm-policy.c
index e74531e92c..98ff704102 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1541,6 +1541,30 @@ hostname_changed(NMHostnameManager *hostname_manager, GParamSpec *pspec, gpointe
update_system_hostname(self, "hostname changed");
}
+void
+nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self)
+{
+ NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
+ NMSettingsConnection *const *connections = NULL;
+ guint i;
+
+ _LOGT(LOGD_DEVICE, "unblocking failed OVS interfaces");
+
+ connections = nm_settings_get_connections(priv->settings, NULL);
+ for (i = 0; connections[i]; i++) {
+ NMSettingsConnection *sett_conn = connections[i];
+ NMConnection * connection = nm_settings_connection_get_connection(sett_conn);
+
+ if (nm_connection_get_setting_ovs_interface(connection)) {
+ nm_settings_connection_autoconnect_retries_reset(sett_conn);
+ nm_settings_connection_autoconnect_blocked_reason_set(
+ sett_conn,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
+ FALSE);
+ }
+ }
+}
+
static gboolean
reset_autoconnect_all(
NMPolicy *self,
diff --git a/src/nm-policy.h b/src/nm-policy.h
index 26178931ea..fa216db3a8 100644
--- a/src/nm-policy.h
+++ b/src/nm-policy.h
@@ -32,6 +32,8 @@ NMActiveConnection *nm_policy_get_default_ip6_ac(NMPolicy *policy);
NMActiveConnection *nm_policy_get_activating_ip4_ac(NMPolicy *policy);
NMActiveConnection *nm_policy_get_activating_ip6_ac(NMPolicy *policy);
+void nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self);
+
/**
* NMPolicyHostnameMode
* @NM_POLICY_HOSTNAME_MODE_NONE: never update the transient hostname.