mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 22:20:27 +01:00
core: add a "default-unmanaged" setting for devices
Allow devices to declare themselves unmanaged-by-default, but tweak nm-manager and nm-policy to allow activating matching connections on those devices anyway. (This ensures that NM keeps its hands completely off the device unless the user explicitly asks it to do something with it.)
This commit is contained in:
parent
ab7ebead2c
commit
2226a00cc2
4 changed files with 126 additions and 60 deletions
128
src/nm-device.c
128
src/nm-device.c
|
|
@ -184,13 +184,15 @@ typedef struct {
|
|||
char * driver;
|
||||
char * driver_version;
|
||||
char * firmware_version;
|
||||
gboolean managed; /* whether managed by NM or not */
|
||||
RfKillType rfkill_type;
|
||||
gboolean firmware_missing;
|
||||
GHashTable * available_connections;
|
||||
guint8 hw_addr[NM_UTILS_HWADDR_LEN_MAX];
|
||||
guint hw_addr_len;
|
||||
|
||||
gboolean manager_managed; /* whether managed by NMManager or not */
|
||||
gboolean default_unmanaged; /* whether unmanaged by default */
|
||||
|
||||
guint32 ip4_address;
|
||||
|
||||
NMActRequest * act_request;
|
||||
|
|
@ -1342,6 +1344,22 @@ nm_device_is_available (NMDevice *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_can_activate (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (!priv->manager_managed)
|
||||
return FALSE;
|
||||
if (!priv->default_unmanaged && priv->state < NM_DEVICE_STATE_DISCONNECTED)
|
||||
return FALSE;
|
||||
|
||||
if (priv->state > NM_DEVICE_STATE_DISCONNECTED)
|
||||
return FALSE;
|
||||
|
||||
return nm_device_is_available (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_ignore_carrier (NMDevice *dev)
|
||||
{
|
||||
|
|
@ -4123,6 +4141,21 @@ nm_device_activate (NMDevice *self, NMActRequest *req)
|
|||
nm_device_get_iface (self),
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
if (priv->state < NM_DEVICE_STATE_DISCONNECTED) {
|
||||
g_return_if_fail (nm_device_can_activate (self));
|
||||
|
||||
if (priv->state == NM_DEVICE_STATE_UNMANAGED) {
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
g_warn_if_fail (priv->state == NM_DEVICE_STATE_DISCONNECTED);
|
||||
|
||||
priv->act_request = g_object_ref (req);
|
||||
|
|
@ -4524,7 +4557,7 @@ dispose (GObject *object)
|
|||
g_warn_if_fail (priv->slaves == NULL);
|
||||
|
||||
/* Take the device itself down and clear its IPv4 configuration */
|
||||
if (priv->managed && take_down) {
|
||||
if (nm_device_get_managed (self) && take_down) {
|
||||
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
|
||||
|
||||
nm_device_take_down (self, FALSE, NM_DEVICE_STATE_REASON_REMOVED);
|
||||
|
|
@ -4662,9 +4695,6 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_IP4_ADDRESS:
|
||||
priv->ip4_address = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_MANAGED:
|
||||
priv->managed = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_AUTOCONNECT:
|
||||
priv->autoconnect = g_value_get_boolean (value);
|
||||
break;
|
||||
|
|
@ -4807,7 +4837,7 @@ get_property (GObject *object, guint prop_id,
|
|||
g_value_set_uint (value, priv->type);
|
||||
break;
|
||||
case PROP_MANAGED:
|
||||
g_value_set_boolean (value, priv->managed);
|
||||
g_value_set_boolean (value, nm_device_get_managed (self));
|
||||
break;
|
||||
case PROP_AUTOCONNECT:
|
||||
g_value_set_boolean (value, priv->autoconnect);
|
||||
|
|
@ -5011,7 +5041,7 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
"Managed",
|
||||
"Managed",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_AUTOCONNECT,
|
||||
|
|
@ -5385,7 +5415,8 @@ nm_device_state_changed (NMDevice *device,
|
|||
* about to assume a connection since that defeats the purpose of
|
||||
* assuming the device's existing connection.
|
||||
*/
|
||||
if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
|
||||
if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED &&
|
||||
old_state != NM_DEVICE_STATE_UNMANAGED)
|
||||
nm_device_deactivate (device, reason);
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
|
|
@ -5416,10 +5447,17 @@ nm_device_state_changed (NMDevice *device,
|
|||
nm_device_get_iface (device));
|
||||
nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED",
|
||||
nm_device_get_iface (device));
|
||||
if (old_state == NM_DEVICE_STATE_UNMANAGED) {
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED",
|
||||
nm_device_get_iface (device));
|
||||
} else if (old_state > NM_DEVICE_STATE_UNAVAILABLE && priv->default_unmanaged)
|
||||
nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
if (old_state > NM_DEVICE_STATE_DISCONNECTED && priv->default_unmanaged)
|
||||
nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE);
|
||||
break;
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
nm_log_info (LOGD_DEVICE, "Activation (%s) successful, device activated.",
|
||||
nm_device_get_iface (device));
|
||||
|
|
@ -5633,39 +5671,79 @@ nm_device_queued_ip_config_change_clear (NMDevice *self)
|
|||
|
||||
gboolean
|
||||
nm_device_get_managed (NMDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (device)->managed;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_managed (NMDevice *device,
|
||||
gboolean managed,
|
||||
NMDeviceStateReason reason)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
if (priv->managed == managed)
|
||||
return;
|
||||
|
||||
priv->managed = managed;
|
||||
if (!priv->manager_managed)
|
||||
return FALSE;
|
||||
else if (priv->default_unmanaged)
|
||||
return (priv->state != NM_DEVICE_STATE_UNMANAGED);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_set_managed_internal (NMDevice *device,
|
||||
gboolean managed,
|
||||
NMDeviceStateReason reason)
|
||||
{
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): now %s",
|
||||
nm_device_get_iface (device),
|
||||
managed ? "managed" : "unmanaged");
|
||||
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED);
|
||||
|
||||
/* If now managed, jump to unavailable */
|
||||
if (managed)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, reason);
|
||||
else
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_manager_managed (NMDevice *device,
|
||||
gboolean managed,
|
||||
NMDeviceStateReason reason)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
gboolean was_managed, now_managed;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
was_managed = nm_device_get_managed (device);
|
||||
priv->manager_managed = managed;
|
||||
now_managed = nm_device_get_managed (device);
|
||||
|
||||
if (was_managed != now_managed)
|
||||
nm_device_set_managed_internal (device, now_managed, reason);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_default_unmanaged (NMDevice *device,
|
||||
gboolean default_unmanaged)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
gboolean was_managed, now_managed;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
was_managed = nm_device_get_managed (device);
|
||||
priv->default_unmanaged = default_unmanaged;
|
||||
now_managed = nm_device_get_managed (device);
|
||||
|
||||
if (was_managed != now_managed)
|
||||
nm_device_set_managed_internal (device, now_managed,
|
||||
default_unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED :
|
||||
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_spec_match_list:
|
||||
* @device: an #NMDevice
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ NMActRequest * nm_device_get_act_request (NMDevice *dev);
|
|||
NMConnection * nm_device_get_connection (NMDevice *dev);
|
||||
|
||||
gboolean nm_device_is_available (NMDevice *dev);
|
||||
gboolean nm_device_can_activate (NMDevice *dev);
|
||||
|
||||
gboolean nm_device_ignore_carrier (NMDevice *dev);
|
||||
|
||||
NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
|
||||
|
|
@ -279,9 +281,11 @@ void nm_device_set_enabled (NMDevice *device, gboolean enabled);
|
|||
RfKillType nm_device_get_rfkill_type (NMDevice *device);
|
||||
|
||||
gboolean nm_device_get_managed (NMDevice *device);
|
||||
void nm_device_set_managed (NMDevice *device,
|
||||
gboolean managed,
|
||||
NMDeviceStateReason reason);
|
||||
void nm_device_set_manager_managed (NMDevice *device,
|
||||
gboolean managed,
|
||||
NMDeviceStateReason reason);
|
||||
void nm_device_set_default_unmanaged (NMDevice *device,
|
||||
gboolean default_unmanaged);
|
||||
|
||||
gboolean nm_device_get_autoconnect (NMDevice *device);
|
||||
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ remove_one_device (NMManager *manager,
|
|||
if ( !nm_device_can_assume_connections (device)
|
||||
|| (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
|
||||
|| !quitting)
|
||||
nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED);
|
||||
nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager);
|
||||
|
|
@ -1362,10 +1362,10 @@ system_unmanaged_devices_changed_cb (NMSettings *settings,
|
|||
gboolean managed;
|
||||
|
||||
managed = !nm_device_spec_match_list (device, unmanaged_specs);
|
||||
nm_device_set_managed (device,
|
||||
managed,
|
||||
managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED :
|
||||
NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
|
||||
nm_device_set_manager_managed (device,
|
||||
managed,
|
||||
managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED :
|
||||
NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1788,7 +1788,7 @@ add_device (NMManager *self, NMDevice *device)
|
|||
static guint32 devcount = 0;
|
||||
const GSList *unmanaged_specs;
|
||||
NMConnection *existing = NULL;
|
||||
gboolean managed = FALSE, enabled = FALSE;
|
||||
gboolean enabled = FALSE;
|
||||
RfKillType rtype;
|
||||
NMDeviceType devtype;
|
||||
|
||||
|
|
@ -1887,11 +1887,10 @@ add_device (NMManager *self, NMDevice *device)
|
|||
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
|
||||
if ( !manager_sleeping (self)
|
||||
&& !nm_device_spec_match_list (device, unmanaged_specs)) {
|
||||
nm_device_set_managed (device,
|
||||
TRUE,
|
||||
existing ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED :
|
||||
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
managed = TRUE;
|
||||
nm_device_set_manager_managed (device,
|
||||
TRUE,
|
||||
existing ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED :
|
||||
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
}
|
||||
|
||||
nm_settings_device_added (priv->settings, device);
|
||||
|
|
@ -1903,7 +1902,7 @@ add_device (NMManager *self, NMDevice *device)
|
|||
system_create_virtual_devices (self);
|
||||
|
||||
/* If the device has a connection it can assume, do that now */
|
||||
if (existing && managed && nm_device_is_available (device)) {
|
||||
if (existing && nm_device_can_activate (device)) {
|
||||
NMActiveConnection *ac;
|
||||
GError *error = NULL;
|
||||
|
||||
|
|
@ -2753,7 +2752,6 @@ nm_manager_activate_connection (NMManager *manager,
|
|||
NMManagerPrivate *priv;
|
||||
NMDevice *device = NULL;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
NMDeviceState state;
|
||||
char *iface;
|
||||
NMDevice *master_device = NULL;
|
||||
NMConnection *master_connection = NULL;
|
||||
|
|
@ -2843,22 +2841,10 @@ nm_manager_activate_connection (NMManager *manager,
|
|||
"Failed to create virtual interface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A newly created device, if allowed to be managed by NM, will be
|
||||
* in the UNAVAILABLE state here. Since we want to use it right
|
||||
* away, we transition it immediately to DISCONNECTED.
|
||||
*/
|
||||
if ( nm_device_is_available (device)
|
||||
&& (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state = nm_device_get_state (device);
|
||||
if (state < NM_DEVICE_STATE_DISCONNECTED) {
|
||||
if (!nm_device_can_activate (device)) {
|
||||
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE,
|
||||
"Device not managed by NetworkManager or unavailable");
|
||||
return NULL;
|
||||
|
|
@ -3245,7 +3231,7 @@ do_sleep_wake (NMManager *self)
|
|||
* the manager wakes up.
|
||||
*/
|
||||
for (iter = priv->devices; iter; iter = iter->next)
|
||||
nm_device_set_managed (NM_DEVICE (iter->data), FALSE, NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
nm_device_set_manager_managed (NM_DEVICE (iter->data), FALSE, NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
|
||||
} else {
|
||||
nm_log_info (LOGD_SUSPEND, "waking up and re-enabling...");
|
||||
|
|
@ -3282,9 +3268,9 @@ do_sleep_wake (NMManager *self)
|
|||
g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, TRUE, NULL);
|
||||
|
||||
if (nm_device_spec_match_list (device, unmanaged_specs))
|
||||
nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
|
||||
nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
|
||||
else
|
||||
nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
nm_device_set_manager_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1146,13 +1146,11 @@ static void
|
|||
schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds)
|
||||
{
|
||||
ActivateData *data;
|
||||
NMDeviceState state;
|
||||
|
||||
if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
|
||||
return;
|
||||
|
||||
state = nm_device_get_state (device);
|
||||
if (state < NM_DEVICE_STATE_DISCONNECTED)
|
||||
if (!nm_device_can_activate (device))
|
||||
return;
|
||||
|
||||
if (!nm_device_get_enabled (device))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue