summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.c8
-rw-r--r--src/devices/nm-device-bond.c66
-rw-r--r--src/devices/nm-device-bridge.c102
-rw-r--r--src/devices/nm-device-ethernet.c19
-rw-r--r--src/devices/nm-device-factory.c96
-rw-r--r--src/devices/nm-device-factory.h85
-rw-r--r--src/devices/nm-device-generic.c39
-rw-r--r--src/devices/nm-device-generic.h2
-rw-r--r--src/devices/nm-device-gre.c10
-rw-r--r--src/devices/nm-device-infiniband.c132
-rw-r--r--src/devices/nm-device-macvlan.c10
-rw-r--r--src/devices/nm-device-private.h2
-rw-r--r--src/devices/nm-device-tun.c76
-rw-r--r--src/devices/nm-device-veth.c10
-rw-r--r--src/devices/nm-device-vlan.c312
-rw-r--r--src/devices/nm-device-vlan.h3
-rw-r--r--src/devices/nm-device-vxlan.c29
-rw-r--r--src/devices/nm-device.c353
-rw-r--r--src/devices/nm-device.h61
-rw-r--r--src/devices/team/nm-device-team.c39
-rw-r--r--src/devices/team/nm-device-team.h14
-rw-r--r--src/devices/team/nm-team-factory.c20
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c6
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.h2
-rw-r--r--src/devices/wifi/nm-device-wifi.c15
-rw-r--r--src/devices/wifi/nm-device-wifi.h2
-rw-r--r--src/devices/wifi/nm-wifi-factory.c16
-rw-r--r--src/devices/wwan/nm-wwan-factory.c11
-rw-r--r--src/nm-manager.c30
29 files changed, 825 insertions, 745 deletions
diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c
index 8d41ca3f1b..ed424bd2f6 100644
--- a/src/devices/bluetooth/nm-bluez-manager.c
+++ b/src/devices/bluetooth/nm-bluez-manager.c
@@ -409,7 +409,11 @@ nm_bluez_manager_init (NMBluezManager *self)
}
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
g_warn_if_fail (plink->type == NM_LINK_TYPE_BNEP);
*out_ignore = TRUE;
@@ -420,7 +424,7 @@ static void
device_factory_interface_init (NMDeviceFactory *factory_iface)
{
factory_iface->get_supported_types = get_supported_types;
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
factory_iface->start = start;
}
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
index f00f618fa9..b352e513dd 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -464,6 +464,32 @@ release_slave (NMDevice *device,
return success;
}
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
+{
+ const char *iface = nm_device_get_iface (device);
+ NMPlatformError plerr;
+
+ g_assert (iface);
+ g_assert (nm_device_get_ifindex (device) <= 0);
+ g_assert (out_plink);
+
+ plerr = nm_platform_bond_add (NM_PLATFORM_GET, iface, out_plink);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to create bond interface '%s' for '%s': %s",
+ iface,
+ nm_connection_get_id (connection),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+ return TRUE;
+}
+
/******************************************************************/
static void
@@ -524,6 +550,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
parent_class->update_connection = update_connection;
parent_class->master_update_slave_connection = master_update_slave_connection;
+ parent_class->create_and_realize = create_and_realize;
parent_class->act_stage1_prepare = act_stage1_prepare;
parent_class->ip4_config_pre_commit = ip4_config_pre_commit;
parent_class->enslave_slave = enslave_slave;
@@ -547,38 +574,12 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
#define NM_BOND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BOND_FACTORY, NMBondFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
-{
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND,
- NM_DEVICE_PLATFORM_DEVICE, plink,
- NM_DEVICE_DRIVER, "bonding",
- NM_DEVICE_TYPE_DESC, "Bond",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND,
- NM_DEVICE_IS_MASTER, TRUE,
- NULL);
-}
-
-static NMDevice *
-create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- const char *iface = nm_connection_get_interface_name (connection);
- NMPlatformError plerr;
-
- g_assert (iface);
-
- plerr = nm_platform_bond_add (NM_PLATFORM_GET, iface, NULL);
- if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Failed to create bond interface '%s' for '%s': %s",
- iface,
- nm_connection_get_id (connection),
- nm_platform_error_to_string (plerr));
- return NULL;
- }
-
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND,
NM_DEVICE_IFACE, iface,
NM_DEVICE_DRIVER, "bonding",
@@ -591,7 +592,6 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (BOND, Bond, bond,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BOND)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BOND_SETTING_NAME),
- factory_iface->new_link = new_link;
- factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index cce97875d7..b031a43e39 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -390,6 +390,52 @@ release_slave (NMDevice *device,
return success;
}
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
+{
+ NMSettingBridge *s_bridge;
+ const char *iface = nm_device_get_iface (device);
+ const char *hwaddr;
+ guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX];
+ NMPlatformError plerr;
+
+ g_assert (iface);
+ g_assert (nm_device_get_ifindex (device) <= 0);
+ g_assert (out_plink);
+
+ s_bridge = nm_connection_get_setting_bridge (connection);
+ g_assert (s_bridge);
+ hwaddr = nm_setting_bridge_get_mac_address (s_bridge);
+ if (hwaddr) {
+ if (!nm_utils_hwaddr_aton (hwaddr, mac_address, ETH_ALEN)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "Invalid hardware address '%s'",
+ hwaddr);
+ return FALSE;
+ }
+ }
+
+ plerr = nm_platform_bridge_add (NM_PLATFORM_GET,
+ iface,
+ hwaddr ? mac_address : NULL,
+ hwaddr ? ETH_ALEN : 0,
+ out_plink);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to create bridge interface '%s' for '%s': %s",
+ iface,
+ nm_connection_get_id (connection),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/******************************************************************/
static void
@@ -450,6 +496,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
parent_class->update_connection = update_connection;
parent_class->master_update_slave_connection = master_update_slave_connection;
+ parent_class->create_and_realize = create_and_realize;
parent_class->act_stage1_prepare = act_stage1_prepare;
parent_class->enslave_slave = enslave_slave;
parent_class->release_slave = release_slave;
@@ -472,54 +519,12 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
#define NM_BRIDGE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BRIDGE_FACTORY, NMBridgeFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
-{
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE,
- NM_DEVICE_PLATFORM_DEVICE, plink,
- NM_DEVICE_DRIVER, "bridge",
- NM_DEVICE_TYPE_DESC, "Bridge",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE,
- NM_DEVICE_IS_MASTER, TRUE,
- NULL);
-}
-
-static NMDevice *
-create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- const char *iface = nm_connection_get_interface_name (connection);
- NMSettingBridge *s_bridge;
- const char *mac_address_str;
- guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX];
- NMPlatformError plerr;
-
- g_assert (iface);
-
- s_bridge = nm_connection_get_setting_bridge (connection);
- g_assert (s_bridge);
-
- mac_address_str = nm_setting_bridge_get_mac_address (s_bridge);
- if (mac_address_str) {
- if (!nm_utils_hwaddr_aton (mac_address_str, mac_address, ETH_ALEN))
- mac_address_str = NULL;
- }
-
- plerr = nm_platform_bridge_add (NM_PLATFORM_GET,
- iface,
- mac_address_str ? mac_address : NULL,
- mac_address_str ? ETH_ALEN : 0,
- NULL);
- if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Failed to create bridge interface '%s' for '%s': %s",
- iface,
- nm_connection_get_id (connection),
- nm_platform_error_to_string (plerr));
- return NULL;
- }
-
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE,
NM_DEVICE_IFACE, iface,
NM_DEVICE_DRIVER, "bridge",
@@ -532,7 +537,6 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (BRIDGE, Bridge, bridge,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BRIDGE)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME),
- factory_iface->new_link = new_link;
- factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 8fcf4827fb..6caea4974c 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -299,6 +299,14 @@ nm_device_ethernet_init (NMDeviceEthernet *self)
priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
+static void
+setup (NMDevice *device, NMPlatformLink *plink)
+{
+ NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->setup (device, plink);
+
+ g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
+}
+
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
@@ -1674,6 +1682,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
object_class->set_property = set_property;
parent_class->get_generic_capabilities = get_generic_capabilities;
+ parent_class->setup = setup;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
parent_class->new_default_connection = new_default_connection;
@@ -1715,10 +1724,14 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
#define NM_ETHERNET_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ETHERNET_FACTORY, NMEthernetFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Ethernet",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET,
NULL);
@@ -1727,6 +1740,6 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (ETHERNET, Ethernet, ethernet,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_ETHERNET)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_PPPOE_SETTING_NAME),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c
index 1303480857..7f2468bd0d 100644
--- a/src/devices/nm-device-factory.c
+++ b/src/devices/nm-device-factory.c
@@ -79,86 +79,64 @@ nm_device_factory_start (NMDeviceFactory *factory)
}
NMDevice *
-nm_device_factory_new_link (NMDeviceFactory *factory,
- NMPlatformLink *plink,
- gboolean *out_ignore,
- GError **error)
+nm_device_factory_create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore,
+ GError **error)
{
NMDeviceFactory *interface;
const NMLinkType *link_types = NULL;
const char **setting_types = NULL;
int i;
- g_return_val_if_fail (factory != NULL, NULL);
- g_return_val_if_fail (plink != NULL, NULL);
+ g_return_val_if_fail (factory, NULL);
+ g_return_val_if_fail (iface && *iface, NULL);
+ g_return_val_if_fail (plink || connection, NULL);
+ g_return_val_if_fail (!plink || !connection, NULL);
- /* Ensure the factory can create interfaces for this connection */
nm_device_factory_get_supported_types (factory, &link_types, &setting_types);
- for (i = 0; link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) {
- if (plink->type == link_types[i])
- break;
- }
-
- if (link_types[i] == NM_LINK_TYPE_UNKNOWN) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Device factory %s does not support link type %s (%d)",
- G_OBJECT_TYPE_NAME (factory),
- plink->kind, plink->type);
- return NULL;
- }
-
- interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
- if (!interface->new_link) {
- g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
- "Device factory %s cannot manage new devices",
- G_OBJECT_TYPE_NAME (factory));
- return NULL;
- }
- return interface->new_link (factory, plink, out_ignore, error);
-}
+ if (plink) {
+ g_return_val_if_fail (strcmp (iface, plink->name) == 0, NULL);
-NMDevice *
-nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
-{
- NMDeviceFactory *interface;
- const char **setting_types = NULL;
- gboolean found = FALSE;
- int i;
+ for (i = 0; link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) {
+ if (plink->type == link_types[i])
+ break;
+ }
- g_return_val_if_fail (factory, NULL);
- g_return_val_if_fail (connection, NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- /* Ensure the factory can create interfaces for this connection */
- nm_device_factory_get_supported_types (factory, NULL, &setting_types);
- for (i = 0; setting_types && setting_types[i]; i++) {
- if (nm_connection_is_type (connection, setting_types[i])) {
- found = TRUE;
- break;
+ if (link_types[i] == NM_LINK_TYPE_UNKNOWN) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Device factory %s does not support link type %s (%d)",
+ G_OBJECT_TYPE_NAME (factory),
+ plink->kind, plink->type);
+ return NULL;
+ }
+ } else if (connection) {
+ for (i = 0; setting_types && setting_types[i]; i++) {
+ if (nm_connection_is_type (connection, setting_types[i]))
+ break;
}
- }
- if (!found) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
- "Device factory %s does not support connection type %s",
- G_OBJECT_TYPE_NAME (factory),
- nm_connection_get_connection_type (connection));
- return NULL;
+ if (!setting_types[i]) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
+ "Device factory %s does not support connection type %s",
+ G_OBJECT_TYPE_NAME (factory),
+ nm_connection_get_connection_type (connection));
+ return NULL;
+ }
}
interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
- if (!interface->create_virtual_device_for_connection) {
+ if (!interface->create_device) {
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
- "Device factory %s cannot create virtual devices",
+ "Device factory %s cannot manage new devices",
G_OBJECT_TYPE_NAME (factory));
return NULL;
}
- return interface->create_virtual_device_for_connection (factory, connection, parent, error);
+ return interface->create_device (factory, iface, plink, connection, out_ignore);
}
const char *
diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h
index 1ac1fc9a41..1bee6b76cb 100644
--- a/src/devices/nm-device-factory.h
+++ b/src/devices/nm-device-factory.h
@@ -84,51 +84,7 @@ struct _NMDeviceFactory {
* Start the factory and discover any existing devices that the factory
* can manage.
*/
- void (*start) (NMDeviceFactory *factory);
-
- /**
- * new_link:
- * @factory: the #NMDeviceFactory
- * @plink: the new link
- * @out_ignore: on return, %TRUE if the link should be ignored
- * @error: error if the link could be claimed but an error occurred
- *
- * The NetworkManager core was notified of a new link which the plugin
- * may want to claim and create a #NMDevice subclass for. If the link
- * represents a device which the factory does not support, or the link
- * is supported but the device could not be created, %NULL should be
- * returned and @error should be set.
- *
- * If the plugin cannot create a #NMDevice for the link and wants the
- * core to ignore it, set @out_ignore to %TRUE and return no error.
- *
- * @plink is guaranteed to be one of the types the factory returns in
- * get_supported_types().
- *
- * Returns: the #NMDevice if the link was claimed and created, %NULL if not
- */
- NMDevice * (*new_link) (NMDeviceFactory *factory,
- NMPlatformLink *plink,
- gboolean *out_ignore,
- GError **error);
-
- /**
- * create_virtual_device_for_connection:
- * @factory: the #NMDeviceFactory
- * @connection: the #NMConnection
- * @error: a @GError in case of failure
- *
- * Virtual device types (such as team, bond, bridge) may need to be created.
- * This function tries to create a device based on the given @connection.
- *
- * Returns: the newly created #NMDevice. If the factory does not support the
- * connection type, it should return %NULL and leave @error unset. On error
- * it should set @error and return %NULL.
- */
- NMDevice * (*create_virtual_device_for_connection) (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error);
+ void (*start) (NMDeviceFactory *factory);
/**
* get_connection_parent:
@@ -159,6 +115,30 @@ struct _NMDeviceFactory {
NMConnection *connection,
const char *parent_iface);
+ /**
+ * create_device:
+ * @factory: the #NMDeviceFactory
+ * @iface: the interface name of the device
+ * @plink: the #NMPlatformLink if backed by a kernel device
+ * @connection: the #NMConnection if not backed by a kernel device
+ * @out_ignore: on return, %TRUE if the link should be ignored
+ *
+ * The plugin should create a new unrealized device using the details given
+ * by @iface and @plink or @connection. If both @iface and @plink are given,
+ * they are guaranteed to match. If both @iface and @connection are given,
+ * @iface is guaranteed to be the interface name that @connection specifies.
+ *
+ * If the plugin cannot create a #NMDevice for the link and wants the
+ * core to ignore it, set @out_ignore to %TRUE and return %NULL.
+ *
+ * Returns: the new unrealized #NMDevice, or %NULL
+ */
+ NMDevice * (*create_device) (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore);
+
/* Signals */
/**
@@ -201,15 +181,12 @@ char * nm_device_factory_get_virtual_iface_name (NMDeviceFactory *factory,
void nm_device_factory_start (NMDeviceFactory *factory);
-NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory,
- NMPlatformLink *plink,
- gboolean *out_ignore,
- GError **error);
-
-NMDevice * nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error);
+NMDevice * nm_device_factory_create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore,
+ GError **error);
/* For use by implementations */
gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory,
diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c
index db5b2b6b4d..5d092b98f7 100644
--- a/src/devices/nm-device-generic.c
+++ b/src/devices/nm-device-generic.c
@@ -60,6 +60,21 @@ get_type_description (NMDevice *device)
return NM_DEVICE_CLASS (nm_device_generic_parent_class)->get_type_description (device);
}
+static void
+setup (NMDevice *device, NMPlatformLink *plink)
+{
+ NMDeviceGeneric *self = NM_DEVICE_GENERIC (device);
+ NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self);
+ int ifindex;
+
+ NM_DEVICE_CLASS (nm_device_generic_parent_class)->setup (device, plink);
+
+ g_clear_pointer (&priv->type_description, g_free);
+ ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self));
+ if (ifindex > 0)
+ priv->type_description = g_strdup (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex));
+}
+
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
@@ -96,12 +111,12 @@ update_connection (NMDevice *device, NMConnection *connection)
/**************************************************************/
NMDevice *
-nm_device_generic_new (NMPlatformLink *platform_device)
+nm_device_generic_new (NMPlatformLink *plink)
{
- g_return_val_if_fail (platform_device != NULL, NULL);
+ g_return_val_if_fail (plink != NULL, NULL);
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GENERIC,
- NM_DEVICE_PLATFORM_DEVICE, platform_device,
+ NM_DEVICE_IFACE, plink->name,
NM_DEVICE_TYPE_DESC, "Generic",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
NULL);
@@ -114,22 +129,6 @@ nm_device_generic_init (NMDeviceGeneric *self)
}
static void
-constructed (GObject *object)
-{
- NMDeviceGeneric *self = NM_DEVICE_GENERIC (object);
- NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self);
-
- if (!priv->type_description) {
- int ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self));
-
- if (ifindex != 0)
- priv->type_description = g_strdup (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex));
- }
-
- G_OBJECT_CLASS (nm_device_generic_parent_class)->constructed (object);
-}
-
-static void
dispose (GObject *object)
{
NMDeviceGeneric *self = NM_DEVICE_GENERIC (object);
@@ -184,11 +183,11 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass)
parent_class->connection_type = NM_SETTING_GENERIC_SETTING_NAME;
- object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
+ parent_class->setup = setup;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->get_type_description = get_type_description;
parent_class->check_connection_compatible = check_connection_compatible;
diff --git a/src/devices/nm-device-generic.h b/src/devices/nm-device-generic.h
index 4dad4421f0..1b3fa7f9bc 100644
--- a/src/devices/nm-device-generic.h
+++ b/src/devices/nm-device-generic.h
@@ -45,7 +45,7 @@ typedef struct {
GType nm_device_generic_get_type (void);
-NMDevice *nm_device_generic_new (NMPlatformLink *platform_device);
+NMDevice *nm_device_generic_new (NMPlatformLink *plink);
G_END_DECLS
diff --git a/src/devices/nm-device-gre.c b/src/devices/nm-device-gre.c
index 9cda059603..47169897be 100644
--- a/src/devices/nm-device-gre.c
+++ b/src/devices/nm-device-gre.c
@@ -265,10 +265,14 @@ nm_device_gre_class_init (NMDeviceGreClass *klass)
#define NM_GRE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GRE_FACTORY, NMGreFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GRE,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Gre",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
NULL);
@@ -276,6 +280,6 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (GRE, Gre, gre,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE, NM_LINK_TYPE_GRETAP),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c
index 98e2f1de09..ce531655bc 100644
--- a/src/devices/nm-device-infiniband.c
+++ b/src/devices/nm-device-infiniband.c
@@ -55,10 +55,7 @@ enum {
LAST_PROP
};
-static void
-nm_device_infiniband_init (NMDeviceInfiniband * self)
-{
-}
+/*************************************************************/
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
@@ -238,6 +235,66 @@ update_connection (NMDevice *device, NMConnection *connection)
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL);
}
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
+{
+ NMSettingInfiniband *s_infiniband;
+ int parent_ifindex, p_key;
+ NMPlatformError plerr;
+
+ g_assert (nm_device_get_ifindex (device) <= 0);
+ g_assert (out_plink);
+
+ if (!NM_IS_DEVICE_INFINIBAND (parent)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Parent interface %s must be an InfiniBand interface",
+ nm_device_get_iface (parent));
+ return FALSE;
+ }
+
+ s_infiniband = nm_connection_get_setting_infiniband (connection);
+
+ /* Can only create partitions at this time */
+ p_key = nm_setting_infiniband_get_p_key (s_infiniband);
+ if (p_key < 0) {
+ g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "only InfiniBand partitions can be created");
+ return FALSE;
+ }
+
+ parent_ifindex = nm_device_get_ifindex (parent);
+ if (parent_ifindex <= 0) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "failed to get InfiniBand parent %s ifindex",
+ nm_device_get_iface (parent));
+ return FALSE;
+ }
+
+ plerr = nm_platform_infiniband_partition_add (NM_PLATFORM_GET, parent_ifindex, p_key, out_plink);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
+ nm_device_get_iface (device),
+ nm_connection_get_id (connection),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+
+ NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->is_partition = TRUE;
+ return TRUE;
+}
+
+/*************************************************************/
+
+static void
+nm_device_infiniband_init (NMDeviceInfiniband * self)
+{
+}
+
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -278,6 +335,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
+ parent_class->create_and_realize = create_and_realize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
@@ -304,58 +362,31 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
#define NM_INFINIBAND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INFINIBAND_FACTORY, NMInfinibandFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
-{
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND,
- NM_DEVICE_PLATFORM_DEVICE, plink,
- NM_DEVICE_TYPE_DESC, "InfiniBand",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND,
- NM_DEVICE_INFINIBAND_IS_PARTITION, (plink->parent > 0),
- NULL);
-}
-
-static NMDevice *
-create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- NMSettingInfiniband *s_infiniband;
- int p_key, parent_ifindex;
- const char *iface;
- NMPlatformError plerr;
-
- if (!NM_IS_DEVICE_INFINIBAND (parent)) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Parent interface %s must be an InfiniBand interface",
- nm_device_get_iface (parent));
- return NULL;
- }
-
- s_infiniband = nm_connection_get_setting_infiniband (connection);
-
- iface = nm_setting_infiniband_get_virtual_interface_name (s_infiniband);
- g_assert (iface);
-
- parent_ifindex = nm_device_get_ifindex (parent);
- p_key = nm_setting_infiniband_get_p_key (s_infiniband);
-
- plerr = nm_platform_infiniband_partition_add (NM_PLATFORM_GET, parent_ifindex, p_key, NULL);
- if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
- iface,
- nm_connection_get_id (connection),
- nm_platform_error_to_string (plerr));
- return NULL;
+ gboolean is_partition = FALSE;
+
+ if (plink)
+ is_partition = (plink->parent > 0);
+ else if (connection) {
+ NMSettingInfiniband *s_infiniband;
+
+ s_infiniband = nm_connection_get_setting_infiniband (connection);
+ g_return_val_if_fail (s_infiniband, NULL);
+ is_partition = !!nm_setting_infiniband_get_parent (s_infiniband)
+ || ( nm_setting_infiniband_get_p_key (s_infiniband) >= 0
+ && nm_setting_infiniband_get_mac_address (s_infiniband));
}
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND,
NM_DEVICE_IFACE, iface,
- NM_DEVICE_DRIVER, nm_device_get_driver (parent),
NM_DEVICE_TYPE_DESC, "InfiniBand",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND,
- NM_DEVICE_INFINIBAND_IS_PARTITION, TRUE,
+ NM_DEVICE_INFINIBAND_IS_PARTITION, is_partition,
NULL);
}
@@ -395,8 +426,7 @@ get_virtual_iface_name (NMDeviceFactory *factory,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (INFINIBAND, Infiniband, infiniband,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_INFINIBAND)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_INFINIBAND_SETTING_NAME),
- factory_iface->new_link = new_link;
- factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection;
+ factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
)
diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c
index e2d256671e..51d75b5bc9 100644
--- a/src/devices/nm-device-macvlan.c
+++ b/src/devices/nm-device-macvlan.c
@@ -173,10 +173,14 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
#define NM_MACVLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MACVLAN_FACTORY, NMMacvlanFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Macvlan",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
NULL);
@@ -184,6 +188,6 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (MACVLAN, Macvlan, macvlan,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h
index 19e00e01cb..c4e3fe0de3 100644
--- a/src/devices/nm-device-private.h
+++ b/src/devices/nm-device-private.h
@@ -28,8 +28,6 @@
/* This file should only be used by subclasses of NMDevice */
-#define NM_DEVICE_PLATFORM_DEVICE "platform-device"
-
enum NMActStageReturn {
NM_ACT_STAGE_RETURN_FAILURE = 0,
NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */
diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c
index d996470af5..e2af6b279f 100644
--- a/src/devices/nm-device-tun.c
+++ b/src/devices/nm-device-tun.c
@@ -41,7 +41,6 @@ G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE_GENERIC)
typedef struct {
NMPlatformTunProperties props;
const char *mode;
- guint delay_tun_get_properties_id;
} NMDeviceTunPrivate;
enum {
@@ -95,17 +94,24 @@ link_changed (NMDevice *device, NMPlatformLink *info)
reload_tun_properties (NM_DEVICE_TUN (device));
}
-static gboolean
-delay_tun_get_properties_cb (gpointer user_data)
+static void
+setup (NMDevice *device, NMPlatformLink *plink)
{
- NMDeviceTun *self = user_data;
+ NMDeviceTun *self = NM_DEVICE_TUN (device);
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
- priv->delay_tun_get_properties_id = 0;
+ NM_DEVICE_CLASS (nm_device_tun_parent_class)->setup (device, plink);
- reload_tun_properties (self);
+ priv->mode = NULL;
+ if (plink->type == NM_LINK_TYPE_TUN)
+ priv->mode = "tun";
+ else if (plink->type == NM_LINK_TYPE_TAP)
+ priv->mode = "tap";
+ else
+ g_assert_not_reached ();
+ g_object_notify (G_OBJECT (device), NM_DEVICE_TUN_MODE);
- return G_SOURCE_REMOVE;
+ reload_tun_properties (NM_DEVICE_TUN (device));
}
/**************************************************************/
@@ -116,37 +122,6 @@ nm_device_tun_init (NMDeviceTun *self)
}
static void
-constructed (GObject *object)
-{
- NMDeviceTun *self = NM_DEVICE_TUN (object);
- gboolean properties_read;
- NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
-
- properties_read = nm_platform_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), &priv->props);
-
- G_OBJECT_CLASS (nm_device_tun_parent_class)->constructed (object);
-
- if (!properties_read) {
- /* Error reading the tun properties. Maybe this was due to a race. Try again a bit later. */
- _LOGD (LOGD_HW, "could not read tun properties (retry)");
- priv->delay_tun_get_properties_id = g_timeout_add_seconds (1, delay_tun_get_properties_cb, self);
- }
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object);
-
- if (priv->delay_tun_get_properties_id) {
- g_source_remove (priv->delay_tun_get_properties_id);
- priv->delay_tun_get_properties_id = 0;
- }
-
- G_OBJECT_CLASS (nm_device_tun_parent_class)->dispose (object);
-}
-
-static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
@@ -213,12 +188,11 @@ nm_device_tun_class_init (NMDeviceTunClass *klass)
g_type_class_add_private (klass, sizeof (NMDeviceTunPrivate));
- object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->set_property = set_property;
- object_class->dispose = dispose;
device_class->link_changed = link_changed;
+ device_class->setup = setup;
/* properties */
g_object_class_install_property
@@ -268,29 +242,21 @@ nm_device_tun_class_init (NMDeviceTunClass *klass)
#define NM_TUN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TUN_FACTORY, NMTunFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- const char *mode = NULL;
-
- if (plink->type == NM_LINK_TYPE_TUN)
- mode = "tun";
- else if (plink->type == NM_LINK_TYPE_TAP)
- mode = "tap";
- else {
- g_warn_if_reached ();
- mode = "unknown";
- }
-
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Tun",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
- NM_DEVICE_TUN_MODE, mode,
NULL);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (TUN, Tun, tun,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_TUN, NM_LINK_TYPE_TAP),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c
index 944e9da616..1a3a65443d 100644
--- a/src/devices/nm-device-veth.c
+++ b/src/devices/nm-device-veth.c
@@ -175,10 +175,14 @@ nm_device_veth_class_init (NMDeviceVethClass *klass)
#define NM_VETH_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VETH_FACTORY, NMVethFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Veth",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET,
NULL);
@@ -186,6 +190,6 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (VETH, Veth, veth,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VETH),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 511656ffe0..d89bf625b5 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -51,8 +51,6 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate))
typedef struct {
- gboolean invalid;
-
NMDevice *parent;
guint parent_state_id;
int vlan_id;
@@ -63,8 +61,6 @@ enum {
PROP_PARENT,
PROP_VLAN_ID,
- PROP_INT_PARENT_DEVICE,
-
LAST_PROP
};
@@ -87,7 +83,7 @@ parent_state_changed (NMDevice *parent,
}
static void
-nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean construct)
+nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
NMDevice *device = NM_DEVICE (self);
@@ -109,16 +105,10 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean constr
device);
/* Set parent-dependent unmanaged flag */
- if (construct) {
- nm_device_set_initial_unmanaged_flag (device,
- NM_UNMANAGED_PARENT,
- !nm_device_get_managed (parent));
- } else {
- nm_device_set_unmanaged (device,
- NM_UNMANAGED_PARENT,
- !nm_device_get_managed (parent),
- NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED);
- }
+ nm_device_set_unmanaged (device,
+ NM_UNMANAGED_PARENT,
+ !nm_device_get_managed (parent),
+ NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED);
}
/* Recheck availability now that the parent has changed */
@@ -128,6 +118,112 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean constr
g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_PARENT);
}
+static void
+setup (NMDevice *device, NMPlatformLink *plink)
+{
+ NMDeviceVlan *self = NM_DEVICE_VLAN (device);
+ NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
+
+ NM_DEVICE_CLASS (nm_device_vlan_parent_class)->setup (device, plink);
+
+ _LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s",
+ priv->vlan_id, nm_device_get_iface (priv->parent));
+}
+
+static gboolean
+realize (NMDevice *device,
+ NMPlatformLink *plink,
+ GError **error)
+{
+ NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device);
+ int parent_ifindex = -1, vlan_id = -1;
+ NMDevice *parent;
+
+ g_return_val_if_fail (plink, FALSE);
+
+ g_assert (plink->type == NM_LINK_TYPE_VLAN);
+
+ if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, plink->ifindex, &parent_ifindex, &vlan_id)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "(%s): failed to read VLAN properties", plink->name);
+ return FALSE;
+ }
+
+ if (vlan_id < 0) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "(%s): VLAN ID invalid", plink->name);
+ return FALSE;
+ }
+
+ parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex);
+ if (!parent) {
+ nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", plink->name);
+ return FALSE;
+ }
+
+ g_warn_if_fail (priv->parent == NULL);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent);
+ priv->vlan_id = vlan_id;
+
+ return TRUE;
+}
+
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
+{
+ NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device);
+ const char *iface = nm_device_get_iface (device);
+ NMSettingVlan *s_vlan;
+ int parent_ifindex, vlan_id;
+ NMPlatformError plerr;
+
+ g_assert (nm_device_get_ifindex (device) <= 0);
+ g_assert (out_plink);
+
+ s_vlan = nm_connection_get_setting_vlan (connection);
+ g_assert (s_vlan);
+
+ if (!nm_device_supports_vlans (parent)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "no support for VLANs on interface %s of type %s",
+ nm_device_get_iface (parent),
+ nm_device_get_type_desc (parent));
+ return FALSE;
+ }
+
+ parent_ifindex = nm_device_get_ifindex (parent);
+ g_warn_if_fail (parent_ifindex > 0);
+
+ vlan_id = nm_setting_vlan_get_id (s_vlan);
+
+ plerr = nm_platform_vlan_add (NM_PLATFORM_GET,
+ iface,
+ parent_ifindex,
+ vlan_id,
+ nm_setting_vlan_get_flags (s_vlan),
+ out_plink);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to create VLAN interface '%s' for '%s': %s",
+ iface,
+ nm_connection_get_id (connection),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+
+ g_warn_if_fail (priv->parent == NULL);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent);
+ priv->vlan_id = vlan_id;
+
+ return TRUE;
+}
+
+/******************************************************************/
+
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
@@ -183,7 +279,7 @@ component_added (NMDevice *device, GObject *component)
if (nm_device_get_ifindex (added_device) != parent_ifindex)
return FALSE;
- nm_device_vlan_set_parent (self, added_device, FALSE);
+ nm_device_vlan_set_parent (self, added_device);
/* Don't claim parent exclusively */
return FALSE;
@@ -357,7 +453,7 @@ update_connection (NMDevice *device, NMConnection *connection)
parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex);
g_assert (parent);
- nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent, FALSE);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent);
/* Update parent in the connection; default to parent's interface name */
new_parent = nm_device_get_iface (parent);
@@ -459,54 +555,6 @@ nm_device_vlan_init (NMDeviceVlan * self)
}
static void
-constructed (GObject *object)
-{
- NMDeviceVlan *self = NM_DEVICE_VLAN (object);
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
- int ifindex = nm_device_get_ifindex (NM_DEVICE (self));
- int parent_ifindex = -1, itype;
- int vlan_id;
-
- if (G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed)
- G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed (object);
-
- itype = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex);
- if (itype != NM_LINK_TYPE_VLAN) {
- _LOGE (LOGD_VLAN, "failed to get VLAN interface type.");
- priv->invalid = TRUE;
- return;
- }
-
- if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, ifindex, &parent_ifindex, &vlan_id)) {
- _LOGW (LOGD_VLAN, "failed to get VLAN interface info.");
- priv->invalid = TRUE;
- return;
- }
-
- if (parent_ifindex < 0 || vlan_id < 0) {
- _LOGW (LOGD_VLAN, "VLAN parent ifindex (%d) or VLAN ID (%d) invalid.",
- parent_ifindex, priv->vlan_id);
- priv->invalid = TRUE;
- return;
- }
-
- if (priv->parent && parent_ifindex != nm_device_get_ip_ifindex (priv->parent)) {
- _LOGW (LOGD_VLAN, "VLAN parent %s (%d) and parent ifindex %d don't match.",
- nm_device_get_iface (priv->parent),
- nm_device_get_ifindex (priv->parent),
- parent_ifindex);
- priv->invalid = TRUE;
- return;
- }
-
- priv->vlan_id = vlan_id;
- _LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s (%d)",
- priv->vlan_id,
- priv->parent ? nm_device_get_iface (priv->parent) : "unknown",
- parent_ifindex);
-}
-
-static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
@@ -516,9 +564,6 @@ get_property (GObject *object, guint prop_id,
case PROP_PARENT:
nm_utils_g_value_set_object_path (value, priv->parent);
break;
- case PROP_INT_PARENT_DEVICE:
- g_value_set_object (value, priv->parent);
- break;
case PROP_VLAN_ID:
g_value_set_uint (value, priv->vlan_id);
break;
@@ -532,25 +577,13 @@ static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_INT_PARENT_DEVICE:
- nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), g_value_get_object (value), TRUE);
- break;
- case PROP_VLAN_ID:
- priv->vlan_id = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
dispose (GObject *object)
{
- nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), NULL, FALSE);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), NULL);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
}
@@ -566,11 +599,13 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
g_type_class_add_private (object_class, sizeof (NMDeviceVlanPrivate));
/* virtual methods */
- object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->dispose = dispose;
+ parent_class->create_and_realize = create_and_realize;
+ parent_class->realize = realize;
+ parent_class->setup = setup;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->bring_up = bring_up;
parent_class->act_stage1_prepare = act_stage1_prepare;
@@ -594,16 +629,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
(object_class, PROP_VLAN_ID,
g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "",
0, 4095, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- /* Internal properties */
- g_object_class_install_property
- (object_class, PROP_INT_PARENT_DEVICE,
- g_param_spec_object (NM_DEVICE_VLAN_INT_PARENT_DEVICE, "", "",
- NM_TYPE_DEVICE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
&dbus_glib_nm_device_vlan_object_info);
@@ -615,93 +641,18 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
#define NM_VLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VLAN_FACTORY, NMVlanFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
-{
- int parent_ifindex = -1;
- NMDevice *parent, *device;
-
- /* Find the parent device */
- if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, plink->ifindex, &parent_ifindex, NULL)) {
- g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "VLAN parent ifindex unknown");
- return NULL;
- }
- parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex);
-
- device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
- NM_DEVICE_PLATFORM_DEVICE, plink,
- NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
- NM_DEVICE_DRIVER, "8021q",
- NM_DEVICE_TYPE_DESC, "VLAN",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
- NULL);
- if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) {
- g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "VLAN initialization failed");
- g_object_unref (device);
- device = NULL;
- }
-
- return device;
-}
-
-static NMDevice *
-create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- NMDevice *device;
- NMSettingVlan *s_vlan;
- gs_free char *iface = NULL;
- NMPlatformError plerr;
-
- if (!NM_IS_DEVICE (parent)) {
- g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "VLAN interfaces must have parents");
- return NULL;
- }
-
- s_vlan = nm_connection_get_setting_vlan (connection);
- g_assert (s_vlan);
-
- iface = g_strdup (nm_connection_get_interface_name (connection));
- if (!iface) {
- iface = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent),
- nm_setting_vlan_get_id (s_vlan));
- }
-
- plerr = nm_platform_vlan_add (NM_PLATFORM_GET,
- iface,
- nm_device_get_ifindex (parent),
- nm_setting_vlan_get_id (s_vlan),
- nm_setting_vlan_get_flags (s_vlan),
- NULL);
- if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Failed to create VLAN interface '%s' for '%s': %s",
- iface,
- nm_connection_get_id (connection),
- nm_platform_error_to_string (plerr));
- return NULL;
- }
-
- device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
- NM_DEVICE_IFACE, iface,
- NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
- NM_DEVICE_DRIVER, "8021q",
- NM_DEVICE_TYPE_DESC, "VLAN",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
- NULL);
- if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) {
- g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
- "Failed to create VLAN interface '%s' for '%s': initialization failed",
- iface, nm_connection_get_id (connection));
- g_object_unref (device);
- device = NULL;
- }
-
- return device;
+ return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
+ NM_DEVICE_IFACE, iface,
+ NM_DEVICE_DRIVER, "8021q",
+ NM_DEVICE_TYPE_DESC, "VLAN",
+ NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
+ NULL);
}
static const char *
@@ -758,8 +709,7 @@ get_virtual_iface_name (NMDeviceFactory *factory,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (VLAN, Vlan, vlan,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VLAN)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VLAN_SETTING_NAME),
- factory_iface->new_link = new_link;
- factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection;
+ factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
)
diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h
index 4a27226fb7..e31e171d04 100644
--- a/src/devices/nm-device-vlan.h
+++ b/src/devices/nm-device-vlan.h
@@ -42,9 +42,6 @@ typedef enum {
#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_ID "vlan-id"
-/* Internal non-exported properties */
-#define NM_DEVICE_VLAN_INT_PARENT_DEVICE "int-parent-device"
-
typedef NMDevice NMDeviceVlan;
typedef NMDeviceClass NMDeviceVlanClass;
diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c
index 072d019a62..4f46f6aa8d 100644
--- a/src/devices/nm-device-vxlan.c
+++ b/src/devices/nm-device-vxlan.c
@@ -131,19 +131,22 @@ link_changed (NMDevice *device, NMPlatformLink *info)
update_properties (device);
}
-/**************************************************************/
-
static void
-nm_device_vxlan_init (NMDeviceVxlan *self)
+setup (NMDevice *device, NMPlatformLink *plink)
{
+ g_assert (plink->type == NM_LINK_TYPE_VXLAN);
+
+ NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->setup (device, plink);
+
+ update_properties (device);
}
+
+/**************************************************************/
+
static void
-constructed (GObject *object)
+nm_device_vxlan_init (NMDeviceVxlan *self)
{
- update_properties (NM_DEVICE (object));
-
- G_OBJECT_CLASS (nm_device_vxlan_parent_class)->constructed (object);
}
static void
@@ -223,10 +226,10 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
g_type_class_add_private (klass, sizeof (NMDeviceVxlanPrivate));
- object_class->constructed = constructed;
object_class->get_property = get_property;
device_class->link_changed = link_changed;
+ device_class->setup = setup;
/* properties */
g_object_class_install_property
@@ -351,10 +354,14 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
#define NM_VXLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VXLAN_FACTORY, NMVxlanFactory))
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN,
- NM_DEVICE_PLATFORM_DEVICE, plink,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Vxlan",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
NULL);
@@ -362,6 +369,6 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_FACTORY_DEFINE_INTERNAL (VXLAN, Vxlan, vxlan,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VXLAN),
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 271201444f..2f21d6f409 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -96,7 +96,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
- PROP_PLATFORM_DEVICE,
PROP_UDI,
PROP_IFACE,
PROP_IP_IFACE,
@@ -380,6 +379,9 @@ static void _set_state_full (NMDevice *self,
static void nm_device_update_hw_address (NMDevice *self);
+static gboolean queued_ip4_config_change (gpointer user_data);
+static gboolean queued_ip6_config_change (gpointer user_data);
+
/***********************************************************/
#define QUEUED_PREFIX "queued state change to "
@@ -1548,6 +1550,95 @@ link_changed (NMDevice *self, NMPlatformLink *info)
nm_device_set_carrier (self, info->connected);
}
+/**
+ * nm_device_realize():
+ * @self: the #NMDevice
+ * @plink: an existing platform link or %NULL
+ * @error: location to store error, or %NULL
+ *
+ * Initializes and sets up the device using existing backing resources.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+nm_device_realize (NMDevice *self, NMPlatformLink *plink, GError **error)
+{
+ /* Try to realize the device from existing resources */
+ if (NM_DEVICE_GET_CLASS (self)->realize) {
+ if (!NM_DEVICE_GET_CLASS (self)->realize (self, plink, error))
+ return FALSE;
+ }
+
+ NM_DEVICE_GET_CLASS (self)->setup (self, plink);
+
+ return TRUE;
+}
+
+/**
+ * nm_device_create_and_realize():
+ * @self: the #NMDevice
+ * @connection: the #NMConnection being activated
+ * @parent: the parent #NMDevice if any
+ * @error: location to store error, or %NULL
+ *
+ * Creates any backing resources needed to realize the device to proceed
+ * with activating @connection.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+nm_device_create_and_realize (NMDevice *self,
+ NMConnection *connection,
+ NMDevice *parent,
+ GError **error)
+{
+ NMPlatformLink plink = { .type = NM_LINK_TYPE_UNKNOWN };
+
+ /* Create any resources the device needs */
+ if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
+ if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
+ return FALSE;
+ }
+
+ NM_DEVICE_GET_CLASS (self)->setup (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
+
+ g_return_val_if_fail (nm_device_check_connection_compatible (self, connection), TRUE);
+ return TRUE;
+}
+
+static void
+update_device_from_platform_link (NMDevice *self, NMPlatformLink *plink)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ const char *udi;
+
+ g_return_if_fail (plink != NULL);
+
+ udi = nm_platform_link_get_udi (NM_PLATFORM_GET, plink->ifindex);
+ if (udi && !g_strcmp0 (udi, priv->udi)) {
+ g_free (priv->udi);
+ priv->udi = g_strdup (udi);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
+ }
+
+ if (!g_strcmp0 (plink->name, priv->iface)) {
+ g_free (priv->iface);
+ priv->iface = g_strdup (plink->name);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IFACE);
+ }
+
+ priv->ifindex = plink->ifindex;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IFINDEX);
+
+ priv->up = NM_FLAGS_HAS (plink->flags, IFF_UP);
+ if (plink->driver && g_strcmp0 (plink->driver, priv->driver) != 0) {
+ g_free (priv->driver);
+ priv->driver = g_strdup (plink->driver);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER);
+ }
+ priv->platform_link_initialized = plink->initialized;
+}
+
static void
config_changed_update_ignore_carrier (NMConfig *config,
NMConfigData *config_data,
@@ -1571,6 +1662,120 @@ check_carrier (NMDevice *self)
nm_device_set_carrier (self, nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
}
+static void
+setup (NMDevice *self, NMPlatformLink *plink)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ static guint32 id = 0;
+
+ /* The device should not be realized */
+ g_return_if_fail (priv->ip_ifindex <= 0);
+ g_return_if_fail (priv->ip_iface == NULL);
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ if (plink) {
+ g_return_if_fail (priv->iface == NULL || strcmp (plink->name, priv->iface) == 0);
+ update_device_from_platform_link (self, plink);
+ }
+
+ if (priv->ifindex > 0) {
+ _LOGD (LOGD_DEVICE, "setup(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
+
+ priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
+
+ priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
+
+ if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
+ priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
+
+ priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_MTU);
+
+ nm_platform_link_get_driver_info (NM_PLATFORM_GET,
+ priv->ifindex,
+ NULL,
+ &priv->driver_version,
+ &priv->firmware_version);
+ if (priv->driver_version)
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION);
+ if (priv->firmware_version)
+ g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION);
+
+ if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
+ priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, priv->ifindex);
+ }
+
+ if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
+ priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
+
+ if (!priv->udi) {
+ /* Use a placeholder UDI until we get a real one */
+ priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
+ }
+
+ /* trigger initial ip config change to initialize ip-config */
+ priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
+ priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
+
+ nm_device_update_hw_address (self);
+
+ if (priv->hw_addr_len) {
+ priv->initial_hw_addr = g_strdup (priv->hw_addr);
+ _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
+
+ if (priv->ifindex > 0) {
+ guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
+ size_t len = 0;
+
+ if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
+ g_warn_if_fail (len == priv->hw_addr_len);
+ priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
+ _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
+ priv->perm_hw_addr);
+ } else {
+ /* Fall back to current address */
+ _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
+ priv->perm_hw_addr = g_strdup (priv->hw_addr);
+ }
+ }
+ }
+
+ /* Note: initial hardware address must be read before calling get_ignore_carrier() */
+ if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
+ NMConfig *config = nm_config_get ();
+
+ priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
+ g_signal_connect (G_OBJECT (config),
+ NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+ G_CALLBACK (config_changed_update_ignore_carrier),
+ self);
+
+ check_carrier (self);
+ _LOGD (LOGD_HW,
+ "carrier is %s%s",
+ priv->carrier ? "ON" : "OFF",
+ priv->ignore_carrier ? " (but ignored)" : "");
+ } else {
+ /* Fake online link when carrier detection is not available. */
+ priv->carrier = TRUE;
+ }
+
+ g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
+
+ /* Enslave ourselves */
+ if (priv->ifindex > 0) {
+ int master = nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex);
+
+ if (master > 0)
+ device_set_master (self, master);
+ }
+
+ g_object_thaw_notify (G_OBJECT (self));
+}
+
/**
* nm_device_notify_component_added():
* @self: the #NMDevice
@@ -8857,54 +9062,12 @@ nm_device_init (NMDevice *self)
priv->v6_commit_first_time = TRUE;
}
-static GObject*
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
+static void
+constructed (GObject *object)
{
- GObject *object;
- NMDevice *self;
- NMDevicePrivate *priv;
+ NMDevice *self = NM_DEVICE (object);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMPlatform *platform;
- static guint32 id = 0;
-
- object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
- n_construct_params,
- construct_params);
- if (!object)
- return NULL;
-
- self = NM_DEVICE (object);
- priv = NM_DEVICE_GET_PRIVATE (self);
-
- _LOGD (LOGD_DEVICE, "constructor(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
-
- if (!priv->iface) {
- _LOGE (LOGD_DEVICE, "No device interface provided, ignoring");
- goto error;
- }
-
- if (!priv->udi) {
- /* Use a placeholder UDI until we get a real one */
- priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
- }
-
- if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
- priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
-
- if (priv->ifindex > 0) {
- priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
- priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
- if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
- priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
- priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
-
- nm_platform_link_get_driver_info (NM_PLATFORM_GET,
- priv->ifindex,
- NULL,
- &priv->driver_version,
- &priv->firmware_version);
- }
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
@@ -8917,79 +9080,6 @@ constructor (GType type,
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
- /* trigger initial ip config change to initialize ip-config */
- priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
- priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
-
- if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET)) {
- int ip_ifindex = nm_device_get_ip_ifindex (self);
-
- if (ip_ifindex > 0)
- priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, ip_ifindex);
- }
-
- return object;
-
-error:
- g_object_unref (self);
- return NULL;
-}
-
-static void
-constructed (GObject *object)
-{
- NMDevice *self = NM_DEVICE (object);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- int master;
-
- nm_device_update_hw_address (self);
-
- if (priv->hw_addr_len) {
- priv->initial_hw_addr = g_strdup (priv->hw_addr);
- _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
-
- if (priv->ifindex > 0) {
- guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
- size_t len = 0;
-
- if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
- g_warn_if_fail (len == priv->hw_addr_len);
- priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
- _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
- priv->perm_hw_addr);
- } else {
- /* Fall back to current address */
- _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
- priv->perm_hw_addr = g_strdup (priv->hw_addr);
- }
- }
- }
-
- /* Note: initial hardware address must be read before calling get_ignore_carrier() */
- if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
- NMConfig *config = nm_config_get ();
-
- priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
- g_signal_connect (G_OBJECT (config),
- NM_CONFIG_SIGNAL_CONFIG_CHANGED,
- G_CALLBACK (config_changed_update_ignore_carrier),
- self);
-
- check_carrier (self);
- _LOGD (LOGD_HW,
- "carrier is %s%s",
- priv->carrier ? "ON" : "OFF",
- priv->ignore_carrier ? " (but ignored)" : "");
- } else {
- /* Fake online link when carrier detection is not available. */
- priv->carrier = TRUE;
- }
-
- /* Enslave ourselves */
- master = nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex);
- if (master)
- device_set_master (self, master);
-
priv->con_provider = nm_connection_provider_get ();
g_assert (priv->con_provider);
g_signal_connect (priv->con_provider,
@@ -9117,25 +9207,10 @@ set_property (GObject *object, guint prop_id,
{
NMDevice *self = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- NMPlatformLink *platform_device;
const char *hw_addr, *p;
guint count;
switch (prop_id) {
- case PROP_PLATFORM_DEVICE:
- platform_device = g_value_get_pointer (value);
- if (platform_device) {
- g_free (priv->udi);
- priv->udi = g_strdup (nm_platform_link_get_udi (NM_PLATFORM_GET, platform_device->ifindex));
- g_free (priv->iface);
- priv->iface = g_strdup (platform_device->name);
- priv->ifindex = platform_device->ifindex;
- priv->up = NM_FLAGS_HAS (platform_device->flags, IFF_UP);
- g_free (priv->driver);
- priv->driver = g_strdup (platform_device->driver);
- priv->platform_link_initialized = platform_device->initialized;
- }
- break;
case PROP_UDI:
if (g_value_get_string (value)) {
g_free (priv->udi);
@@ -9365,7 +9440,6 @@ nm_device_class_init (NMDeviceClass *klass)
object_class->finalize = finalize;
object_class->set_property = set_property;
object_class->get_property = get_property;
- object_class->constructor = constructor;
object_class->constructed = constructed;
klass->link_changed = link_changed;
@@ -9385,6 +9459,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->check_connection_compatible = check_connection_compatible;
klass->check_connection_available = check_connection_available;
klass->can_unmanaged_external_down = can_unmanaged_external_down;
+ klass->setup = setup;
klass->is_up = is_up;
klass->bring_up = bring_up;
klass->take_down = take_down;
@@ -9393,12 +9468,6 @@ nm_device_class_init (NMDeviceClass *klass)
/* Properties */
g_object_class_install_property
- (object_class, PROP_PLATFORM_DEVICE,
- g_param_spec_pointer (NM_DEVICE_PLATFORM_DEVICE, "", "",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property
(object_class, PROP_UDI,
g_param_spec_string (NM_DEVICE_UDI, "", "",
NULL,
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index c6d414bfdf..d849f6682f 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -129,6 +129,58 @@ typedef struct {
void (* link_changed) (NMDevice *self, NMPlatformLink *info);
+ /**
+ * realize():
+ * @self: the #NMDevice
+ * @plink: the #NMPlatformLink if backed by a kernel netdevice
+ * @error: location to store error, or %NULL
+ *
+ * Realize the device from existing backing resources. No resources
+ * should be created as a side-effect of this function. This function
+ * should only fail if critical device properties/resources (eg, VLAN ID)
+ * fail to be read or initialized, that would cause the device to be
+ * unusable. For example, for any properties required to realize the device
+ * during create_and_realize(), if reading those properties in realize()
+ * should fail, this function should probably return %FALSE and an error.
+ *
+ * Returns: %TRUE on success, %FALSE if some error ocurred when realizing
+ * the device from backing resources
+ */
+ gboolean (*realize) (NMDevice *self,
+ NMPlatformLink *plink,
+ GError **error);
+
+ /**
+ * create_and_realize():
+ * @self: the #NMDevice
+ * @connection: the #NMConnection being activated
+ * @parent: the parent #NMDevice, if any
+ * @out_plink: on success, a backing kernel network device if one exists
+ * @error: location to store error, or %NULL
+ *
+ * Create any backing resources (kernel devices, etc) required for this
+ * device to activate @connection. If the device is backed by a kernel
+ * network device, that device should be returned in @out_plink after
+ * being created.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+ gboolean (*create_and_realize) (NMDevice *self,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error);
+
+ /**
+ * setup():
+ * @self: the #NMDevice
+ * @plink: the #NMPlatformLink if backed by a kernel netdevice
+ *
+ * Update the device from backing resource properties (like hardware
+ * addresses, carrier states, driver/firmware info, etc).
+ */
+ void (*setup) (NMDevice *self, NMPlatformLink *plink);
+
/* Hardware state (IFF_UP) */
gboolean (*can_unmanaged_external_down) (NMDevice *self);
gboolean (*is_up) (NMDevice *self);
@@ -257,7 +309,6 @@ typedef struct {
NMConnection * (* new_default_connection) (NMDevice *self);
} NMDeviceClass;
-
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
DBusGMethodInvocation *context,
GError *error,
@@ -392,6 +443,14 @@ void nm_device_set_nm_owned (NMDevice *device);
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
+gboolean nm_device_realize (NMDevice *device,
+ NMPlatformLink *plink,
+ GError **error);
+gboolean nm_device_create_and_realize (NMDevice *self,
+ NMConnection *connection,
+ NMDevice *parent,
+ GError **error);
+
gboolean nm_device_get_autoconnect (NMDevice *device);
void nm_device_state_changed (NMDevice *device,
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c
index 38c125db45..145b854f69 100644
--- a/src/devices/team/nm-device-team.c
+++ b/src/devices/team/nm-device-team.c
@@ -669,38 +669,34 @@ release_slave (NMDevice *device,
return success;
}
-/******************************************************************/
-
-NMDevice *
-nm_device_team_new (NMPlatformLink *platform_device)
-{
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM,
- NM_DEVICE_PLATFORM_DEVICE, platform_device,
- NM_DEVICE_DRIVER, "team",
- NM_DEVICE_TYPE_DESC, "Team",
- NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM,
- NM_DEVICE_IS_MASTER, TRUE,
- NULL);
-}
-
-NMDevice *
-nm_device_team_new_for_connection (NMConnection *connection, GError **error)
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
{
- const char *iface = nm_connection_get_interface_name (connection);
+ const char *iface = nm_device_get_iface (device);
NMPlatformError plerr;
- g_assert (iface);
-
- plerr = nm_platform_team_add (NM_PLATFORM_GET, iface, NULL);
+ plerr = nm_platform_team_add (NM_PLATFORM_GET, iface, out_plink);
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create team master interface '%s' for '%s': %s",
iface,
nm_connection_get_id (connection),
nm_platform_error_to_string (plerr));
- return NULL;
+ return FALSE;
}
+ return TRUE;
+}
+
+/******************************************************************/
+
+NMDevice *
+nm_device_team_new (const char *iface)
+{
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM,
NM_DEVICE_IFACE, iface,
NM_DEVICE_DRIVER, "team",
@@ -798,6 +794,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass)
object_class->set_property = set_property;
object_class->dispose = dispose;
+ parent_class->create_and_realize = create_and_realize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
diff --git a/src/devices/team/nm-device-team.h b/src/devices/team/nm-device-team.h
index 76cdba1396..2436705712 100644
--- a/src/devices/team/nm-device-team.h
+++ b/src/devices/team/nm-device-team.h
@@ -34,20 +34,12 @@ G_BEGIN_DECLS
#define NM_DEVICE_TEAM_SLAVES "slaves"
-typedef struct {
- NMDevice parent;
-} NMDeviceTeam;
-
-typedef struct {
- NMDeviceClass parent;
-
-} NMDeviceTeamClass;
-
+typedef NMDevice NMDeviceTeam;
+typedef NMDeviceClass NMDeviceTeamClass;
GType nm_device_team_get_type (void);
-NMDevice *nm_device_team_new (NMPlatformLink *platform_device);
-NMDevice *nm_device_team_new_for_connection (NMConnection *connection, GError **error);
+NMDevice *nm_device_team_new (const char *iface);
G_END_DECLS
diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c
index d87919b6b7..949e01d15d 100644
--- a/src/devices/team/nm-team-factory.c
+++ b/src/devices/team/nm-team-factory.c
@@ -48,18 +48,13 @@ nm_device_factory_create (GError **error)
/************************************************************************/
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- return nm_device_team_new (plink);
-}
-
-static NMDevice *
-create_virtual_device_for_connection (NMDeviceFactory *factory,
- NMConnection *connection,
- NMDevice *parent,
- GError **error)
-{
- return nm_device_team_new_for_connection (connection, error);
+ return nm_device_team_new (iface);
}
NM_DEVICE_FACTORY_DECLARE_TYPES (
@@ -77,8 +72,7 @@ nm_team_factory_init (NMTeamFactory *self)
static void
device_factory_interface_init (NMDeviceFactory *factory_iface)
{
- factory_iface->new_link = new_link;
- factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection;
+ factory_iface->create_device = create_device;
factory_iface->get_supported_types = get_supported_types;
}
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index ad401f5e52..f7fffd272e 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -419,12 +419,10 @@ state_changed (NMDevice *device,
/*******************************************************************/
NMDevice *
-nm_device_olpc_mesh_new (NMPlatformLink *platform_device)
+nm_device_olpc_mesh_new (const char *iface)
{
- g_return_val_if_fail (platform_device != NULL, NULL);
-
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_OLPC_MESH,
- NM_DEVICE_PLATFORM_DEVICE, platform_device,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "802.11 OLPC Mesh",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH,
NULL);
diff --git a/src/devices/wifi/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h
index 8d6895f27a..63895a88fd 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.h
+++ b/src/devices/wifi/nm-device-olpc-mesh.h
@@ -65,7 +65,7 @@ struct _NMDeviceOlpcMeshClass
GType nm_device_olpc_mesh_get_type (void);
-NMDevice *nm_device_olpc_mesh_new (NMPlatformLink *platform_device);
+NMDevice *nm_device_olpc_mesh_new (const char *iface);
G_END_DECLS
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 0c434bf462..58da7cc065 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -445,6 +445,14 @@ periodic_update_cb (gpointer user_data)
return TRUE;
}
+static void
+setup (NMDevice *device, NMPlatformLink *plink)
+{
+ NM_DEVICE_CLASS (nm_device_wifi_parent_class)->setup (device, plink);
+
+ g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
+}
+
static gboolean
bring_up (NMDevice *device, gboolean *no_firmware)
{
@@ -2844,12 +2852,10 @@ set_enabled (NMDevice *device, gboolean enabled)
/********************************************************************/
NMDevice *
-nm_device_wifi_new (NMPlatformLink *platform_device)
+nm_device_wifi_new (const char *iface)
{
- g_return_val_if_fail (platform_device != NULL, NULL);
-
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIFI,
- NM_DEVICE_PLATFORM_DEVICE, platform_device,
+ NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "802.11 WiFi",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
@@ -2958,6 +2964,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
object_class->dispose = dispose;
object_class->finalize = finalize;
+ parent_class->setup = setup;
parent_class->bring_up = bring_up;
parent_class->can_auto_connect = can_auto_connect;
parent_class->is_available = is_available;
diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h
index c74ff1c5bf..e2954b9c5c 100644
--- a/src/devices/wifi/nm-device-wifi.h
+++ b/src/devices/wifi/nm-device-wifi.h
@@ -73,7 +73,7 @@ struct _NMDeviceWifiClass
GType nm_device_wifi_get_type (void);
-NMDevice *nm_device_wifi_new (NMPlatformLink *platform_device);
+NMDevice * nm_device_wifi_new (const char *iface);
G_END_DECLS
diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c
index c4b4042e70..eca4e1de53 100644
--- a/src/devices/wifi/nm-wifi-factory.c
+++ b/src/devices/wifi/nm-wifi-factory.c
@@ -59,13 +59,19 @@ nm_device_factory_create (GError **error)
/**************************************************************************/
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
+ g_return_val_if_fail (plink != NULL, NULL);
+
if (plink->type == NM_LINK_TYPE_WIFI)
- return nm_device_wifi_new (plink);
+ return nm_device_wifi_new (iface);
else if (plink->type == NM_LINK_TYPE_OLPC_MESH)
- return nm_device_olpc_mesh_new (plink);
- g_assert_not_reached ();
+ return nm_device_olpc_mesh_new (iface);
+ g_return_val_if_reached (NULL);
}
NM_DEVICE_FACTORY_DECLARE_TYPES (
@@ -76,7 +82,7 @@ NM_DEVICE_FACTORY_DECLARE_TYPES (
static void
device_factory_interface_init (NMDeviceFactory *factory_iface)
{
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
factory_iface->get_supported_types = get_supported_types;
}
diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c
index 49b0b0af53..863c5828fe 100644
--- a/src/devices/wwan/nm-wwan-factory.c
+++ b/src/devices/wwan/nm-wwan-factory.c
@@ -96,9 +96,14 @@ NM_DEVICE_FACTORY_DECLARE_TYPES (
)
static NMDevice *
-new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore, GError **error)
+create_device (NMDeviceFactory *factory,
+ const char *iface,
+ NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
{
- g_warn_if_fail (plink->type == NM_LINK_TYPE_WWAN_ETHERNET);
+ g_return_val_if_fail (plink, NULL);
+ g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_ETHERNET, NULL);
*out_ignore = TRUE;
return NULL;
}
@@ -126,7 +131,7 @@ static void
device_factory_interface_init (NMDeviceFactory *factory_iface)
{
factory_iface->get_supported_types = get_supported_types;
- factory_iface->new_link = new_link;
+ factory_iface->create_device = create_device;
factory_iface->start = start;
}
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 7d1d2b3ca5..c2188b9ce0 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1032,11 +1032,13 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface);
- device = nm_device_factory_create_virtual_device_for_connection (factory,
- connection,
- parent,
- error);
+ device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, error);
if (device) {
+ if (!nm_device_create_and_realize (device, connection, parent, error)) {
+ g_clear_object (&device);
+ goto out;
+ }
+
if (nm_owned)
nm_device_set_nm_owned (device);
@@ -1045,6 +1047,9 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError
*/
add_device (self, device, !nm_owned);
+ /* Add device takes a reference that NMManager still owns, so it's
+ * safe to unref here and still return @device.
+ */
g_object_unref (device);
}
@@ -1837,7 +1842,15 @@ factory_device_added_cb (NMDeviceFactory *factory,
NMDevice *device,
gpointer user_data)
{
- add_device (NM_MANAGER (user_data), device, TRUE);
+ GError *error = NULL;
+
+ if (nm_device_realize (device, NULL, &error))
+ add_device (NM_MANAGER (user_data), device, TRUE);
+ else {
+ nm_log_warn (LOGD_DEVICE, "(%s): failed to realize device: %s",
+ nm_device_get_iface (device), error->message);
+ g_error_free (error);
+ }
}
static gboolean
@@ -1885,7 +1898,7 @@ platform_link_added (NMManager *self,
if (factory) {
gboolean ignore = FALSE;
- device = nm_device_factory_new_link (factory, plink, &ignore, &error);
+ device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
if (!device) {
if (!ignore) {
nm_log_warn (LOGD_HW, "%s: factory failed to create device: %s",
@@ -1893,6 +1906,11 @@ platform_link_added (NMManager *self,
g_clear_error (&error);
}
return;
+ } else if (!nm_device_realize (device, plink, &error)) {
+ nm_log_warn (LOGD_HW, "%s: factory failed to create device: %s",
+ plink->name, error->message);
+ g_clear_error (&error);
+ return;
}
}