LLDP TLV names to variant boxed values.
</tp:docstring>
</property>
+ <property name="Real" type="b" access="read">
+ <tp:docstring>
+ True if the device exists, or False for placeholder devices that
+ do not yet exist but could be automatically created by NetworkManager
+ if one of their AvailableConnections was activated.
+ </tp:docstring>
+ </property>
<method name="Disconnect">
<tp:docstring>
PROP_HAS_PENDING_ACTION,
PROP_METERED,
PROP_LLDP_NEIGHBORS,
+ PROP_REAL,
LAST_PROP
};
char * udi;
char * iface; /* may change, could be renamed by user */
int ifindex;
+ gboolean real;
char * ip_iface;
int ip_ifindex;
NMDeviceType type;
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
}
+/**
+ * nm_device_is_software:
+ * @self: the #NMDevice
+ *
+ * Indicates if the device is a software-based virtual device without
+ * backing hardware, which can be added and removed programmatically.
+ *
+ * Returns: %TRUE if the device is a software-based device
+ */
gboolean
nm_device_is_software (NMDevice *self)
{
return NM_FLAGS_HAS (NM_DEVICE_GET_PRIVATE (self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE);
}
+/**
+ * nm_device_is_real:
+ * @self: the #NMDevice
+ *
+ * Returns: %TRUE if the device exists, %FALSE if the device is a placeholder
+ */
+gboolean
+nm_device_is_real (NMDevice *self)
+{
+ return NM_DEVICE_GET_PRIVATE (self)->real;
+}
+
const char *
nm_device_get_ip_iface (NMDevice *self)
{
device_set_master (self, master);
}
+ priv->real = TRUE;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
+
g_object_thaw_notify (G_OBJECT (self));
}
return TRUE;
/* The existence of a software device is good enough. */
- if (nm_device_is_software (self))
+ if (nm_device_is_software (self) && nm_device_is_real (self))
return TRUE;
/* Slaves are also configured by definition */
return;
if (priv->queued_act_request)
return;
- if (!nm_device_is_software (self))
+ if (!nm_device_is_software (self) || !nm_device_is_real (self))
return;
if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED)
return;
{
GError *error = NULL;
- if (!nm_device_is_software (self)) {
+ if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_SOFTWARE,
- "This device is not a software device");
+ "This device is not a software device or is not realized");
g_dbus_method_invocation_take_error (context, error);
return;
}
g_value_take_variant (value, g_variant_builder_end (&array_builder));
}
break;
+ case PROP_REAL:
+ g_value_set_boolean (value, priv->real);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property
+ (object_class, PROP_REAL,
+ g_param_spec_boolean (NM_DEVICE_REAL, "", "",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/* Signals */
signals[STATE_CHANGED] =
g_signal_new ("state-changed",
#define NM_DEVICE_HW_ADDRESS "hw-address"
#define NM_DEVICE_METERED "metered"
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
+#define NM_DEVICE_REAL "real"
#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */
#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */
const char * nm_device_get_iface (NMDevice *dev);
int nm_device_get_ifindex (NMDevice *dev);
gboolean nm_device_is_software (NMDevice *dev);
+gboolean nm_device_is_real (NMDevice *dev);
const char * nm_device_get_ip_iface (NMDevice *dev);
int nm_device_get_ip_ifindex(NMDevice *dev);
const char * nm_device_get_driver (NMDevice *dev);
nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device);
}
-void
-nm_settings_device_added (NMSettings *self, NMDevice *device)
+static void
+device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self)
{
NMConnection *connection;
NMSettingsConnection *added;
GError *error = NULL;
+ if (!nm_device_is_real (device))
+ return;
+
+ g_signal_handlers_disconnect_by_func (device,
+ G_CALLBACK (device_realized),
+ self);
+
/* If the device isn't managed or it already has a default wired connection,
* ignore it.
*/
nm_settings_connection_get_id (added));
}
+void
+nm_settings_device_added (NMSettings *self, NMDevice *device)
+{
+ if (nm_device_is_real (device))
+ device_realized (device, NULL, self);
+ else {
+ g_signal_connect_after (device, "notify::" NM_DEVICE_REAL,
+ G_CALLBACK (device_realized),
+ self);
+ }
+}
+
void
nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quitting)
{
NMSettingsConnection *connection;
+ g_signal_handlers_disconnect_by_func (device,
+ G_CALLBACK (device_realized),
+ self);
+
connection = g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_CONNECTION_TAG);
if (connection) {
default_wired_clear_tag (self, device, connection, FALSE);