mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-03-04 17:40:33 +01:00
core: split device creation and device setup (bgo #737458)
Future patches will create devices long before they are backed by kernel resources, so we need to split NMDevice object creation from actual setup based on the backing resources. This patch combines the NMDeviceFactory's new_link() and create_virtual_device_for_connection() class methods into a single create_device() method that simply creates an unrealized NMDevice object; this method is not expected to fail unless the device is supposed to be ignored. This also means that the NMDevice 'platform-device' property is removed, because a platform link object may not be available at NMDevice object creation time. After the device is created, it is then "realized" at some later time from a platform link (for existing/hardware devices via the realize() method) or from an NMConnection (for newly created software devices via the create_and_realize() NMDeviceClass methods). https://bugzilla.gnome.org/show_bug.cgi?id=737458
This commit is contained in:
parent
cf455aa0e2
commit
e8139f56c2
29 changed files with 827 additions and 747 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
create_device (NMDeviceFactory *factory,
|
||||
const char *iface,
|
||||
NMPlatformLink *plink,
|
||||
NMConnection *connection,
|
||||
gboolean *out_ignore)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
create_device (NMDeviceFactory *factory,
|
||||
const char *iface,
|
||||
NMPlatformLink *plink,
|
||||
NMConnection *connection,
|
||||
gboolean *out_ignore)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
if (plink) {
|
||||
g_return_val_if_fail (strcmp (iface, plink->name) == 0, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
} else if (connection) {
|
||||
for (i = 0; setting_types && setting_types[i]; i++) {
|
||||
if (nm_connection_is_type (connection, setting_types[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
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->new_link) {
|
||||
if (!interface->create_device) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
|
||||
interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
|
||||
if (!interface->create_virtual_device_for_connection) {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
|
||||
"Device factory %s cannot create virtual 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 *
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -113,22 +128,6 @@ nm_device_generic_init (NMDeviceGeneric *self)
|
|||
nm_device_set_initial_unmanaged_flag (NM_DEVICE (self), NM_UNMANAGED_DEFAULT, TRUE);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
create_device (NMDeviceFactory *factory,
|
||||
const char *iface,
|
||||
NMPlatformLink *plink,
|
||||
NMConnection *connection,
|
||||
gboolean *out_ignore)
|
||||
{
|
||||
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);
|
||||
}
|
||||
gboolean is_partition = FALSE;
|
||||
|
||||
static NMDevice *
|
||||
create_virtual_device_for_connection (NMDeviceFactory *factory,
|
||||
NMConnection *connection,
|
||||
NMDevice *parent,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingInfiniband *s_infiniband;
|
||||
int p_key, parent_ifindex;
|
||||
const char *iface;
|
||||
NMPlatformError plerr;
|
||||
if (plink)
|
||||
is_partition = (plink->parent > 0);
|
||||
else if (connection) {
|
||||
NMSettingInfiniband *s_infiniband;
|
||||
|
||||
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;
|
||||
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;
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
|
@ -115,37 +121,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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -458,54 +554,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)
|
||||
create_device (NMDeviceFactory *factory,
|
||||
const char *iface,
|
||||
NMPlatformLink *plink,
|
||||
NMConnection *connection,
|
||||
gboolean *out_ignore)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,17 @@ link_changed (NMDevice *device, NMPlatformLink *info)
|
|||
update_properties (device);
|
||||
}
|
||||
|
||||
static void
|
||||
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
|
||||
|
|
@ -138,14 +149,6 @@ nm_device_vxlan_init (NMDeviceVxlan *self)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constructed (GObject *object)
|
||||
{
|
||||
update_properties (NM_DEVICE (object));
|
||||
|
||||
G_OBJECT_CLASS (nm_device_vxlan_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
|
|
@ -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;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -9392,12 +9467,6 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
klass->get_ip_iface_identifier = get_ip_iface_identifier;
|
||||
|
||||
/* 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, "", "",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -669,38 +669,34 @@ release_slave (NMDevice *device,
|
|||
return success;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
NMDevice *
|
||||
nm_device_team_new (NMPlatformLink *platform_device)
|
||||
static gboolean
|
||||
create_and_realize (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
NMDevice *parent,
|
||||
NMPlatformLink *out_plink,
|
||||
GError **error)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue