summary refs log tree commit diff
path: root/src/core/nm-active-connection.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2024-06-24 12:22:41 +0200
committerMichael Biebl <biebl@debian.org>2024-06-24 12:22:41 +0200
commit8e2fde558a5af5c3b03a5112dbd8f9085c5a8369 (patch)
tree4da74f7af9031f00703228c00dc36c755b95f3ae /src/core/nm-active-connection.c
parentbaef747c9365b6044db3c2dfbb859652bdde1d76 (diff)
New upstream version 1.48.2 upstream/1.48.2
Diffstat (limited to 'src/core/nm-active-connection.c')
-rw-r--r--src/core/nm-active-connection.c62
1 files changed, 62 insertions, 0 deletions
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);