about summary refs log tree commit diff
path: root/src/core/nm-manager.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2025-02-12 13:46:50 +0100
committerMichael Biebl <biebl@debian.org>2025-02-12 13:46:50 +0100
commit8bdf070ff046f482f6eb5e2b15ebc216f5d1e3da (patch)
treef706478d189d54c6532e8863d4b0d5ff5575af60 /src/core/nm-manager.c
parent818258cf34b83fbc754633295e1052d4752d7b15 (diff)
New upstream version 1.51.90 upstream/1.51.90
Diffstat (limited to 'src/core/nm-manager.c')
-rw-r--r--src/core/nm-manager.c138
1 files changed, 87 insertions, 51 deletions
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index b96a9053..c9bcbd12 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -1638,7 +1638,7 @@ _devcon_lookup_data(NMManager            *self,
         return NULL;
 
     data  = g_slice_new(DevConData);
-    *data = (DevConData){
+    *data = (DevConData) {
         .device    = device,
         .sett_conn = sett_conn,
         .autoconnect =
@@ -2522,7 +2522,7 @@ return_ifname_fom_connection:
         g_set_error(error,
                     NM_MANAGER_ERROR,
                     NM_MANAGER_ERROR_FAILED,
-                    "failed to determine interface name: error determine name for %s",
+                    "failed to determine interface name for a %s",
                     nm_connection_get_connection_type(connection));
     }
     return iface;
@@ -3455,7 +3455,7 @@ get_existing_connection(NMManager *self, NMDevice *device, gboolean *out_generat
         if (connection) {
             NMConnection *con = nm_settings_connection_get_connection(connection_checked);
 
-            if (nm_utils_match_connection((NMConnection *[]){con, NULL},
+            if (nm_utils_match_connection((NMConnection *[]) {con, NULL},
                                           connection,
                                           TRUE,
                                           nm_device_has_carrier(device),
@@ -4536,7 +4536,7 @@ nm_manager_get_best_device_for_connection(NMManager            *self,
                                           NMSettingsConnection *sett_conn,
                                           NMConnection         *connection,
                                           gboolean              for_user_request,
-                                          GHashTable           *unavailable_devices,
+                                          GHashTable           *exclude_devices,
                                           GError              **error)
 {
     NMManagerPrivate       *priv = NM_MANAGER_GET_PRIVATE(self);
@@ -4619,7 +4619,7 @@ nm_manager_get_best_device_for_connection(NMManager            *self,
 
         ac_device = nm_active_connection_get_device(ac);
         if (ac_device
-            && ((unavailable_devices && g_hash_table_contains(unavailable_devices, ac_device))
+            && (nm_g_hash_table_contains(exclude_devices, ac_device)
                 || !nm_device_check_connection_available(ac_device, connection, flags, NULL, NULL)))
             ac_device = NULL;
 
@@ -4635,9 +4635,7 @@ nm_manager_get_best_device_for_connection(NMManager            *self,
                 NMDevice               *ac_device2 = nm_active_connection_get_device(ac2);
                 NMActiveConnectionState ac_state2;
 
-                if (!ac_device2
-                    || (unavailable_devices
-                        && g_hash_table_contains(unavailable_devices, ac_device2))
+                if (!ac_device2 || nm_g_hash_table_contains(exclude_devices, ac_device2)
                     || !nm_device_check_connection_available(ac_device2,
                                                              connection,
                                                              flags,
@@ -4698,7 +4696,13 @@ found_better:
         GError              *local = NULL;
         DeviceActivationPrio prio;
 
-        if (unavailable_devices && g_hash_table_contains(unavailable_devices, device))
+        if (nm_g_hash_table_contains(exclude_devices, device))
+            continue;
+
+        if (!nm_device_is_available(device,
+                                    for_user_request
+                                        ? NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST
+                                        : NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
             continue;
 
         /* determine the priority of this device. Currently, this priority is independent
@@ -5347,7 +5351,7 @@ find_ports(NMManager            *manager,
             }
 
             nm_assert(n_ports < n_all_connections);
-            ports[n_ports++] = (PortConnectionInfo){
+            ports[n_ports++] = (PortConnectionInfo) {
                 .connection = candidate,
                 .device     = port_device,
             };
@@ -6403,17 +6407,11 @@ nm_manager_activate_connection(NMManager             *self,
  * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there
  *   is only a partial activation.
  * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified)
- * @device_path: the object path of the device to be activated, or NULL
- * @out_device: on successful return, the #NMDevice to be activated with @connection
- *   The caller may pass in a device which shortcuts the lookup by path.
- *   In this case, the passed in device must have the matching @device_path
- *   already.
- * @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection
  * @error: location to store an error on failure
  *
- * Performs basic validation on an activation request, including ensuring that
- * the requestor is a valid Unix process, is not disallowed in @connection
- * permissions, and that a device exists that can activate @connection.
+ * Performs basic permission validation on an activation request: Ensures that
+ * the requestor is a valid Unix process and is not disallowed in @connection
+ * permissions.
  *
  * Returns: on success, the #NMAuthSubject representing the requestor, or
  *   %NULL on error
@@ -6423,13 +6421,8 @@ validate_activation_request(NMManager             *self,
                             GDBusMethodInvocation *context,
                             NMSettingsConnection  *sett_conn,
                             NMConnection          *connection,
-                            const char            *device_path,
-                            NMDevice             **out_device,
-                            gboolean              *out_is_vpn,
                             GError               **error)
 {
-    NMDevice                      *device  = NULL;
-    gboolean                       is_vpn  = FALSE;
     gs_unref_object NMAuthSubject *subject = NULL;
 
     nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn));
@@ -6437,8 +6430,6 @@ validate_activation_request(NMManager             *self,
     nm_assert(sett_conn || connection);
     nm_assert(!connection || !sett_conn
               || connection == nm_settings_connection_get_connection(sett_conn));
-    nm_assert(out_device);
-    nm_assert(out_is_vpn);
 
     if (!connection)
         connection = nm_settings_connection_get_connection(sett_conn);
@@ -6459,6 +6450,51 @@ validate_activation_request(NMManager             *self,
                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
                                              error))
         return NULL;
+    return g_steal_pointer(&subject);
+}
+
+/**
+ * find_device_for_activation:
+ * @self: the #NMManager
+ * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there
+ *   is only a partial activation.
+ * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified)
+ * @device_path: the object path of the device to be activated, or NULL
+ * @out_device: on successful return, the #NMDevice to be activated with @connection
+ *   The caller may pass in a device which shortcuts the lookup by path.
+ *   In this case, the passed in device must have the matching @device_path
+ *   already.
+ * @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection
+ * @error: location to store an error on failure
+ *
+ * Looks up a device that can activate @connection, or indicates the
+ * connection is a VPN connection that does not require a device.
+ *
+ * Returns: %TRUE if the device could be find or connection doesn't
+ *   need one, %FALSE otherwise
+ */
+static gboolean
+find_device_for_activation(NMManager            *self,
+                           NMSettingsConnection *sett_conn,
+                           NMConnection         *connection,
+                           const char           *device_path,
+                           NMDevice            **out_device,
+                           gboolean             *out_is_vpn,
+                           GError              **error)
+{
+    gboolean  is_vpn = FALSE;
+    NMDevice *device = NULL;
+
+    nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn));
+    nm_assert(!connection || NM_IS_CONNECTION(connection));
+    nm_assert(sett_conn || connection);
+    nm_assert(!connection || !sett_conn
+              || connection == nm_settings_connection_get_connection(sett_conn));
+    nm_assert(out_device);
+    nm_assert(out_is_vpn);
+
+    if (!connection)
+        connection = nm_settings_connection_get_connection(sett_conn);
 
     is_vpn = _connection_is_vpn(connection);
 
@@ -6475,7 +6511,7 @@ validate_activation_request(NMManager             *self,
                                 NM_MANAGER_ERROR,
                                 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
                                 "Device not found");
-            return NULL;
+            return FALSE;
         }
     } else if (!is_vpn) {
         gs_free_error GError *local = NULL;
@@ -6497,13 +6533,13 @@ validate_activation_request(NMManager             *self,
                             NM_MANAGER_ERROR_UNKNOWN_DEVICE,
                             "No suitable device found for this connection (%s).",
                             local->message);
-                return NULL;
+                return FALSE;
             }
 
             /* Look for an existing device with the connection's interface name */
             iface = nm_manager_get_connection_iface(self, connection, NULL, NULL, error);
             if (!iface)
-                return NULL;
+                return FALSE;
 
             device = find_device_by_iface(self, iface, connection, NULL, NULL);
             if (!device) {
@@ -6511,7 +6547,7 @@ validate_activation_request(NMManager             *self,
                                     NM_MANAGER_ERROR,
                                     NM_MANAGER_ERROR_UNKNOWN_DEVICE,
                                     "Failed to find a compatible device for this connection");
-                return NULL;
+                return FALSE;
             }
         }
     }
@@ -6520,7 +6556,8 @@ validate_activation_request(NMManager             *self,
 
     *out_device = device;
     *out_is_vpn = is_vpn;
-    return g_steal_pointer(&subject);
+
+    return TRUE;
 }
 
 /*****************************************************************************/
@@ -6637,17 +6674,14 @@ impl_manager_activate_connection(NMDBusObject                      *obj,
             goto error;
     }
 
-    subject = validate_activation_request(self,
-                                          invocation,
-                                          sett_conn,
-                                          NULL,
-                                          device_path,
-                                          &device,
-                                          &is_vpn,
-                                          &error);
+    subject = validate_activation_request(self, invocation, sett_conn, NULL, &error);
     if (!subject)
         goto error;
 
+    if (!find_device_for_activation(self, sett_conn, NULL, device_path, &device, &is_vpn, &error)) {
+        goto error;
+    }
+
     active = _new_active_connection(self,
                                     is_vpn,
                                     sett_conn,
@@ -6920,17 +6954,20 @@ impl_manager_add_and_activate_connection(NMDBusObject                      *obj,
                                         NM_SETTING_PARSE_FLAGS_STRICT,
                                         NULL);
 
-    subject = validate_activation_request(self,
-                                          invocation,
-                                          NULL,
-                                          incompl_conn,
-                                          device_path,
-                                          &device,
-                                          &is_vpn,
-                                          &error);
+    subject = validate_activation_request(self, invocation, NULL, incompl_conn, &error);
     if (!subject)
         goto error;
 
+    if (!find_device_for_activation(self,
+                                    NULL,
+                                    incompl_conn,
+                                    device_path,
+                                    &device,
+                                    &is_vpn,
+                                    &error)) {
+        goto error;
+    }
+
     if (is_vpn) {
         /* Try to fill the VPN's connection setting and name at least */
         if (!nm_connection_get_setting_vpn(incompl_conn)) {
@@ -6952,8 +6989,7 @@ impl_manager_add_and_activate_connection(NMDBusObject                      *obj,
                                   NULL,
                                   _("VPN connection"),
                                   NULL,
-                                  NULL,
-                                  FALSE); /* No IPv6 by default for now */
+                                  NULL);
     } else {
         conns = nm_settings_connections_array_to_connections(
             nm_settings_get_connections(priv->settings, NULL),
@@ -8931,12 +8967,12 @@ nm_manager_init(NMManager *self)
 
     priv->capabilities = g_array_new(FALSE, FALSE, sizeof(guint32));
 
-    priv->radio_states[NM_RFKILL_TYPE_WLAN] = (RfkillRadioState){
+    priv->radio_states[NM_RFKILL_TYPE_WLAN] = (RfkillRadioState) {
         .user_enabled = TRUE,
         .sw_enabled   = FALSE,
         .hw_enabled   = TRUE,
     };
-    priv->radio_states[NM_RFKILL_TYPE_WWAN] = (RfkillRadioState){
+    priv->radio_states[NM_RFKILL_TYPE_WWAN] = (RfkillRadioState) {
         .user_enabled = TRUE,
         .sw_enabled   = FALSE,
         .hw_enabled   = TRUE,