summary refs log tree commit diff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/devices/nm-device-bridge.c12
-rw-r--r--src/core/devices/nm-device.c8
-rw-r--r--src/core/devices/nm-device.h3
-rw-r--r--src/core/devices/ovs/nm-ovsdb.c6
-rw-r--r--src/core/dhcp/nm-dhcp-options.c8
-rw-r--r--src/core/nm-active-connection.c62
-rw-r--r--src/core/nm-active-connection.h1
-rw-r--r--src/core/nm-manager.c24
-rw-r--r--src/core/platform/tests/test-common.c6
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c7
-rw-r--r--src/core/supplicant/nm-supplicant-settings-verify.c33
11 files changed, 136 insertions, 34 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 2405beea..82314f13 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -299,13 +299,11 @@ typedef struct {
 } Option;
 
 #define OPTION(_name, _sysname, ...) \
-    {                                \
-        .name    = ""_name           \
-                   "",               \
-        .sysname = ""_sysname        \
-                   "",               \
-        __VA_ARGS__                  \
-    }
+    {.name    = ""_name              \
+                "",                  \
+     .sysname = ""_sysname           \
+                "",                  \
+     __VA_ARGS__}
 
 #define OPTION_TYPE_INT(min, max, def) .nm_min = (min), .nm_max = (max), .nm_default = (def)
 
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index b96adefb..f3441508 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -17205,6 +17205,14 @@ nm_device_get_state(NMDevice *self)
     return NM_DEVICE_GET_PRIVATE(self)->state;
 }
 
+NMDeviceStateReason
+nm_device_get_state_reason(NMDevice *self)
+{
+    g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_STATE_REASON_NONE);
+
+    return NM_DEVICE_GET_PRIVATE(self)->state_reason;
+}
+
 /*****************************************************************************/
 
 /**
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index ffe6b1af..ba45497c 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -561,7 +561,8 @@ int      nm_device_spec_match_list_full(NMDevice *self, const GSList *specs, int
 gboolean nm_device_is_activating(NMDevice *dev);
 gboolean nm_device_autoconnect_allowed(NMDevice *self);
 
-NMDeviceState nm_device_get_state(NMDevice *device);
+NMDeviceState       nm_device_get_state(NMDevice *device);
+NMDeviceStateReason nm_device_get_state_reason(NMDevice *device);
 
 gboolean nm_device_get_enabled(NMDevice *device);
 
diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c
index 68366f73..8e32cff5 100644
--- a/src/core/devices/ovs/nm-ovsdb.c
+++ b/src/core/devices/ovs/nm-ovsdb.c
@@ -461,7 +461,7 @@ ovsdb_call_method(NMOvsdb                  *self,
                    "new: add-interface bridge=%s port=%s interface=%s",
                    nm_connection_get_interface_name(call->payload.add_interface.bridge),
                    nm_connection_get_interface_name(call->payload.add_interface.port),
-                   nm_connection_get_interface_name(call->payload.add_interface.interface));
+                   nm_device_get_iface(call->payload.add_interface.interface_device));
         break;
     case OVSDB_DEL_INTERFACE:
         call->payload.del_interface.ifname = g_strdup(payload->del_interface.ifname);
@@ -945,7 +945,7 @@ _insert_interface(json_t       *params,
 
     row = json_pack("{s:s, s:s, s:o, s:o, s:o}",
                     "name",
-                    nm_connection_get_interface_name(interface),
+                    nm_device_get_iface(interface_device),
                     "type",
                     type ?: "",
                     "options",
@@ -1196,7 +1196,7 @@ _add_interface(NMOvsdb      *self,
 
     bridge_name        = nm_connection_get_interface_name(bridge);
     port_name          = nm_connection_get_interface_name(port);
-    interface_name     = nm_connection_get_interface_name(interface);
+    interface_name     = nm_device_get_iface(interface_device);
     interface_is_local = nm_streq0(bridge_name, interface_name);
 
     /* Determine cloned MAC addresses */
diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c
index 7c47c82e..f89237c5 100644
--- a/src/core/dhcp/nm-dhcp-options.c
+++ b/src/core/dhcp/nm-dhcp-options.c
@@ -11,9 +11,11 @@
 
 /*****************************************************************************/
 
-#define REQ(_num, _name, _include)                                                         \
-    {                                                                                      \
-        .name = NM_DHCP_OPTION_REQPREFIX ""_name, .option_num = _num, .include = _include, \
+#define REQ(_num, _name, _include)                      \
+    {                                                   \
+        .name       = NM_DHCP_OPTION_REQPREFIX ""_name, \
+        .option_num = _num,                             \
+        .include    = _include,                         \
     }
 
 const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = {
diff --git a/src/core/nm-active-connection.c b/src/core/nm-active-connection.c
index b08d26c2..7d89251c 100644
--- a/src/core/nm-active-connection.c
+++ b/src/core/nm-active-connection.c
@@ -50,6 +50,7 @@ typedef struct _NMActiveConnectionPrivate {
 
     NMAuthSubject      *subject;
     NMActiveConnection *controller;
+    NMDevice           *controller_dev;
 
     NMActiveConnection *parent;
 
@@ -826,6 +827,31 @@ master_state_cb(NMActiveConnection *master, GParamSpec *pspec, gpointer user_dat
     }
 }
 
+static void
+controller_dev_state_cb(NMDevice           *controller_dev,
+                        NMDeviceState       new_state,
+                        NMDeviceState       old_state,
+                        NMDeviceStateReason reason,
+                        gpointer            user_data)
+{
+    NMActiveConnection        *self = NM_ACTIVE_CONNECTION(user_data);
+    NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self);
+    NMActRequest              *controller_act_request;
+    NMActiveConnection        *controller_ac;
+
+    if (new_state >= NM_DEVICE_STATE_PREPARE && new_state <= NM_DEVICE_STATE_ACTIVATED) {
+        controller_act_request = nm_device_get_act_request(controller_dev);
+        if (controller_act_request) {
+            controller_ac = NM_ACTIVE_CONNECTION(controller_act_request);
+            g_signal_handlers_disconnect_by_func(controller_dev,
+                                                 G_CALLBACK(controller_dev_state_cb),
+                                                 self);
+            g_clear_object(&priv->controller_dev);
+            nm_active_connection_set_controller(self, controller_ac);
+        }
+    }
+}
+
 /**
  * nm_active_connection_set_controller:
  * @self: the #NMActiveConnection
@@ -867,6 +893,36 @@ nm_active_connection_set_controller(NMActiveConnection *self, NMActiveConnection
     check_controller_ready(self);
 }
 
+void
+nm_active_connection_set_controller_dev(NMActiveConnection *self, NMDevice *controller_dev)
+{
+    NMActiveConnectionPrivate *priv;
+
+    g_return_if_fail(NM_IS_ACTIVE_CONNECTION(self));
+    g_return_if_fail(NM_IS_DEVICE(controller_dev));
+
+    priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self);
+
+    /* Controller device is write-once, and must be set before exporting the object */
+    g_return_if_fail(priv->controller_dev == NULL);
+    g_return_if_fail(!nm_dbus_object_is_exported(NM_DBUS_OBJECT(self)));
+    if (priv->device) {
+        g_return_if_fail(priv->device != controller_dev);
+    }
+
+    _LOGD("set controller device %p, %s(%s), state %s",
+          controller_dev,
+          nm_device_get_iface(controller_dev),
+          nm_device_get_type_desc(controller_dev),
+          nm_device_state_to_string(nm_device_get_state(controller_dev)));
+
+    priv->controller_dev = g_object_ref(controller_dev);
+    g_signal_connect(priv->controller_dev,
+                     NM_DEVICE_STATE_CHANGED,
+                     G_CALLBACK(controller_dev_state_cb),
+                     self);
+}
+
 NMActivationType
 nm_active_connection_get_activation_type(NMActiveConnection *self)
 {
@@ -1533,7 +1589,13 @@ dispose(GObject *object)
     if (priv->controller) {
         g_signal_handlers_disconnect_by_func(priv->controller, G_CALLBACK(master_state_cb), self);
     }
+    if (priv->controller_dev) {
+        g_signal_handlers_disconnect_by_func(priv->controller_dev,
+                                             G_CALLBACK(controller_dev_state_cb),
+                                             self);
+    }
     g_clear_object(&priv->controller);
+    g_clear_object(&priv->controller_dev);
 
     if (priv->parent)
         unwatch_parent(self, TRUE);
diff --git a/src/core/nm-active-connection.h b/src/core/nm-active-connection.h
index 12cb311c..ba328302 100644
--- a/src/core/nm-active-connection.h
+++ b/src/core/nm-active-connection.h
@@ -175,6 +175,7 @@ NMActiveConnection *nm_active_connection_get_controller(NMActiveConnection *self
 gboolean nm_active_connection_get_controller_ready(NMActiveConnection *self);
 
 void nm_active_connection_set_controller(NMActiveConnection *self, NMActiveConnection *controller);
+void nm_active_connection_set_controller_dev(NMActiveConnection *self, NMDevice *controller_dev);
 
 void nm_active_connection_set_parent(NMActiveConnection *self, NMActiveConnection *parent);
 
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index b2a827e3..ddbd2021 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -5943,7 +5943,20 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
                                              NM_DEVICE_STATE_REASON_USER_REQUESTED);
         }
 
-        nm_active_connection_set_controller(active, master_ac);
+        /* If controller NMActiveConnection is deactivating, we should wait on
+         * controller's NMDevice to have new NMActiveConnection after
+         * controller device state change to between NM_DEVICE_STATE_PREPARE and
+         * NM_DEVICE_STATE_ACTIVATED.
+         */
+        if ((nm_active_connection_get_state(master_ac) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING)
+            && master_device
+            && (nm_device_get_state_reason(master_device)
+                == NM_DEVICE_STATE_REASON_NEW_ACTIVATION)) {
+            nm_active_connection_set_controller_dev(active, master_device);
+        } else {
+            nm_active_connection_set_controller(active, master_ac);
+        }
+
         _LOGD(LOGD_CORE,
               "Activation of '%s' depends on active connection %p %s",
               nm_settings_connection_get_id(sett_conn),
@@ -7947,6 +7960,7 @@ nm_manager_write_device_state_all(NMManager *self)
     NMManagerPrivate              *priv               = NM_MANAGER_GET_PRIVATE(self);
     gs_unref_hashtable GHashTable *preserve_ifindexes = NULL;
     NMDevice                      *device;
+    NMActiveConnection            *ac;
 
     preserve_ifindexes = g_hash_table_new(nm_direct_hash, NULL);
 
@@ -7958,6 +7972,14 @@ nm_manager_write_device_state_all(NMManager *self)
         }
     }
 
+    /* Save to disk the timestamps of active connections as if we were bringing them down.
+     * Otherwise they will be wrong on next start and affect the activation order.
+     */
+    c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
+        NMSettingsConnection *sett = nm_active_connection_get_settings_connection(ac);
+        nm_settings_connection_update_timestamp(sett, (guint64) time(NULL));
+    }
+
     nm_config_device_state_prune_stale(preserve_ifindexes, NULL);
 }
 
diff --git a/src/core/platform/tests/test-common.c b/src/core/platform/tests/test-common.c
index fde7dc0d..99b8bc45 100644
--- a/src/core/platform/tests/test-common.c
+++ b/src/core/platform/tests/test-common.c
@@ -59,10 +59,8 @@ typedef struct {
 
 } IPTunnelModInfo;
 
-#define INF(_module_name, _iftype, _ifname, ...)                                           \
-    {                                                                                      \
-        .module_name = ""_module_name, .iftype = _iftype, .ifname = ""_ifname, __VA_ARGS__ \
-    }
+#define INF(_module_name, _iftype, _ifname, ...) \
+    {.module_name = ""_module_name, .iftype = _iftype, .ifname = ""_ifname, __VA_ARGS__}
 
 static const IPTunnelModInfo ip_tunnel_mod_infos[] = {
     INF("ip_gre", NM_LINK_TYPE_GRE, "gre0"),
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index 277d0d5f..50484405 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -700,9 +700,10 @@ nms_ifcfg_rh_utils_is_numbered_tag_impl(const char *key,
 
 /*****************************************************************************/
 
-#define _KEY_TYPE(key, flags)                                                            \
-    {                                                                                    \
-        .key_name = "" key "", .key_flags = ((NMS_IFCFG_KEY_TYPE_WELL_KNOWN) | (flags)), \
+#define _KEY_TYPE(key, flags)                                     \
+    {                                                             \
+        .key_name  = "" key "",                                   \
+        .key_flags = ((NMS_IFCFG_KEY_TYPE_WELL_KNOWN) | (flags)), \
     }
 
 const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
diff --git a/src/core/supplicant/nm-supplicant-settings-verify.c b/src/core/supplicant/nm-supplicant-settings-verify.c
index c7aaf47d..76328541 100644
--- a/src/core/supplicant/nm-supplicant-settings-verify.c
+++ b/src/core/supplicant/nm-supplicant-settings-verify.c
@@ -20,21 +20,30 @@ struct Opt {
 
 typedef gboolean (*validate_func)(const struct Opt *, const char *, const guint32);
 
-#define OPT_INT(_key, _int_low, _int_high)                                                      \
-    {                                                                                           \
-        .key = _key, .type = NM_SUPPL_OPT_TYPE_INT, .int_high = _int_high, .int_low = _int_low, \
+#define OPT_INT(_key, _int_low, _int_high) \
+    {                                      \
+        .key      = _key,                  \
+        .type     = NM_SUPPL_OPT_TYPE_INT, \
+        .int_high = _int_high,             \
+        .int_low  = _int_low,              \
     }
-#define OPT_BYTES(_key, _int_high)                                           \
-    {                                                                        \
-        .key = _key, .type = NM_SUPPL_OPT_TYPE_BYTES, .int_high = _int_high, \
+#define OPT_BYTES(_key, _int_high)           \
+    {                                        \
+        .key      = _key,                    \
+        .type     = NM_SUPPL_OPT_TYPE_BYTES, \
+        .int_high = _int_high,               \
     }
-#define OPT_UTF8(_key, _int_high)                                           \
-    {                                                                       \
-        .key = _key, .type = NM_SUPPL_OPT_TYPE_UTF8, .int_high = _int_high, \
+#define OPT_UTF8(_key, _int_high)           \
+    {                                       \
+        .key      = _key,                   \
+        .type     = NM_SUPPL_OPT_TYPE_UTF8, \
+        .int_high = _int_high,              \
     }
-#define OPT_KEYWORD(_key, _str_allowed)                                              \
-    {                                                                                \
-        .key = _key, .type = NM_SUPPL_OPT_TYPE_KEYWORD, .str_allowed = _str_allowed, \
+#define OPT_KEYWORD(_key, _str_allowed)           \
+    {                                             \
+        .key         = _key,                      \
+        .type        = NM_SUPPL_OPT_TYPE_KEYWORD, \
+        .str_allowed = _str_allowed,              \
     }
 
 static const struct Opt opt_table[] = {