diff --git a/include/NetworkManager.h b/include/NetworkManager.h index d45ad07b3..737ecc802 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -53,6 +53,7 @@ #define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond" #define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan" #define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge" +#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic" #define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" @@ -98,6 +99,7 @@ typedef enum { /** * NMDeviceType: * @NM_DEVICE_TYPE_UNKNOWN: unknown device + * @NM_DEVICE_TYPE_GENERIC: generic support for unrecognized device types * @NM_DEVICE_TYPE_ETHERNET: a wired ethernet device * @NM_DEVICE_TYPE_WIFI: an 802.11 WiFi device * @NM_DEVICE_TYPE_UNUSED1: not used @@ -131,6 +133,7 @@ typedef enum { NM_DEVICE_TYPE_VLAN = 11, NM_DEVICE_TYPE_ADSL = 12, NM_DEVICE_TYPE_BRIDGE = 13, + NM_DEVICE_TYPE_GENERIC = 14, } NMDeviceType; /** diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 3850a2346..82e9fba8d 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -15,6 +15,7 @@ EXTRA_DIST = \ nm-device-bond.xml \ nm-device-bridge.xml \ nm-device-vlan.xml \ + nm-device-generic.xml \ nm-device.xml \ nm-ip4-config.xml \ nm-ip6-config.xml \ diff --git a/introspection/nm-device-generic.xml b/introspection/nm-device-generic.xml new file mode 100644 index 000000000..7cd3d1afc --- /dev/null +++ b/introspection/nm-device-generic.xml @@ -0,0 +1,21 @@ + + + + + + + + Hardware address of the device. + + + + + + + A dictionary mapping property names to variant boxed values + + + + + + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 7f6ee1b33..974cc0d28 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -66,6 +66,7 @@ libnminclude_HEADERS = \ nm-device-bond.h \ nm-device-bridge.h \ nm-device-vlan.h \ + nm-device-generic.h \ nm-access-point.h \ nm-ip4-config.h \ nm-device-modem.h \ @@ -102,6 +103,7 @@ libnm_glib_la_csources = \ nm-device-bond.c \ nm-device-bridge.c \ nm-device-vlan.c \ + nm-device-generic.c \ nm-access-point.c \ nm-ip4-config.c \ nm-device-modem.c \ diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 1848171e6..d066067cf 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -102,6 +102,10 @@ global: nm_device_ethernet_get_type; nm_device_ethernet_new; nm_device_filter_connections; + nm_device_generic_error_get_type; + nm_device_generic_error_quark; + nm_device_generic_get_hw_address; + nm_device_generic_get_type; nm_device_get_active_connection; nm_device_get_autoconnect; nm_device_get_available_connections; diff --git a/libnm-glib/nm-device-generic.c b/libnm-glib/nm-device-generic.c new file mode 100644 index 000000000..170b9b8fd --- /dev/null +++ b/libnm-glib/nm-device-generic.c @@ -0,0 +1,246 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include + +#include + +#include "nm-device-generic.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-setting-generic.h" + +G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericPrivate)) + +typedef struct { + DBusGProxy *proxy; + + char *hw_address; +} NMDeviceGenericPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + + LAST_PROP +}; + +#define DBUS_PROP_HW_ADDRESS "HwAddress" + +/** + * nm_device_generic_error_quark: + * + * Registers an error quark for #NMDeviceGeneric if necessary. + * + * Returns: the error quark used for #NMDeviceGeneric errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_device_generic_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("nm-device-generic-error-quark"); + return quark; +} + +/** + * nm_device_generic_new: + * @connection: the #DBusGConnection + * @path: the DBus object path of the device + * + * Creates a new #NMDeviceGeneric. + * + * Returns: (transfer full): a new device + * + * Since: 0.9.10 + **/ +GObject * +nm_device_generic_new (DBusGConnection *connection, const char *path) +{ + GObject *device; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + device = g_object_new (NM_TYPE_DEVICE_GENERIC, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); + _nm_object_ensure_inited (NM_OBJECT (device)); + return device; +} + +/** + * nm_device_generic_get_hw_address: + * @device: a #NMDeviceGeneric + * + * Gets the hardware address of the #NMDeviceGeneric + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_generic_get_hw_address (NMDeviceGeneric *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_GENERIC (device), NULL); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GENERIC_GET_PRIVATE (device)->hw_address; +} + +/***********************************************************/ + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + const char *ctype, *iface_name; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + ctype = nm_setting_connection_get_connection_type (s_con); + if (strcmp (ctype, NM_SETTING_GENERIC_SETTING_NAME) != 0) { + g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION, + "The connection was not a generic connection."); + return FALSE; + } + + iface_name = nm_setting_connection_get_interface_name (s_con); + if (!iface_name) { + g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME, + "The connection did not specify an interface name."); + return FALSE; + } + + return NM_DEVICE_CLASS (nm_device_generic_parent_class)->connection_compatible (device, connection, error); +} + +/***********************************************************/ + +static void +nm_device_generic_init (NMDeviceGeneric *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_GENERIC); +} + +static void +register_properties (NMDeviceGeneric *device) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (device); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_GENERIC_HW_ADDRESS, &priv->hw_address }, + { NULL }, + }; + + _nm_object_register_properties (NM_OBJECT (device), + priv->proxy, + property_info); +} + +static void +constructed (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->constructed (object); + + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_GENERIC); + register_properties (NM_DEVICE_GENERIC (object)); +} + +static void +dispose (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + g_clear_object (&priv->proxy); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + _nm_object_ensure_inited (NM_OBJECT (object)); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, priv->hw_address); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_generic_class_init (NMDeviceGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + device_class->connection_compatible = connection_compatible; + + /** + * NMDeviceGeneric:hw-address: + * + * The hardware address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, + "Hardware Address", + "Hardware address", + NULL, + G_PARAM_READABLE)); +} + diff --git a/libnm-glib/nm-device-generic.h b/libnm-glib/nm-device-generic.h new file mode 100644 index 000000000..492e3c598 --- /dev/null +++ b/libnm-glib/nm-device-generic.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_GENERIC_H +#define NM_DEVICE_GENERIC_H + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) +#define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) + +/** + * NMDeviceGenericError: + * @NM_DEVICE_GENERIC_ERROR_UNKNOWN: unknown or unclassified error + * @NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION: the connection was not of generic type + * @NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME: the connection did not specify the interface name + */ +typedef enum { + NM_DEVICE_GENERIC_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION, /*< nick=NotGenericConnection >*/ + NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME, /*< nick=MissingInterfaceName >*/ +} NMDeviceGenericError; + +#define NM_DEVICE_GENERIC_ERROR nm_device_generic_error_quark () +GQuark nm_device_generic_error_quark (void); + +#define NM_DEVICE_GENERIC_HW_ADDRESS "hw-address" + +typedef struct { + NMDevice parent; +} NMDeviceGeneric; + +typedef struct { + NMDeviceClass parent; + + /* Padding for future expansion */ + void (*_reserved1) (void); + void (*_reserved2) (void); + void (*_reserved3) (void); + void (*_reserved4) (void); + void (*_reserved5) (void); + void (*_reserved6) (void); +} NMDeviceGenericClass; + +GType nm_device_generic_get_type (void); + +GObject *nm_device_generic_new (DBusGConnection *connection, const char *path); + +const char *nm_device_generic_get_hw_address (NMDeviceGeneric *device); + +G_END_DECLS + +#endif /* NM_DEVICE_GENERIC_H */ diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index d952914b5..cda3a2638 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -37,6 +37,7 @@ #include "nm-device-bond.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" +#include "nm-device-generic.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-object-private.h" @@ -301,6 +302,8 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype) return NM_TYPE_DEVICE_BRIDGE; case NM_DEVICE_TYPE_VLAN: return NM_TYPE_DEVICE_VLAN; + case NM_DEVICE_TYPE_GENERIC: + return NM_TYPE_DEVICE_GENERIC; default: g_warning ("Unknown device type %d", dtype); return G_TYPE_INVALID; diff --git a/src/Makefile.am b/src/Makefile.am index 113b52760..b2162d788 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -149,6 +149,8 @@ NetworkManager_SOURCES = \ nm-device-bridge.h \ nm-device-vlan.c \ nm-device-vlan.h \ + nm-device-generic.c \ + nm-device-generic.h \ nm-wifi-ap.c \ nm-wifi-ap.h \ nm-wifi-ap-utils.c \ @@ -276,6 +278,9 @@ nm-dhcp6-config-glue.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml nm-device-modem-glue.h: $(top_srcdir)/introspection/nm-device-modem.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_modem --mode=glib-server --output=$@ $< +nm-device-generic-glue.h: $(top_srcdir)/introspection/nm-device-generic.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_generic --mode=glib-server --output=$@ $< + BUILT_SOURCES = \ nm-access-point-glue.h \ nm-manager-glue.h \ @@ -290,6 +295,7 @@ BUILT_SOURCES = \ nm-device-olpc-mesh-glue.h \ nm-device-bt-glue.h \ nm-device-modem-glue.h \ + nm-device-generic-glue.h \ nm-ip4-config-glue.h \ nm-ip6-config-glue.h \ nm-active-connection-glue.h \ diff --git a/src/nm-device-generic.c b/src/nm-device-generic.c new file mode 100644 index 000000000..043de7eaf --- /dev/null +++ b/src/nm-device-generic.c @@ -0,0 +1,145 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-device-generic.h" +#include "nm-device-private.h" +#include "nm-enum-types.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" + +#include "nm-device-generic-glue.h" + +G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericPrivate)) + +typedef struct { + int dummy; +} NMDeviceGenericPrivate; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +#define NM_DEVICE_GENERIC_ERROR (nm_device_generic_error_quark ()) + +static GQuark +nm_device_generic_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-device-generic-error"); + return quark; +} + +/**************************************************************/ + +static guint32 +get_generic_capabilities (NMDevice *dev) +{ + return NM_DEVICE_CAP_NM_SUPPORTED; +} + +static gboolean +is_available (NMDevice *device) +{ + return TRUE; +} + +static gboolean +check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + NMSettingConnection *s_con; + + if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->check_connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_GENERIC_SETTING_NAME)) { + g_set_error (error, + NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_CONNECTION_NOT_GENERIC, + "The connection was not a generic connection."); + return FALSE; + } + + s_con = nm_connection_get_setting_connection (connection); + if (!nm_setting_connection_get_interface_name (s_con)) { + g_set_error (error, + NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_CONNECTION_INVALID, + "The connection did not specify an interface name."); + return FALSE; + } + + return TRUE; +} + +/**************************************************************/ + +NMDevice * +nm_device_generic_new (const char *udi, + const char *iface, + const char *driver) +{ + g_return_val_if_fail (udi != NULL, NULL); + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GENERIC, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, driver, + NM_DEVICE_TYPE_DESC, "Generic", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); +} + +static void +nm_device_generic_init (NMDeviceGeneric *self) +{ + nm_device_set_default_unmanaged (NM_DEVICE (self), TRUE); +} + +static void +nm_device_generic_class_init (NMDeviceGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); + + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->is_available = is_available; + parent_class->check_connection_compatible = check_connection_compatible; + + /* signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDeviceGenericClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_generic_object_info); + + dbus_g_error_domain_register (NM_DEVICE_GENERIC_ERROR, NULL, NM_TYPE_DEVICE_GENERIC_ERROR); +} diff --git a/src/nm-device-generic.h b/src/nm-device-generic.h new file mode 100644 index 000000000..5c21c8ab2 --- /dev/null +++ b/src/nm-device-generic.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_GENERIC_H +#define NM_DEVICE_GENERIC_H + +#include + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) +#define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) + +typedef enum +{ + NM_DEVICE_GENERIC_ERROR_CONNECTION_NOT_GENERIC = 0, /*< nick=ConnectionNotGeneric >*/ + NM_DEVICE_GENERIC_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_DEVICE_GENERIC_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ +} NMDeviceGenericError; + +#define NM_DEVICE_GENERIC_HW_ADDRESS "hw-address" + +typedef struct { + NMDevice parent; +} NMDeviceGeneric; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*properties_changed) (NMDeviceGeneric *device, GHashTable *properties); +} NMDeviceGenericClass; + +GType nm_device_generic_get_type (void); + +NMDevice *nm_device_generic_new (const char *udi, + const char *iface, + const char *driver); + +G_END_DECLS + +#endif /* NM_DEVICE_GENERIC_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index a82d741ad..ef43496ef 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -50,6 +50,7 @@ #include "nm-device-bridge.h" #include "nm-device-vlan.h" #include "nm-device-adsl.h" +#include "nm-device-generic.h" #include "nm-system.h" #include "nm-properties-changed-signal.h" #include "nm-setting-bluetooth.h" @@ -2192,7 +2193,6 @@ udev_device_added_cb (NMUdevManager *udev_mgr, g_return_if_fail (udev_device != NULL); g_return_if_fail (iface != NULL); g_return_if_fail (sysfs_path != NULL); - g_return_if_fail (driver != NULL); /* Most devices will have an ifindex here */ if (ifindex > 0) { @@ -2232,6 +2232,9 @@ udev_device_added_cb (NMUdevManager *udev_mgr, } } + if (device == NULL && driver == NULL) + device = nm_device_generic_new (sysfs_path, iface, driver); + if (device == NULL) { if (is_olpc_mesh (udev_device)) /* must be before is_wireless */ device = nm_device_olpc_mesh_new (sysfs_path, iface, driver); @@ -2267,10 +2270,25 @@ udev_device_added_cb (NMUdevManager *udev_mgr, } } else nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", iface); - } else if (is_adsl (udev_device)) + } else if (is_adsl (udev_device)) { device = nm_device_adsl_new (sysfs_path, iface, driver); - else - device = nm_device_ethernet_new (sysfs_path, iface, driver); + } else { + gint etype; + gboolean is_ctc; + + /* For anything else, if it uses Ethernet encapsulation, consider it + * an Ethernet device. (But some s390 CTC-type devices report 256 for + * some reason, and we need to call them Ethernet too. FIXME: use + * something other than interface name to detect CTC here.) + */ + etype = g_udev_device_get_sysfs_attr_as_int (udev_device, "type"); + is_ctc = g_str_has_prefix (iface, "ctc") && (etype == 256); + + if (etype == ARPHRD_ETHER || is_ctc) + device = nm_device_ethernet_new (sysfs_path, iface, driver); + else + device = nm_device_generic_new (sysfs_path, iface, driver); + } } if (device) diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index a48534958..38b67a2ff 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -353,7 +353,6 @@ dev_get_attrs (GUdevDevice *udev_device, GUdevDevice *parent = NULL, *grandparent = NULL; const char *ifname, *driver, *path, *subsys; gint ifindex = -1; - gboolean success = FALSE; g_return_val_if_fail (udev_device != NULL, FALSE); g_return_val_if_fail (out_ifname != NULL, FALSE); @@ -414,36 +413,27 @@ dev_get_attrs (GUdevDevice *udev_device, driver = "easytether"; break; } - - if (!driver) { - nm_log_warn (LOGD_HW, "%s: couldn't determine device driver; ignoring...", path); - goto out; - } } *out_ifname = ifname; *out_path = path; *out_driver = g_strdup (driver); *out_ifindex = ifindex; - success = TRUE; -out: if (grandparent) g_object_unref (grandparent); if (parent) g_object_unref (parent); - return success; + return TRUE; } static void net_add (NMUdevManager *self, GUdevDevice *udev_device) { gint ifindex = -1; - gint etype; const char *ifname = NULL, *path = NULL, *tmp; char *driver = NULL; - gboolean is_ctc; g_return_if_fail (udev_device != NULL); @@ -455,18 +445,6 @@ net_add (NMUdevManager *self, GUdevDevice *udev_device) goto out; } - etype = g_udev_device_get_sysfs_attr_as_int (udev_device, "type"); - is_ctc = (strncmp (ifname, "ctc", 3) == 0) && (etype == 256); - - /* Ignore devices that don't report Ethernet encapsulation, except for - * s390 CTC-type devices that report 256 for some reason. - * FIXME: use something other than interface name to detect CTC here. - */ - if ((etype != ARPHRD_ETHER) && (etype != ARPHRD_INFINIBAND) && (is_ctc == FALSE)) { - nm_log_dbg (LOGD_HW, "(%s): ignoring interface with type %d", ifname, etype); - goto out; - } - /* Not all ethernet devices are immediately usable; newer mobile broadband * devices (Ericsson, Option, Sierra) require setup on the tty before the * ethernet device is usable. 2.6.33 and later kernels set the 'DEVTYPE'