diff options
| author | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
| commit | 2c032d8f1c6292c1338a615e6ec40252889ba85c (patch) | |
| tree | 1f77182220b2b0264288ba4a476ab47e5bc48716 /src/devices | |
| parent | 33491bc4279481db8ae47213e34a6d695a0e8830 (diff) | |
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/devices')
118 files changed, 8439 insertions, 7104 deletions
diff --git a/src/devices/adsl/Makefile.am b/src/devices/adsl/Makefile.am index 0430f47d..07a8f9ee 100644 --- a/src/devices/adsl/Makefile.am +++ b/src/devices/adsl/Makefile.am @@ -5,20 +5,15 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/ppp-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(GUDEV_CFLAGS) GLIB_GENERATED = nm-adsl-enum-types.h nm-adsl-enum-types.c diff --git a/src/devices/adsl/Makefile.in b/src/devices/adsl/Makefile.in index 708a45d2..7942c559 100644 --- a/src/devices/adsl/Makefile.in +++ b/src/devices/adsl/Makefile.in @@ -217,6 +217,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -340,6 +342,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -359,6 +362,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -385,7 +389,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -467,20 +471,15 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/ppp-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(GUDEV_CFLAGS) GLIB_GENERATED = nm-adsl-enum-types.h nm-adsl-enum-types.c diff --git a/src/devices/adsl/exports.ver b/src/devices/adsl/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/adsl/exports.ver +++ b/src/devices/adsl/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index e8db3596..6f34c02b 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -18,7 +18,7 @@ * Copyright (C) 2009 - 2013 Red Hat, Inc. */ -#include <config.h> +#include "config.h" #include <string.h> #include <gudev/gudev.h> @@ -28,11 +28,11 @@ #include "nm-device-adsl.h" #include "nm-device-factory.h" #include "nm-logging.h" +#include "nm-glib-compat.h" typedef struct { GUdevClient *client; GSList *devices; - guint start_id; } NMAtmManagerPrivate; #define NM_ATM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ATM_MANAGER, NMAtmManagerPrivate)) @@ -46,20 +46,12 @@ G_DEFINE_TYPE_EXTENDED (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_ADSL - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_ATM_MANAGER, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ static gboolean @@ -163,9 +155,10 @@ adsl_remove (NMAtmManager *self, GUdevDevice *udev_device) } } -static gboolean -query_devices (NMAtmManager *self) +static void +start (NMDeviceFactory *factory) { + NMAtmManager *self = NM_ATM_MANAGER (factory); NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); GUdevEnumerator *enumerator; GList *devices, *iter; @@ -180,8 +173,6 @@ query_devices (NMAtmManager *self) } g_list_free (devices); g_object_unref (enumerator); - - return G_SOURCE_REMOVE; } static void @@ -212,6 +203,12 @@ handle_uevent (GUdevClient *client, adsl_remove (self, device); } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_ADSL; +} + /*********************************************************************/ static void @@ -222,13 +219,13 @@ nm_atm_manager_init (NMAtmManager *self) priv->client = g_udev_client_new (subsys); g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); - - priv->start_id = g_idle_add ((GSourceFunc) query_devices, self); } static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void @@ -242,11 +239,6 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_func (priv->client, handle_uevent, self); g_clear_object (&priv->client); - if (priv->start_id) { - g_source_remove (priv->start_id); - priv->start_id = 0; - } - for (iter = priv->devices; iter; iter = iter->next) g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); g_clear_pointer (&priv->devices, g_slist_free); diff --git a/src/devices/adsl/nm-atm-manager.h b/src/devices/adsl/nm-atm-manager.h index 00525220..e4ec3e6a 100644 --- a/src/devices/adsl/nm-atm-manager.h +++ b/src/devices/adsl/nm-atm-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_ATM_MANAGER_H -#define NM_ATM_MANAGER_H +#ifndef __NETWORKMANAGER_ATM_MANAGER_H__ +#define __NETWORKMANAGER_ATM_MANAGER_H__ #include <glib.h> #include <glib-object.h> @@ -38,5 +38,5 @@ typedef struct { GObjectClass parent; } NMAtmManagerClass; -#endif /* NM_ATM_MANAGER_H */ +#endif /* __NETWORKMANAGER_ATM_MANAGER_H__ */ diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 0c35bb7a..e664ff48 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -18,7 +18,7 @@ * Pantelis Koukousoulas <pktoss@gmail.com> */ -#include <config.h> +#include "config.h" #include <sys/socket.h> #include <linux/atmdev.h> @@ -44,9 +44,13 @@ #include "ppp-manager/nm-ppp-manager.h" #include "nm-setting-adsl.h" +#include "nm-utils.h" #include "nm-device-adsl-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF (NMDeviceAdsl); + G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) #define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate)) @@ -72,7 +76,9 @@ typedef struct { static guint32 get_generic_capabilities (NMDevice *dev) { - return (NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER); + return ( NM_DEVICE_CAP_CARRIER_DETECT + | NM_DEVICE_CAP_NONSTANDARD_CARRIER + | NM_DEVICE_CAP_IS_NON_KERNEL); } static gboolean @@ -119,7 +125,8 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, NM_SETTING_ADSL_SETTING_NAME, existing_connections, - _("ADSL connection %d"), + NULL, + _("ADSL connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -142,18 +149,14 @@ set_nas_iface (NMDeviceAdsl *self, int idx, const char *name) g_warn_if_fail (priv->nas_ifname == NULL); priv->nas_ifname = g_strdup (name); - - /* Update NAS interface's MAC address */ - nm_device_update_hw_address (NM_DEVICE (self)); } static gboolean br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); struct atm_newif_br2684 ni; - int err, fd; + int err, fd, errsv; gboolean success = FALSE; guint num = 0; @@ -161,8 +164,8 @@ br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); if (fd < 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to open ATM control socket (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); return FALSE; } @@ -183,17 +186,19 @@ br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) err = ioctl (fd, ATM_NEWBACKENDIF, &ni); if (err == 0) { set_nas_iface (self, -1, ni.ifname); - nm_log_info (LOGD_ADSL, "(%s): using NAS interface %s (%d)", - iface, priv->nas_ifname, priv->nas_ifindex); + _LOGI (LOGD_ADSL, "using NAS interface %s (%d)", + priv->nas_ifname, priv->nas_ifindex); success = TRUE; break; - } else if (errno == -EEXIST) { - /* Try again */ - num++; } else { - nm_log_warn (LOGD_ADSL, "(%s): failed to create br2684 interface (%d)", - iface, errno); - break; + errsv = errno; + if (errsv == -EEXIST) { + /* Try again */ + num++; + } else { + _LOGW (LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); + break; + } } } @@ -205,11 +210,10 @@ static gboolean br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); struct sockaddr_atmpvc addr; struct atm_backend_br2684 be; struct atm_qos qos; - int err, bufsize = 8192; + int errsv, err, bufsize = 8192; const char *encapsulation; gboolean is_llc; @@ -218,15 +222,15 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); if (priv->brfd < 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to open ATM control socket (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); return FALSE; } err = setsockopt (priv->brfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof (bufsize)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set SNDBUF option (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set SNDBUF option (%d)", errsv); goto error; } @@ -240,8 +244,8 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) err = setsockopt (priv->brfd, SOL_ATM, SO_ATMQOS, &qos, sizeof (qos)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set QoS (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set QoS (%d)", errsv); goto error; } @@ -254,15 +258,14 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) addr.sap_addr.vpi = (guint16) nm_setting_adsl_get_vpi (s_adsl); addr.sap_addr.vci = (int) nm_setting_adsl_get_vci (s_adsl); - nm_log_dbg (LOGD_ADSL, "(%s): assigning address %d.%d.%d encapsulation %s", - nm_device_get_iface (NM_DEVICE (self)), - priv->atm_index, addr.sap_addr.vpi, addr.sap_addr.vci, - encapsulation); + _LOGD (LOGD_ADSL, "assigning address %d.%d.%d encapsulation %s", + priv->atm_index, addr.sap_addr.vpi, addr.sap_addr.vci, + encapsulation ? encapsulation : "(none)"); err = connect (priv->brfd, (struct sockaddr*) &addr, sizeof (addr)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set VPI/VCI (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set VPI/VCI (%d)", errsv); goto error; } @@ -278,8 +281,8 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) be.encaps = is_llc ? BR2684_ENCAPS_LLC : BR2684_ENCAPS_VC; err = ioctl (priv->brfd, ATM_SETBACKEND, &be); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to attach VCC (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to attach VCC (%d)", errsv); goto error; } @@ -292,18 +295,17 @@ error: } static void -link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDeviceAdsl *device_adsl) +link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDeviceAdsl *self) { if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (device_adsl); - NMDevice *device = NM_DEVICE (device_adsl); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); /* This only gets called for PPPoE connections and "nas" interfaces */ if (priv->nas_ifindex >= 0 && ifindex == priv->nas_ifindex) { /* NAS device went away for some reason; kill the connection */ - nm_log_dbg (LOGD_ADSL, "(%s): NAS interface disappeared", - nm_device_get_iface (device)); + _LOGD (LOGD_ADSL, "NAS interface disappeared"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BR2684_FAILED); @@ -326,8 +328,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) g_assert (s_adsl); protocol = nm_setting_adsl_get_protocol (s_adsl); - nm_log_dbg (LOGD_ADSL, "(%s): using ADSL protocol '%s'", - nm_device_get_iface (device), protocol); + _LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol); if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) { @@ -348,7 +349,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) G_CALLBACK (link_changed_cb), self); - nm_log_dbg (LOGD_ADSL, "(%s): ATM setup successful", nm_device_get_iface (device)); + _LOGD (LOGD_ADSL, "ATM setup successful"); /* otherwise we're good for stage3 */ nm_platform_link_set_up (priv->nas_ifindex); @@ -357,10 +358,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) } else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) { /* PPPoA doesn't need anything special */ ret = NM_ACT_STAGE_RETURN_SUCCESS; - } else { - nm_log_warn (LOGD_ADSL, "(%s): unhandled ADSL protocol '%s'", - nm_device_get_iface (device), protocol); - } + } else + _LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol); done: return ret; @@ -410,7 +409,6 @@ act_stage3_ip4_config_start (NMDevice *device, NMActRequest *req; GError *err = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - const char *iface = nm_device_get_iface (device); const char *ppp_iface; req = nm_device_get_act_request (device); @@ -427,11 +425,10 @@ act_stage3_ip4_config_start (NMDevice *device, g_assert (priv->nas_ifname); ppp_iface = priv->nas_ifname; - nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoE on NAS interface %s", - iface, priv->nas_ifname); + _LOGD (LOGD_ADSL, "starting PPPoE on NAS interface %s", priv->nas_ifname); } else { - ppp_iface = iface; - nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoA", iface); + ppp_iface = nm_device_get_iface (device); + _LOGD (LOGD_ADSL, "starting PPPoA"); } priv->ppp_manager = nm_ppp_manager_new (ppp_iface); @@ -444,7 +441,7 @@ act_stage3_ip4_config_start (NMDevice *device, self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { - nm_log_warn (LOGD_ADSL, "(%s): PPP failed to start: %s", iface, err->message); + _LOGW (LOGD_ADSL, "PPP failed to start: %s", err->message); g_error_free (err); g_object_unref (priv->ppp_manager); @@ -482,33 +479,19 @@ deactivate (NMDevice *device) priv->nas_ifindex = -1; g_free (priv->nas_ifname); priv->nas_ifname = NULL; - - /* Poke NMDevice to notice that our hw_address is no longer valid */ - nm_device_update_hw_address (NM_DEVICE (self)); } /**************************************************************/ -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) -{ - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (device); - - return priv->nas_ifname ? ETH_ALEN : 0; -} - static gboolean carrier_update_cb (gpointer user_data) { NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data); int carrier; char *path; - const char *iface; - - iface = nm_device_get_iface (NM_DEVICE (self)); path = g_strdup_printf ("/sys/class/atm/%s/carrier", - ASSERT_VALID_PATH_COMPONENT (iface)); + ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); carrier = (int) nm_platform_sysctl_get_int_checked (path, 10, 0, 1, -1); g_free (path); @@ -555,6 +538,7 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; + NMDeviceAdsl *self; NMDeviceAdslPrivate *priv; object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type, @@ -563,18 +547,16 @@ constructor (GType type, if (!object) return NULL; + self = NM_DEVICE_ADSL (object); priv = NM_DEVICE_ADSL_GET_PRIVATE (object); priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object))); if (priv->atm_index < 0) { - nm_log_err (LOGD_ADSL, "(%s): error reading ATM device index", - nm_device_get_iface (NM_DEVICE (object))); + _LOGE (LOGD_ADSL, "error reading ATM device index"); g_object_unref (object); return NULL; - } else { - nm_log_dbg (LOGD_ADSL, "(%s): ATM device index %d", - nm_device_get_iface (NM_DEVICE (object)), priv->atm_index); - } + } else + _LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index); /* Poll the carrier */ priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, object); @@ -629,7 +611,6 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; - parent_class->get_hw_address_length = get_hw_address_length; parent_class->act_stage2_config = act_stage2_config; parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; parent_class->deactivate = deactivate; diff --git a/src/devices/adsl/nm-device-adsl.h b/src/devices/adsl/nm-device-adsl.h index bbd0e63f..f21381c2 100644 --- a/src/devices/adsl/nm-device-adsl.h +++ b/src/devices/adsl/nm-device-adsl.h @@ -19,8 +19,8 @@ * Copyright (C) 2009 - 2011 Red Hat Inc. */ -#ifndef NM_DEVICE_ADSL_H -#define NM_DEVICE_ADSL_H +#ifndef __NETWORKMANAGER_DEVICE_ADSL_H__ +#define __NETWORKMANAGER_DEVICE_ADSL_H__ #include <glib-object.h> diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am index 639a1ad7..8ab561ac 100644 --- a/src/devices/bluetooth/Makefile.am +++ b/src/devices/bluetooth/Makefile.am @@ -5,26 +5,22 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/devices/wwan \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h +nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml dbus-binding-tool --prefix=nm_device_bt --mode=glib-server --output=$@ $< @@ -47,6 +43,8 @@ libnm_device_plugin_bluetooth_la_SOURCES = \ nm-bluez4-manager.h \ nm-bluez5-manager.c \ nm-bluez5-manager.h \ + nm-bt-error.h \ + nm-bt-error.c \ \ nm-device-bt.c \ nm-device-bt.h \ @@ -62,6 +60,16 @@ libnm_device_plugin_bluetooth_la_LIBADD = \ $(DBUS_LIBS) \ $(GUDEV_LIBS) +if WITH_BLUEZ5_DUN +AM_CPPFLAGS += $(BLUEZ5_CFLAGS) + +libnm_device_plugin_bluetooth_la_SOURCES += \ + nm-bluez5-dun.c \ + nm-bluez5-dun.h + +libnm_device_plugin_bluetooth_la_LIBADD += $(BLUEZ5_LIBS) +endif + CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = $(SYMBOL_VIS_FILE) diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in index 3145c52d..0a285fda 100644 --- a/src/devices/bluetooth/Makefile.in +++ b/src/devices/bluetooth/Makefile.in @@ -78,6 +78,12 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@WITH_BLUEZ5_DUN_TRUE@am__append_1 = $(BLUEZ5_CFLAGS) +@WITH_BLUEZ5_DUN_TRUE@am__append_2 = \ +@WITH_BLUEZ5_DUN_TRUE@ nm-bluez5-dun.c \ +@WITH_BLUEZ5_DUN_TRUE@ nm-bluez5-dun.h + +@WITH_BLUEZ5_DUN_TRUE@am__append_3 = $(BLUEZ5_LIBS) subdir = src/devices/bluetooth DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -131,14 +137,26 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = +@WITH_BLUEZ5_DUN_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libnm_device_plugin_bluetooth_la_DEPENDENCIES = \ $(top_builddir)/src/devices/wwan/libnm-wwan.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am__libnm_device_plugin_bluetooth_la_SOURCES_DIST = \ + nm-bluez-manager.c nm-bluez-manager.h nm-bluez-common.h \ + nm-bluez-device.c nm-bluez-device.h nm-bluez4-adapter.c \ + nm-bluez4-adapter.h nm-bluez4-manager.c nm-bluez4-manager.h \ + nm-bluez5-manager.c nm-bluez5-manager.h nm-bt-error.h \ + nm-bt-error.c nm-device-bt.c nm-device-bt.h nm-bt-enum-types.h \ + nm-bt-enum-types.c nm-device-bt-glue.h nm-bluez5-dun.c \ + nm-bluez5-dun.h am__objects_1 = nm-bt-enum-types.lo am__objects_2 = $(am__objects_1) +@WITH_BLUEZ5_DUN_TRUE@am__objects_3 = nm-bluez5-dun.lo am_libnm_device_plugin_bluetooth_la_OBJECTS = nm-bluez-manager.lo \ nm-bluez-device.lo nm-bluez4-adapter.lo nm-bluez4-manager.lo \ - nm-bluez5-manager.lo nm-device-bt.lo $(am__objects_2) + nm-bluez5-manager.lo nm-bt-error.lo nm-device-bt.lo \ + $(am__objects_2) $(am__objects_3) libnm_device_plugin_bluetooth_la_OBJECTS = \ $(am_libnm_device_plugin_bluetooth_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -184,7 +202,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES) -DIST_SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES) +DIST_SOURCES = $(am__libnm_device_plugin_bluetooth_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -219,6 +237,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -342,6 +362,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -361,6 +382,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -387,7 +409,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -466,59 +488,35 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I${top_srcdir}/src \ - -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ - -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/devices/wwan \ - -I${top_builddir}/include \ - -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ +AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src \ + -I${top_srcdir}/src/devices -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform -I${top_srcdir}/src/devices/wwan \ + -I${top_srcdir}/include -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) - + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(DBUS_CFLAGS) \ + $(am__append_1) GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h +nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h BUILT_SOURCES = $(GLIB_GENERATED) nm-device-bt-glue.h pkglib_LTLIBRARIES = libnm-device-plugin-bluetooth.la SYMBOL_VIS_FILE = $(srcdir)/exports.ver -libnm_device_plugin_bluetooth_la_SOURCES = \ - nm-bluez-manager.c \ - nm-bluez-manager.h \ - nm-bluez-common.h \ - nm-bluez-device.c \ - nm-bluez-device.h \ - nm-bluez4-adapter.c \ - nm-bluez4-adapter.h \ - nm-bluez4-manager.c \ - nm-bluez4-manager.h \ - nm-bluez5-manager.c \ - nm-bluez5-manager.h \ - \ - nm-device-bt.c \ - nm-device-bt.h \ - \ - $(BUILT_SOURCES) - +libnm_device_plugin_bluetooth_la_SOURCES = nm-bluez-manager.c \ + nm-bluez-manager.h nm-bluez-common.h nm-bluez-device.c \ + nm-bluez-device.h nm-bluez4-adapter.c nm-bluez4-adapter.h \ + nm-bluez4-manager.c nm-bluez4-manager.h nm-bluez5-manager.c \ + nm-bluez5-manager.h nm-bt-error.h nm-bt-error.c nm-device-bt.c \ + nm-device-bt.h $(BUILT_SOURCES) $(am__append_2) libnm_device_plugin_bluetooth_la_LDFLAGS = \ -module -avoid-version \ -Wl,--version-script=$(SYMBOL_VIS_FILE) -libnm_device_plugin_bluetooth_la_LIBADD = \ - $(top_builddir)/src/devices/wwan/libnm-wwan.la \ - $(DBUS_LIBS) \ - $(GUDEV_LIBS) - +libnm_device_plugin_bluetooth_la_LIBADD = \ + $(top_builddir)/src/devices/wwan/libnm-wwan.la $(DBUS_LIBS) \ + $(GUDEV_LIBS) $(am__append_3) CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = $(SYMBOL_VIS_FILE) all: $(BUILT_SOURCES) @@ -605,8 +603,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-adapter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-dun.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bt.Plo@am__quote@ .c.o: diff --git a/src/devices/bluetooth/exports.ver b/src/devices/bluetooth/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/bluetooth/exports.ver +++ b/src/devices/bluetooth/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index f80cfc2e..f0cab43b 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Red Hat, Inc. */ -#ifndef NM_BLUEZ_COMMON_H -#define NM_BLUEZ_COMMON_H +#ifndef __NETWORKMANAGER_BLUEZ_COMMON_H__ +#define __NETWORKMANAGER_BLUEZ_COMMON_H__ #include <config.h> diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 4c448a37..fe1a97bb 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -19,22 +19,24 @@ * Copyright (C) 2013 Intel Corporation. */ +#include "config.h" + #include <glib.h> #include <glib/gi18n.h> #include <gio/gio.h> #include <string.h> -#include <net/ethernet.h> -#include <netinet/ether.h> -#include "NetworkManager.h" -#include "nm-setting-bluetooth.h" +#include "nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-device.h" #include "nm-logging.h" -#include "nm-utils.h" #include "nm-settings-connection.h" +#include "NetworkManagerUtils.h" +#if WITH_BLUEZ5_DUN +#include "nm-bluez5-dun.h" +#endif G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT) @@ -55,19 +57,21 @@ typedef struct { gboolean usable; NMBluetoothCapabilities connection_bt_type; + char *adapter_address; char *address; - guint8 bin_address[ETH_ALEN]; char *name; guint32 capabilities; gboolean connected; - char *bt_iface; + char *b4_iface; +#if WITH_BLUEZ5_DUN + NMBluez5DunContext *b5_dun_context; +#endif NMConnectionProvider *provider; GSList *connections; NMConnection *pan_connection; - NMConnection *pan_connection_original; gboolean pan_connection_no_autocreate; } NMBluezDevicePrivate; @@ -156,9 +160,12 @@ nm_bluez_device_get_capabilities (NMBluezDevice *self) gboolean nm_bluez_device_get_connected (NMBluezDevice *self) { + NMBluezDevicePrivate *priv; + g_return_val_if_fail (NM_IS_BLUEZ_DEVICE (self), FALSE); - return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->connected; + priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); + return priv->connected; } static void @@ -168,7 +175,6 @@ pan_connection_check_create (NMBluezDevice *self) NMConnection *added; NMSetting *setting; char *uuid, *id; - GByteArray *bdaddr_array; GError *error = NULL; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); @@ -187,7 +193,7 @@ pan_connection_check_create (NMBluezDevice *self) /* create a new connection */ - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Setting: Connection */ uuid = nm_utils_uuid_generate (); @@ -202,29 +208,26 @@ pan_connection_check_create (NMBluezDevice *self) nm_connection_add_setting (connection, setting); /* Setting: Bluetooth */ - bdaddr_array = g_byte_array_sized_new (sizeof (priv->bin_address)); - g_byte_array_append (bdaddr_array, priv->bin_address, sizeof (priv->bin_address)); setting = nm_setting_bluetooth_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_BLUETOOTH_BDADDR, bdaddr_array, + NM_SETTING_BLUETOOTH_BDADDR, priv->address, NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, NULL); nm_connection_add_setting (connection, setting); - g_byte_array_free (bdaddr_array, TRUE); /* Setting: IPv4 */ setting = nm_setting_ip4_config_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_MAY_FAIL, FALSE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, NULL); nm_connection_add_setting (connection, setting); /* Setting: IPv6 */ setting = nm_setting_ip6_config_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); nm_connection_add_setting (connection, setting); @@ -240,9 +243,10 @@ pan_connection_check_create (NMBluezDevice *self) g_assert (connection_compatible (self, added)); g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT)); + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, TRUE); + priv->connections = g_slist_prepend (priv->connections, g_object_ref (added)); priv->pan_connection = added; - priv->pan_connection_original = connection; nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid); } else { nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %d / %s", @@ -250,8 +254,8 @@ pan_connection_check_create (NMBluezDevice *self) (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - g_object_unref (connection); } + g_object_unref (connection); g_free (id); g_free (uuid); @@ -264,13 +268,12 @@ check_emit_usable (NMBluezDevice *self) gboolean new_usable; /* only expect the supported capabilities set. */ - g_assert (priv->bluez_version != 4 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE )); - g_assert (priv->bluez_version != 5 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP )) == NM_BT_CAPABILITY_NONE )); + g_assert ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE ); new_usable = (priv->initialized && priv->capabilities && priv->name && ((priv->bluez_version == 4) || (priv->bluez_version == 5 && priv->adapter5 && priv->adapter_powered) ) && - priv->dbus_connection && priv->address); + priv->dbus_connection && priv->address && priv->adapter_address); if (!new_usable) goto END; @@ -302,7 +305,7 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection) NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); NMSettingBluetooth *s_bt; const char *bt_type; - const GByteArray *bdaddr; + const char *bdaddr; if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) return FALSE; @@ -311,14 +314,13 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection) if (!s_bt) return FALSE; - if (!priv->address) { - /* unless address is set, bin_address is not initialized. */ + if (!priv->address) return FALSE; - } + bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr || bdaddr->len != ETH_ALEN) + if (!bdaddr) return FALSE; - if (memcmp (bdaddr->data, priv->bin_address, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (bdaddr, -1, priv->address, -1)) return FALSE; bt_type = nm_setting_bluetooth_get_connection_type (s_bt); @@ -362,10 +364,8 @@ cp_connection_removed (NMConnectionProvider *provider, if (g_slist_find (priv->connections, connection)) { priv->connections = g_slist_remove (priv->connections, connection); - if (priv->pan_connection == connection) { + if (priv->pan_connection == connection) priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); - } g_object_unref (connection); check_emit_usable (self); } @@ -420,26 +420,37 @@ nm_bluez_device_disconnect (NMBluezDevice *self) { NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); GVariant *args = NULL; - const char *dbus_iface; + const char *dbus_iface = NULL; g_return_if_fail (priv->dbus_connection); - if (priv->bluez_version == 5) { - g_return_if_fail (priv->connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ5_NETWORK_INTERFACE; - } else if (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_DUN) { - /* Can't pass a NULL interface name through dbus to bluez, so just - * ignore the disconnect if the interface isn't known. - */ - if (!priv->bt_iface) - return; - - args = g_variant_new ("(s)", priv->bt_iface), - dbus_iface = BLUEZ4_SERIAL_INTERFACE; - } else { - g_return_if_fail (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ4_NETWORK_INTERFACE; - } + if (priv->connection_bt_type == NM_BT_CAPABILITY_DUN) { + if (priv->bluez_version == 4) { + /* Can't pass a NULL interface name through dbus to bluez, so just + * ignore the disconnect if the interface isn't known. + */ + if (!priv->b4_iface) + goto out; + args = g_variant_new ("(s)", priv->b4_iface), + dbus_iface = BLUEZ4_SERIAL_INTERFACE; + } else if (priv->bluez_version == 5) { +#if WITH_BLUEZ5_DUN + nm_bluez5_dun_cleanup (priv->b5_dun_context); +#else + g_assert_not_reached (); +#endif + priv->connected = FALSE; + goto out; + } + } else if (priv->connection_bt_type == NM_BT_CAPABILITY_NAP) { + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_NETWORK_INTERFACE; + else if (priv->bluez_version == 5) + dbus_iface = BLUEZ5_NETWORK_INTERFACE; + else + g_assert_not_reached (); + } else + g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, BLUEZ_SERVICE, @@ -454,6 +465,8 @@ nm_bluez_device_disconnect (NMBluezDevice *self) (GAsyncReadyCallback) bluez_disconnect_cb, g_object_ref (self)); +out: + g_clear_pointer (&priv->b4_iface, g_free); priv->connection_bt_type = NM_BT_CAPABILITY_NONE; } @@ -480,7 +493,7 @@ bluez_connect_cb (GDBusConnection *dbus_connection, g_simple_async_result_set_op_res_gpointer (result, g_strdup (device), g_free); - priv->bt_iface = device; + priv->b4_iface = device; g_variant_unref (variant); } @@ -489,6 +502,28 @@ bluez_connect_cb (GDBusConnection *dbus_connection, g_object_unref (result_object); } +#if WITH_BLUEZ5_DUN +static void +bluez5_dun_connect_cb (NMBluez5DunContext *context, + const char *device, + GError *error, + gpointer user_data) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + + if (error) { + g_simple_async_result_take_error (result, error); + } else { + g_simple_async_result_set_op_res_gpointer (result, + g_strdup (device), + g_free); + } + + g_simple_async_result_complete (result); + g_object_unref (result); +} +#endif + void nm_bluez_device_connect_async (NMBluezDevice *self, NMBluetoothCapabilities connection_bt_type, @@ -497,26 +532,39 @@ nm_bluez_device_connect_async (NMBluezDevice *self, { GSimpleAsyncResult *simple; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - const char *dbus_iface; - const char *connect_type = BLUETOOTH_CONNECT_NAP; + const char *dbus_iface = NULL; + const char *connect_type = NULL; g_return_if_fail (priv->capabilities & connection_bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP)); - if (priv->bluez_version == 5) { - g_return_if_fail (connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ5_NETWORK_INTERFACE; - } else if (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_DUN) { - dbus_iface = BLUEZ4_SERIAL_INTERFACE; - connect_type = BLUETOOTH_CONNECT_DUN; - } else { - g_return_if_fail (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ4_NETWORK_INTERFACE; - } - simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, nm_bluez_device_connect_async); + priv->connection_bt_type = connection_bt_type; + + if (connection_bt_type == NM_BT_CAPABILITY_NAP) { + connect_type = BLUETOOTH_CONNECT_NAP; + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_NETWORK_INTERFACE; + else if (priv->bluez_version == 5) + dbus_iface = BLUEZ5_NETWORK_INTERFACE; + } else if (connection_bt_type == NM_BT_CAPABILITY_DUN) { + connect_type = BLUETOOTH_CONNECT_DUN; + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_SERIAL_INTERFACE; + else if (priv->bluez_version == 5) { +#if WITH_BLUEZ5_DUN + if (priv->b5_dun_context == NULL) + priv->b5_dun_context = nm_bluez5_dun_new (priv->adapter_address, priv->address); + nm_bluez5_dun_connect (priv->b5_dun_context, bluez5_dun_connect_cb, simple); +#else + g_assert_not_reached (); +#endif + return; + } + } else + g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, BLUEZ_SERVICE, @@ -530,8 +578,6 @@ nm_bluez_device_connect_async (NMBluezDevice *self, NULL, (GAsyncReadyCallback) bluez_connect_cb, simple); - - priv->connection_bt_type = connection_bt_type; } const char * @@ -539,6 +585,7 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, GAsyncResult *result, GError **error) { + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); GSimpleAsyncResult *simple; const char *device; @@ -553,13 +600,28 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, return NULL; device = (const char *) g_simple_async_result_get_op_res_gpointer (simple); + if (device && priv->bluez_version == 5) + priv->connected = TRUE; + return device; } /***********************************************************/ +static void +set_adapter_address (NMBluezDevice *self, const char *address) +{ + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); + + g_return_if_fail (address); + + if (priv->adapter_address) + g_free (priv->adapter_address); + priv->adapter_address = g_strdup (address); +} + static guint32 -convert_uuids_to_capabilities (const char **strings, int bluez_version) +convert_uuids_to_capabilities (const char **strings) { const char **iter; guint32 capabilities = 0; @@ -571,8 +633,7 @@ convert_uuids_to_capabilities (const char **strings, int bluez_version) if (parts && parts[0]) { switch (g_ascii_strtoull (parts[0], NULL, 16)) { case 0x1103: - if (bluez_version == 4) - capabilities |= NM_BT_CAPABILITY_DUN; + capabilities |= NM_BT_CAPABILITY_DUN; break; case 0x1116: capabilities |= NM_BT_CAPABILITY_NAP; @@ -593,7 +654,7 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids) guint32 uint_val; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - uint_val = convert_uuids_to_capabilities (uuids, priv->bluez_version); + uint_val = convert_uuids_to_capabilities (uuids); if (priv->capabilities != uint_val) { if (priv->capabilities) { /* changing (relevant) capabilities is not supported and ignored -- except setting initially */ @@ -613,13 +674,10 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids) /** * priv->address can only be set one to a certain (non NULL) value. Every later attempt * to reset it to another value will be ignored and a warning will be logged. - * - * When setting the address for the first time, we also set bin_address. **/ static void _set_property_address (NMBluezDevice *self, const char *addr) { - struct ether_addr *tmp; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); if (g_strcmp0 (priv->address, addr) == 0) @@ -635,15 +693,11 @@ _set_property_address (NMBluezDevice *self, const char *addr) return; } - tmp = ether_aton (addr); - if (!tmp) { - if (priv->address) - nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from '%s' to '%s' (invalid value)", priv->path, priv->address, addr); - else - nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from NULL to '%s' (invalid value)", priv->path, addr); + if (!nm_utils_hwaddr_valid (addr, ETH_ALEN)) { + nm_log_warn (LOGD_BT, "bluez[%s] cannot set address to '%s' (invalid value)", priv->path, addr); return; } - memcpy (priv->bin_address, tmp->ether_addr_octet, ETH_ALEN); + priv->address = g_strdup (addr); g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_ADDRESS); } @@ -752,6 +806,10 @@ adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) if (v) g_variant_unref (v); + v = g_dbus_proxy_get_cached_property (priv->adapter5, "Address"); + if (VARIANT_IS_OF_TYPE_STRING (v)) + set_adapter_address (self, g_variant_get_string (v, NULL)); + priv->initialized = TRUE; g_signal_emit (self, signals[INITIALIZED], 0, TRUE); @@ -957,7 +1015,10 @@ on_bus_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) /********************************************************************/ NMBluezDevice * -nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version) +nm_bluez_device_new (const char *path, + const char *adapter_address, + NMConnectionProvider *provider, + int bluez_version) { NMBluezDevice *self; NMBluezDevicePrivate *priv; @@ -978,8 +1039,10 @@ nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); priv->bluez_version = bluez_version; - priv->provider = provider; + g_return_val_if_fail (bluez_version == 5 || (bluez_version == 4 && adapter_address), NULL); + if (adapter_address) + set_adapter_address (self, adapter_address); g_signal_connect (priv->provider, NM_CP_SIGNAL_CONNECTION_ADDED, @@ -1037,14 +1100,19 @@ dispose (GObject *object) if (priv->pan_connection) { /* Check whether we want to remove the created connection. If so, we take a reference * and delete it at the end of dispose(). */ - if ( nm_settings_connection_get_unsaved (NM_SETTINGS_CONNECTION (priv->pan_connection)) - && nm_connection_compare (priv->pan_connection, priv->pan_connection_original, NM_SETTING_COMPARE_FLAG_EXACT)) + if (nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (priv->pan_connection))) to_delete = g_object_ref (priv->pan_connection); priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); } +#if WITH_BLUEZ5_DUN + if (priv->b5_dun_context) { + nm_bluez5_dun_free (priv->b5_dun_context); + priv->b5_dun_context = NULL; + } +#endif + g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self); g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self); g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self); @@ -1073,9 +1141,10 @@ finalize (GObject *object) nm_log_dbg (LOGD_BT, "bluez[%s]: finalize NMBluezDevice", priv->path); g_free (priv->path); + g_free (priv->adapter_address); g_free (priv->address); g_free (priv->name); - g_free (priv->bt_iface); + g_free (priv->b4_iface); if (priv->proxy) g_signal_handlers_disconnect_by_data (priv->proxy, object); @@ -1148,51 +1217,45 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class) /* Properties */ g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_BLUEZ_DEVICE_PATH, - "DBus Path", - "DBus Path", + g_param_spec_string (NM_BLUEZ_DEVICE_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ADDRESS, - g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS, - "Address", - "Address", + g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_BLUEZ_DEVICE_NAME, - "Name", - "Name", + g_param_spec_string (NM_BLUEZ_DEVICE_NAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, - "Capabilities", - "Capabilities", - 0, G_MAXUINT, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_USABLE, - g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE, - "Usable", - "Usable", + g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONNECTED, - g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED, - "Connected", - "Connected", + g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[INITIALIZED] = g_signal_new ("initialized", diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h index 0bf7d898..92d99fa7 100644 --- a/src/devices/bluetooth/nm-bluez-device.h +++ b/src/devices/bluetooth/nm-bluez-device.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 - 2014 Red Hat, Inc. */ -#ifndef NM_BLUEZ_DEVICE_H -#define NM_BLUEZ_DEVICE_H +#ifndef __NETWORKMANAGER_BLUEZ_DEVICE_H__ +#define __NETWORKMANAGER_BLUEZ_DEVICE_H__ #include <glib.h> #include <glib-object.h> @@ -62,7 +62,10 @@ typedef struct { GType nm_bluez_device_get_type (void); -NMBluezDevice *nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version); +NMBluezDevice *nm_bluez_device_new (const char *path, + const char *adapter_address, + NMConnectionProvider *provider, + int bluez_version); const char *nm_bluez_device_get_path (NMBluezDevice *self); @@ -94,5 +97,5 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, void nm_bluez_device_disconnect (NMBluezDevice *self); -#endif /* NM_BLUEZ_DEVICE_H */ +#endif /* __NETWORKMANAGER_BLUEZ_DEVICE_H__ */ diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 04ffb0a4..e176a4b4 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 - 2014 Red Hat, Inc. */ +#include "config.h" + #include <signal.h> #include <string.h> #include <stdlib.h> @@ -62,20 +64,12 @@ static void check_bluez_and_try_setup (NMBluezManager *self); /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_BT - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ struct AsyncData { @@ -368,6 +362,18 @@ check_bluez_and_try_setup (NMBluezManager *self) async_data_pack (self)); } +static void +start (NMDeviceFactory *factory) +{ + check_bluez_and_try_setup (NM_BLUEZ_MANAGER (factory)); +} + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_BT; +} + /*********************************************************************/ static void @@ -391,16 +397,6 @@ dispose (GObject *object) } static void -constructed (GObject *object) -{ - NMBluezManager *self = NM_BLUEZ_MANAGER (object); - - G_OBJECT_CLASS (nm_bluez_manager_parent_class)->constructed (object); - - check_bluez_and_try_setup (self); -} - -static void nm_bluez_manager_init (NMBluezManager *self) { NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); @@ -412,6 +408,8 @@ nm_bluez_manager_init (NMBluezManager *self) static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void @@ -423,6 +421,5 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass) /* virtual methods */ object_class->dispose = dispose; - object_class->constructed = constructed; } diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h index 68d6dbe5..8320b298 100644 --- a/src/devices/bluetooth/nm-bluez-manager.h +++ b/src/devices/bluetooth/nm-bluez-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_BLUEZ_MANAGER_H -#define NM_BLUEZ_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ_MANAGER_H__ #include <glib.h> #include <glib-object.h> @@ -40,5 +40,5 @@ typedef struct { GObjectClass parent; } NMBluezManagerClass; -#endif /* NM_BLUEZ_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c index ad1786f0..9d1cfe1f 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.c +++ b/src/devices/bluetooth/nm-bluez4-adapter.c @@ -18,10 +18,12 @@ * Copyright (C) 2009 - 2012 Red Hat, Inc. */ +#include "config.h" + #include <glib.h> #include <string.h> -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-bluez4-adapter.h" #include "nm-bluez-device.h" @@ -162,7 +164,7 @@ device_created (DBusGProxy *proxy, const char *path, gpointer user_data) NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self); NMBluezDevice *device; - device = nm_bluez_device_new (path, priv->provider, 4); + device = nm_bluez_device_new (path, priv->address, priv->provider, 4); g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self); g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self); g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device); @@ -371,19 +373,17 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class) /* Properties */ g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH, - "DBus Path", - "DBus Path", + g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ADDRESS, - g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS, - "Address", - "Address", + g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[INITIALIZED] = g_signal_new ("initialized", diff --git a/src/devices/bluetooth/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h index 454ca557..a6256412 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.h +++ b/src/devices/bluetooth/nm-bluez4-adapter.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 - 2012 Red Hat, Inc. */ -#ifndef NM_BLUEZ4_ADAPTER_H -#define NM_BLUEZ4_ADAPTER_H +#ifndef __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ +#define __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ #include <glib.h> #include <glib-object.h> @@ -65,5 +65,5 @@ gboolean nm_bluez4_adapter_get_initialized (NMBluez4Adapter *self); GSList *nm_bluez4_adapter_get_devices (NMBluez4Adapter *self); -#endif /* NM_BLUEZ4_ADAPTER_H */ +#endif /* __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c index 2660cbd9..23b13d32 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -19,6 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ +#include "config.h" + #include <signal.h> #include <string.h> #include <stdlib.h> diff --git a/src/devices/bluetooth/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h index 19b1c65a..13cfef93 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.h +++ b/src/devices/bluetooth/nm-bluez4-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#ifndef NM_BLUEZ4_MANAGER_H -#define NM_BLUEZ4_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ4_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ4_MANAGER_H__ #include <glib.h> #include <glib-object.h> @@ -58,5 +58,5 @@ NMBluez4Manager *nm_bluez4_manager_new (NMConnectionProvider *provider); void nm_bluez4_manager_query_devices (NMBluez4Manager *manager); -#endif /* NM_BLUEZ4_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ4_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c new file mode 100644 index 00000000..a97eaa77 --- /dev/null +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -0,0 +1,410 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include <sys/socket.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> +#include <bluetooth/rfcomm.h> +#include <net/ethernet.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +#include "nm-bluez5-dun.h" +#include "nm-bt-error.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" + +struct _NMBluez5DunContext { + bdaddr_t src; + bdaddr_t dst; + char *src_str; + char *dst_str; + int rfcomm_channel; + int rfcomm_fd; + int rfcomm_tty_fd; + int rfcomm_id; + NMBluez5DunFunc callback; + gpointer user_data; + sdp_session_t *sdp_session; + guint sdp_watch_id; +}; + +static void +dun_connect (NMBluez5DunContext *context) +{ + struct sockaddr_rc sa; + int devid, try = 30; + char tty[100]; + const int ttylen = sizeof (tty) - 1; + GError *error = NULL; + + struct rfcomm_dev_req req = { + .flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), + .dev_id = -1, + .channel = context->rfcomm_channel + }; + + context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (context->rfcomm_fd < 0) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to create RFCOMM socket: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + /* Connect to the remote device */ + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = 0; + memcpy (&sa.rc_bdaddr, &context->src, ETH_ALEN); + if (bind (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof(sa))) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to bind socket: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + sa.rc_channel = context->rfcomm_channel; + memcpy (&sa.rc_bdaddr, &context->dst, ETH_ALEN); + if (connect (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof (sa)) ) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to connect to remote device: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + nm_log_dbg (LOGD_BT, "(%s): connected to %s on channel %d", + context->src_str, context->dst_str, context->rfcomm_channel); + + /* Create an RFCOMM kernel device for the DUN channel */ + memcpy (&req.src, &context->src, ETH_ALEN); + memcpy (&req.dst, &context->dst, ETH_ALEN); + devid = ioctl (context->rfcomm_fd, RFCOMMCREATEDEV, &req); + if (devid < 0) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to create rfcomm device: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + context->rfcomm_id = devid; + + snprintf (tty, ttylen, "/dev/rfcomm%d", devid); + while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY)) < 0 && try--) { + if (try) { + g_usleep (100 * 1000); + continue; + } + + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to find rfcomm device: %s", + tty); + break; + } + +done: + context->callback (context, tty, error, context->user_data); +} + +static void +sdp_search_cleanup (NMBluez5DunContext *context) +{ + if (context->sdp_session) { + sdp_close (context->sdp_session); + context->sdp_session = NULL; + } + + if (context->sdp_watch_id) { + g_source_remove (context->sdp_watch_id); + context->sdp_watch_id = 0; + } +} + +static void +sdp_search_completed_cb (uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data) +{ + NMBluez5DunContext *context = user_data; + int scanned, seqlen = 0, bytesleft = size; + uint8_t dataType; + int channel = -1; + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished with type=%d status=%d", + context->src_str, context->dst_str, status, type); + + /* SDP response received */ + if (status || type != SDP_SVC_SEARCH_ATTR_RSP) { + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Did not get a Service Discovery response"); + context->callback (context, NULL, error, context->user_data); + goto done; + } + + scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP sequence type scanned=%d length=%d", + context->src_str, context->dst_str, scanned, seqlen); + + scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); + if (!scanned || !seqlen) { + /* Short read or unknown sequence type */ + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Improper Service Discovery response"); + context->callback (context, NULL, error, context->user_data); + goto done; + } + + rsp += scanned; + bytesleft -= scanned; + do { + sdp_record_t *rec; + int recsize = 0; + sdp_list_t *protos; + + rec = sdp_extract_pdu (rsp, bytesleft, &recsize); + if (!rec) + break; + + if (!recsize) { + sdp_record_free (rec); + break; + } + + if (sdp_get_access_protos (rec, &protos) == 0) { + /* Extract the DUN channel number */ + channel = sdp_get_proto_port (protos, RFCOMM_UUID); + sdp_list_free (protos, NULL); + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP channel=%d", + context->src_str, context->dst_str, channel); + } + sdp_record_free (rec); + + scanned += recsize; + rsp += recsize; + bytesleft -= recsize; + } while ((scanned < (ssize_t) size) && (bytesleft > 0) && (channel < 0)); + +done: + if (channel != -1) { + context->rfcomm_channel = channel; + dun_connect (context); + } + + sdp_search_cleanup (context); +} + +static gboolean +sdp_search_process_cb (GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + NMBluez5DunContext *context = user_data; + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search progressed with condition=%d", + context->src_str, context->dst_str, condition); + + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery interrupted"); + context->callback (context, NULL, error, context->user_data); + sdp_search_cleanup (context); + return FALSE; + } + + if (sdp_process (context->sdp_session) < 0) { + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished", + context->src_str, context->dst_str); + + /* Search finished successfully. */ + return FALSE; + } + + /* Search progressed successfully. */ + return TRUE; +} + +static gboolean +sdp_connect_watch (GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + NMBluez5DunContext *context = user_data; + sdp_list_t *search, *attrs; + uuid_t svclass; + uint16_t attr; + int fd, err, fd_err = 0; + socklen_t len = sizeof (fd_err); + GError *error = NULL; + + context->sdp_watch_id = 0; + + fd = g_io_channel_unix_get_fd (channel); + if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { + nm_log_dbg (LOGD_BT, "(%s -> %s): getsockopt error=%d", + context->src_str, context->dst_str, errno); + err = errno; + } else { + nm_log_dbg (LOGD_BT, "(%s -> %s): SO_ERROR error=%d", + context->src_str, context->dst_str, fd_err); + err = fd_err; + } + + if (err != 0) { + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Error on Service Discovery socket: (%d) %s", + err, strerror (err)); + goto done; + } + + if (sdp_set_notify (context->sdp_session, sdp_search_completed_cb, context) < 0) { + /* Should not be reached, only can fail if we passed bad sdp_session. */ + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Could not request Service Discovery notification"); + goto done; + } + + sdp_uuid16_create (&svclass, DIALUP_NET_SVCLASS_ID); + search = sdp_list_append (NULL, &svclass); + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append (NULL, &attr); + + if (!sdp_service_search_attr_async (context->sdp_session, search, SDP_ATTR_REQ_INDIVIDUAL, attrs)) { + /* Set callback responsible for update the internal SDP transaction */ + context->sdp_watch_id = g_io_add_watch (channel, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + sdp_search_process_cb, + context); + } else { + err = sdp_get_error (context->sdp_session); + error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Error starting Service Discovery: (%d) %s", + err, strerror (err)); + } + + sdp_list_free (attrs, NULL); + sdp_list_free (search, NULL); + +done: + if (error) { + context->callback (context, NULL, error, context->user_data); + sdp_search_cleanup (context); + } + + return G_SOURCE_REMOVE; +} + +NMBluez5DunContext * +nm_bluez5_dun_new (const char *adapter, + const char *remote) + +{ + NMBluez5DunContext *context; + + context = g_slice_new0 (NMBluez5DunContext); + str2ba (adapter, &context->src); + str2ba (remote, &context->dst); + context->src_str = g_strdup (adapter); + context->dst_str = g_strdup (remote); + context->rfcomm_channel = -1; + context->rfcomm_id = -1; + context->rfcomm_fd = -1; + return context; +} + +void +nm_bluez5_dun_connect (NMBluez5DunContext *context, + NMBluez5DunFunc callback, + gpointer user_data) +{ + GIOChannel *channel; + + context->callback = callback; + context->user_data = user_data; + + if (context->rfcomm_channel != -1) { + nm_log_dbg (LOGD_BT, "(%s): channel number on device %s cached: %d", + context->src_str, context->dst_str, context->rfcomm_channel); + dun_connect (context); + return; + } + + nm_log_dbg (LOGD_BT, "(%s): starting channel number discovery for device %s", + context->src_str, context->dst_str); + + context->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING); + if (!context->sdp_session) { + GError *error; + int err = sdp_get_error (context->sdp_session); + + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to connect to the SDP server: (%d) %s", + err, strerror (err)); + context->callback (context, NULL, error, context->user_data); + return; + } + + channel = g_io_channel_unix_new (sdp_get_socket (context->sdp_session)); + context->sdp_watch_id = g_io_add_watch (channel, + G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + sdp_connect_watch, + context); + g_io_channel_unref (channel); +} + +/* Only clean up connection-related stuff to allow reconnect */ +void +nm_bluez5_dun_cleanup (NMBluez5DunContext *context) +{ + g_return_if_fail (context != NULL); + + sdp_search_cleanup (context); + + if (context->rfcomm_fd >= 0) { + if (context->rfcomm_id >= 0) { + struct rfcomm_dev_req req = { 0 }; + + req.dev_id = context->rfcomm_id; + ioctl (context->rfcomm_fd, RFCOMMRELEASEDEV, &req); + context->rfcomm_id = -1; + } + close (context->rfcomm_fd); + context->rfcomm_fd = -1; + } + + close (context->rfcomm_tty_fd); + context->rfcomm_tty_fd = -1; +} + +void +nm_bluez5_dun_free (NMBluez5DunContext *context) +{ + g_return_if_fail (context != NULL); + + nm_bluez5_dun_cleanup (context); + g_clear_pointer (&context->src_str, g_free); + g_clear_pointer (&context->dst_str, g_free); + g_slice_free (NMBluez5DunContext, context); +} diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h new file mode 100644 index 00000000..7e259725 --- /dev/null +++ b/src/devices/bluetooth/nm-bluez5-dun.h @@ -0,0 +1,46 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#ifndef _NM_BLUEZ5_UTILS_H_ +#define _NM_BLUEZ5_UTILS_H_ + +#include <glib.h> +#include <gio/gio.h> + +typedef struct _NMBluez5DunContext NMBluez5DunContext; + +typedef void (*NMBluez5DunFunc) (NMBluez5DunContext *context, + const char *rfcomm_dev, + GError *error, + gpointer user_data); + +NMBluez5DunContext *nm_bluez5_dun_new (const char *adapter, + const char *remote); + +void nm_bluez5_dun_connect (NMBluez5DunContext *context, + NMBluez5DunFunc callback, gpointer user_data); + +/* Clean up connection resources */ +void nm_bluez5_dun_cleanup (NMBluez5DunContext *context); + +/* Clean up and dispose all resources */ +void nm_bluez5_dun_free (NMBluez5DunContext *context); + +#endif /* _NM_BLUEZ5_UTILS_H_ */ diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 63006b3a..b8568523 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -20,6 +20,8 @@ * Copyright (C) 2013 Intel Corporation. */ +#include "config.h" + #include <signal.h> #include <string.h> #include <stdlib.h> @@ -143,7 +145,7 @@ device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NMBluezDevice *device; - device = nm_bluez_device_new (path, priv->provider, 5); + device = nm_bluez_device_new (path, NULL, priv->provider, 5); g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self); g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self); g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device); diff --git a/src/devices/bluetooth/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h index 79f347bc..8152976d 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.h +++ b/src/devices/bluetooth/nm-bluez5-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#ifndef NM_BLUEZ5_MANAGER_H -#define NM_BLUEZ5_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ5_MANAGER_H__ #include <glib.h> #include <glib-object.h> @@ -58,5 +58,5 @@ NMBluez5Manager *nm_bluez5_manager_new (NMConnectionProvider *provider); void nm_bluez5_manager_query_devices (NMBluez5Manager *manager); -#endif /* NM_BLUEZ5_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ5_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bt-enum-types.c b/src/devices/bluetooth/nm-bt-enum-types.c index 2595caeb..16741c9f 100644 --- a/src/devices/bluetooth/nm-bt-enum-types.c +++ b/src/devices/bluetooth/nm-bt-enum-types.c @@ -5,7 +5,7 @@ #include "nm-bt-enum-types.h" -#include "nm-device-bt.h" +#include "nm-bt-error.h" GType nm_bt_error_get_type (void) @@ -18,6 +18,7 @@ nm_bt_error_get_type (void) { NM_BT_ERROR_CONNECTION_NOT_BT, "NM_BT_ERROR_CONNECTION_NOT_BT", "ConnectionNotBt" }, { NM_BT_ERROR_CONNECTION_INVALID, "NM_BT_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, { NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "NM_BT_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { NM_BT_ERROR_DUN_CONNECT_FAILED, "NM_BT_ERROR_DUN_CONNECT_FAILED", "DunConnectFailed" }, { 0, NULL, NULL } }; GType g_define_type_id = diff --git a/src/devices/bluetooth/nm-bt-error.c b/src/devices/bluetooth/nm-bt-error.c new file mode 100644 index 00000000..e3b8e7f5 --- /dev/null +++ b/src/devices/bluetooth/nm-bt-error.c @@ -0,0 +1,35 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include "nm-bt-error.h" + +GQuark +nm_bt_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-bt-error"); + return quark; +} + + diff --git a/src/devices/bluetooth/nm-bt-error.h b/src/devices/bluetooth/nm-bt-error.h new file mode 100644 index 00000000..fa3a9570 --- /dev/null +++ b/src/devices/bluetooth/nm-bt-error.h @@ -0,0 +1,35 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#ifndef _NM_BLUEZ5_ERROR_H_ +#define _NM_BLUEZ5_ERROR_H_ + +typedef enum { + NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ + NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_BT_ERROR_DUN_CONNECT_FAILED, /*< nick=DunConnectFailed >*/ +} NMBtError; + +#define NM_BT_ERROR (nm_bt_error_quark ()) +GQuark nm_bt_error_quark (void); + +#endif /* _NM_BT_ERROR_H_ */ + diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 0bd2f17d..689f37c9 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -22,8 +22,6 @@ #include <stdio.h> #include <string.h> -#include <net/ethernet.h> -#include <netinet/ether.h> #include <glib/gi18n.h> #include <gio/gio.h> @@ -46,9 +44,13 @@ #include "NetworkManagerUtils.h" #include "nm-bt-enum-types.h" #include "nm-utils.h" +#include "nm-bt-error.h" +#include "nm-bt-enum-types.h" + +#define MM_DBUS_SERVICE "org.freedesktop.ModemManager1" -#define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_NEW_DBUS_SERVICE "org.freedesktop.ModemManager1" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBt); G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) @@ -63,7 +65,7 @@ typedef struct { NMBluezDevice *bt_device; - guint8 bdaddr[ETH_ALEN]; + char *bdaddr; char *name; guint32 capabilities; @@ -94,17 +96,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -#define NM_BT_ERROR (nm_bt_error_quark ()) - -static GQuark -nm_bt_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bt-error"); - return quark; -} - guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) { g_return_val_if_fail (NM_IS_DEVICE_BT (self), NM_BT_CAPABILITY_NONE); @@ -112,15 +103,6 @@ guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) return NM_DEVICE_BT_GET_PRIVATE (self)->capabilities; } -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) -{ - /* HW address is the Bluetooth HW address of the remote device */ - if (out_permanent) - *out_permanent = TRUE; /* the bdaddr of the remote device will never change */ - return ETH_ALEN; -} - static guint32 get_connection_bt_type (NMConnection *connection) { @@ -142,6 +124,12 @@ get_connection_bt_type (NMConnection *connection) return NM_BT_CAPABILITY_NONE; } +static guint32 +get_generic_capabilities (NMDevice *device) +{ + return NM_DEVICE_CAP_IS_NON_KERNEL; +} + static gboolean can_auto_connect (NMDevice *device, NMConnection *connection, @@ -167,7 +155,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingConnection *s_con; NMSettingBluetooth *s_bt; - const GByteArray *array; + const char *bdaddr; guint32 bt_type; if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection)) @@ -187,11 +175,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!(bt_type & priv->capabilities)) return FALSE; - array = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!array || (array->len != ETH_ALEN)) + bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); + if (!bdaddr) return FALSE; - - if (memcmp (priv->bdaddr, array->data, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1)) return FALSE; return TRUE; @@ -225,14 +212,14 @@ complete_connection (NMDevice *device, { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingBluetooth *s_bt; - const GByteArray *setting_bdaddr; + const char *setting_bdaddr; const char *ctype; gboolean is_dun = FALSE, is_pan = FALSE; NMSettingGsm *s_gsm; NMSettingCdma *s_cdma; NMSettingSerial *s_serial; - NMSettingPPP *s_ppp; - const char *format = NULL, *preferred = NULL; + NMSettingPpp *s_ppp; + const char *fallback_prefix = NULL, *preferred = NULL; s_gsm = nm_connection_get_setting_gsm (connection); s_cdma = nm_connection_get_setting_cdma (connection); @@ -262,18 +249,24 @@ complete_connection (NMDevice *device, /* Make sure the device supports PAN */ if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "PAN required but Bluetooth device does not support NAP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("PAN requested, but Bluetooth device does not support NAP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } /* PAN can't use any DUN-related settings */ if (s_gsm || s_cdma || s_serial || s_ppp) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "PAN incompatible with GSM, CDMA, or serial settings"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("PAN connections cannot specify GSM, CDMA, or serial settings")); + g_prefix_error (error, "%s: ", + s_gsm ? NM_SETTING_GSM_SETTING_NAME : + s_cdma ? NM_SETTING_CDMA_SETTING_NAME : + s_serial ? NM_SETTING_SERIAL_SETTING_NAME : + NM_SETTING_PPP_SETTING_NAME); return FALSE; } @@ -281,23 +274,25 @@ complete_connection (NMDevice *device, NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, NULL); - format = _("PAN connection %d"); + fallback_prefix = _("PAN connection"); } else if (is_dun) { /* Make sure the device supports PAN */ if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "DUN required but Bluetooth device does not support DUN"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("DUN requested, but Bluetooth device does not support DUN")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } /* Need at least a GSM or a CDMA setting */ if (!s_gsm && !s_cdma) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "Setting requires DUN but no GSM or CDMA setting is present"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("DUN connection must include a GSM or CDMA setting")); + g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); return FALSE; } @@ -306,51 +301,46 @@ complete_connection (NMDevice *device, NULL); if (s_gsm) { - format = _("GSM connection %d"); + fallback_prefix = _("GSM connection"); if (!nm_setting_gsm_get_number (s_gsm)) g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - } else if (s_cdma) { - format = _("CDMA connection %d"); + } else { + fallback_prefix = _("CDMA connection"); if (!nm_setting_cdma_get_number (s_cdma)) g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL); - } else - format = _("DUN connection %d"); + } } else { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "Unknown/unhandled Bluetooth connection type"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown/unhandled Bluetooth connection type")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } nm_utils_complete_generic (connection, NM_SETTING_BLUETOOTH_SETTING_NAME, existing_connections, - format, preferred, + fallback_prefix, + NULL, is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */ setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); if (setting_bdaddr) { /* Make sure the setting BT Address (if any) matches the device's */ - if (memcmp (setting_bdaddr->data, priv->bdaddr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_bdaddr, -1, priv->bdaddr, -1)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - NM_SETTING_BLUETOOTH_BDADDR); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); return FALSE; } } else { - GByteArray *bdaddr; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - /* Lock the connection to this device by default */ - if (memcmp (priv->bdaddr, null_mac, ETH_ALEN)) { - bdaddr = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bdaddr, priv->bdaddr, ETH_ALEN); - g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL); - g_byte_array_free (bdaddr, TRUE); - } + if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, NULL, ETH_ALEN)) + g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, priv->bdaddr, NULL); } return TRUE; @@ -437,7 +427,8 @@ modem_prepare_result (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDevice *device = NM_DEVICE (self); NMDeviceState state; state = nm_device_get_state (device); @@ -470,8 +461,7 @@ modem_prepare_result (NMModem *modem, * the SIM if the incorrect PIN continues to be used. */ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL); - nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN", - nm_device_get_iface (device)); + _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN"); } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); @@ -491,21 +481,20 @@ device_state_changed (NMDevice *device, } static void -modem_ip4_config_result (NMModem *self, +modem_ip4_config_result (NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { - nm_log_warn (LOGD_MB | LOGD_IP4 | LOGD_BT, - "(%s): retrieving IP4 configuration failed: (%d) %s", - nm_device_get_ip_iface (device), - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT, + "retrieving IP4 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else @@ -648,16 +637,14 @@ component_added (NMDevice *device, GObject *component) */ state = nm_device_get_state (NM_DEVICE (self)); if (state != NM_DEVICE_STATE_CONFIG) { - nm_log_warn (LOGD_BT | LOGD_MB, - "(%s): modem found but device not in correct state (%d)", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_state (NM_DEVICE (self))); + _LOGW (LOGD_BT | LOGD_MB, + "modem found but device not in correct state (%d)", + nm_device_get_state (NM_DEVICE (self))); return TRUE; } - nm_log_info (LOGD_BT | LOGD_MB, - "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) modem found.", - nm_device_get_iface (NM_DEVICE (self))); + _LOGI (LOGD_BT | LOGD_MB, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) modem found."); if (priv->modem) { g_warn_if_reached (); @@ -674,11 +661,6 @@ component_added (NMDevice *device, GObject *component) g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); - /* In the old ModemManager the data port is known from the very beginning; - * while in the new ModemManager the data port is set afterwards when the bearer gets - * created */ - if (modem_data_port) - nm_device_set_ip_iface (NM_DEVICE (self), modem_data_port); g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self); /* Kick off the modem connection */ @@ -711,11 +693,9 @@ check_connect_continue (NMDeviceBt *self) if (!priv->connected || !priv->have_iface) return; - nm_log_info (LOGD_BT, "Activation (%s %s/bluetooth) Stage 2 of 5 (Device Configure) " - "successful. Will connect via %s.", - nm_device_get_iface (device), - nm_device_get_ip_iface (device), - dun ? "DUN" : (pan ? "PAN" : "unknown")); + _LOGI (LOGD_BT, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) successful. Will connect via %s.", + dun ? "DUN" : (pan ? "PAN" : "unknown")); /* Kill the connect timeout since we're connected now */ if (priv->timeout_id) { @@ -730,9 +710,8 @@ check_connect_continue (NMDeviceBt *self) /* Wait for ModemManager to find the modem */ priv->timeout_id = g_timeout_add_seconds (30, modem_find_timeout, self); - nm_log_info (LOGD_BT | LOGD_MB, "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " - "waiting for modem to appear.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT | LOGD_MB, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) waiting for modem to appear."); } else g_assert_not_reached (); } @@ -751,13 +730,14 @@ bluez_connect_cb (GObject *object, res, &error); if (!device) { - nm_log_warn (LOGD_BT, "Error connecting with bluez: %s", - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_BT, "Error connecting with bluez: %s", + error && error->message ? error->message : "(unknown)"); g_clear_error (&error); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); + g_object_unref (self); return; } @@ -768,12 +748,12 @@ bluez_connect_cb (GObject *object, nm_device_set_ip_iface (NM_DEVICE (self), device); } - nm_log_dbg (LOGD_BT, "(%s): connect request successful", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_BT, "connect request successful"); /* Stage 3 gets scheduled when Bluez says we're connected */ priv->have_iface = TRUE; check_connect_continue (self); + g_object_unref (self); } static void @@ -790,8 +770,7 @@ bluez_connected_changed (NMBluezDevice *bt_device, connected = nm_bluez_device_get_connected (bt_device); if (connected) { if (state == NM_DEVICE_STATE_CONFIG) { - nm_log_dbg (LOGD_BT, "(%s): connected to the device", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "connected to the device"); priv->connected = TRUE; check_connect_continue (self); @@ -802,13 +781,10 @@ bluez_connected_changed (NMBluezDevice *bt_device, /* Bluez says we're disconnected from the device. Suck. */ if (nm_device_is_activating (device)) { - nm_log_info (LOGD_BT, - "Activation (%s/bluetooth): bluetooth link disconnected.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT, "Activation: (bluetooth) bluetooth link disconnected."); fail = TRUE; } else if (state == NM_DEVICE_STATE_ACTIVATED) { - nm_log_info (LOGD_BT, "(%s): bluetooth link disconnected.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT, "bluetooth link disconnected."); fail = TRUE; } @@ -824,8 +800,7 @@ bt_connect_timeout (gpointer user_data) { NMDeviceBt *self = NM_DEVICE_BT (user_data); - nm_log_dbg (LOGD_BT, "(%s): initial connection timed out", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_BT, "initial connection timed out"); NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0; nm_device_state_changed (NM_DEVICE (self), @@ -837,6 +812,7 @@ bt_connect_timeout (gpointer user_data) static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { + NMDeviceBt *self = NM_DEVICE_BT (device); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMConnection *connection; @@ -853,13 +829,12 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_FAILURE; } - nm_log_dbg (LOGD_BT, "(%s): requesting connection to the device", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "requesting connection to the device"); /* Connect to the BT device */ nm_bluez_device_connect_async (priv->bt_device, priv->bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP), - bluez_connect_cb, device); + bluez_connect_cb, g_object_ref (device)); if (priv->timeout_id) g_source_remove (priv->timeout_id); @@ -897,8 +872,7 @@ act_stage3_ip6_config_start (NMDevice *device, if (priv->bt_type == NM_BT_CAPABILITY_DUN) { ret = nm_modem_stage3_ip6_config_start (NM_DEVICE_BT_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_bt_parent_class), + nm_device_get_act_request (device), reason); } else ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip6_config_start (device, out_config, reason); @@ -979,8 +953,7 @@ handle_availability_change (NMDeviceBt *self, state = nm_device_get_state (device); if (state < NM_DEVICE_STATE_UNAVAILABLE) { - nm_log_dbg (LOGD_BT, "(%s): availability blocked by UNMANAGED state", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "availability blocked by UNMANAGED state"); return; } @@ -990,7 +963,7 @@ handle_availability_change (NMDeviceBt *self, if (available) { if (state != NM_DEVICE_STATE_UNAVAILABLE) - nm_log_warn (LOGD_CORE | LOGD_BT, "not in expected unavailable state!"); + _LOGW (LOGD_CORE | LOGD_BT, "not in expected unavailable state!"); nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, @@ -1011,9 +984,8 @@ set_mm_running (NMDeviceBt *self, gboolean running) if (priv->mm_running == running) return; - nm_log_dbg (LOGD_BT, "(%s): ModemManager now %s", - nm_device_get_iface (NM_DEVICE (self)), - running ? "available" : "unavailable"); + _LOGD (LOGD_BT, "ModemManager now %s", + running ? "available" : "unavailable"); old_available = nm_device_is_available (NM_DEVICE (self)); priv->mm_running = running; @@ -1038,11 +1010,7 @@ mm_name_owner_changed (NMDBusManager *dbus_mgr, gboolean new_owner_good; /* Can't handle the signal if its not from the modem service */ - if ( strcmp (MM_OLD_DBUS_SERVICE, name) != 0 -#if WITH_MODEM_MANAGER_1 - && strcmp (MM_NEW_DBUS_SERVICE, name) != 0 -#endif - ) + if (strcmp (MM_DBUS_SERVICE, name) != 0) return; old_owner_good = (old_owner && strlen (old_owner)); @@ -1096,11 +1064,7 @@ nm_device_bt_init (NMDeviceBt *self) self); /* Initial check to see if ModemManager is running */ - mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_OLD_DBUS_SERVICE); -#if WITH_MODEM_MANAGER_1 - if (!mm_running) - mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_NEW_DBUS_SERVICE); -#endif + mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE); set_mm_running (self, mm_running); } @@ -1108,15 +1072,13 @@ static void constructed (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - const guint8 *my_hwaddr; - guint my_hwaddr_len = 0; + const char *my_hwaddr; G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); - my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object), &my_hwaddr_len); + my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object)); g_assert (my_hwaddr); - g_assert_cmpint (my_hwaddr_len, ==, ETH_ALEN); - memcpy (priv->bdaddr, my_hwaddr, ETH_ALEN); + priv->bdaddr = g_strdup (my_hwaddr); /* Watch for BT device property changes */ g_signal_connect (priv->bt_device, "notify::" NM_BLUEZ_DEVICE_CONNECTED, @@ -1203,6 +1165,7 @@ finalize (GObject *object) g_free (priv->rfcomm_iface); g_free (priv->name); + g_free (priv->bdaddr); G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); } @@ -1221,7 +1184,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; - device_class->get_hw_address_length = get_hw_address_length; + device_class->get_generic_capabilities = get_generic_capabilities; device_class->can_auto_connect = can_auto_connect; device_class->deactivate = deactivate; device_class->act_stage2_config = act_stage2_config; @@ -1238,27 +1201,24 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_BT_NAME, - g_param_spec_string (NM_DEVICE_BT_NAME, - "Bluetooth device name", - "Bluetooth device name", + g_param_spec_string (NM_DEVICE_BT_NAME, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, - "Bluetooth device capabilities", - "Bluetooth device capabilities", + g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, "", "", NM_BT_CAPABILITY_NONE, G_MAXUINT, NM_BT_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BT_DEVICE, - g_param_spec_object (NM_DEVICE_BT_DEVICE, - "NMBluezDevice object for the Device", - "NMBluezDevice object for the Device", + g_param_spec_object (NM_DEVICE_BT_DEVICE, "", "", NM_TYPE_BLUEZ_DEVICE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[PPP_STATS] = @@ -1273,6 +1233,4 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bt_object_info); - - dbus_g_error_domain_register (NM_BT_ERROR, NULL, NM_TYPE_BT_ERROR); } diff --git a/src/devices/bluetooth/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h index 83732bc0..c1e95d91 100644 --- a/src/devices/bluetooth/nm-device-bt.h +++ b/src/devices/bluetooth/nm-device-bt.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Red Hat, Inc. */ -#ifndef NM_DEVICE_BT_H -#define NM_DEVICE_BT_H +#ifndef __NETWORKMANAGER_DEVICE_BT_H__ +#define __NETWORKMANAGER_DEVICE_BT_H__ #include <nm-device.h> #include "nm-bluez-device.h" @@ -34,12 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT)) #define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) -typedef enum { - NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ - NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBtError; - #define NM_DEVICE_BT_NAME "name" #define NM_DEVICE_BT_CAPABILITIES "bt-capabilities" #define NM_DEVICE_BT_DEVICE "bt-device" @@ -71,4 +65,4 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device, G_END_DECLS -#endif /* NM_DEVICE_BT_H */ +#endif /* __NETWORKMANAGER_DEVICE_BT_H__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 6f8caeb4..9d9fe426 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -23,30 +23,30 @@ #include <glib.h> #include <glib/gi18n.h> -#include <netinet/ether.h> #include <errno.h> #include <stdlib.h> #include "gsystem-local-alloc.h" #include "nm-device-bond.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-platform.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-bond-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBond); G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) #define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) -#define NM_BOND_ERROR (nm_bond_error_quark ()) - typedef struct { int dummy; } NMDeviceBondPrivate; @@ -60,17 +60,6 @@ enum { /******************************************************************/ -static GQuark -nm_bond_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bond-error"); - return quark; -} - -/******************************************************************/ - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -110,7 +99,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; /* Bond connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; @@ -126,17 +115,14 @@ complete_connection (NMDevice *device, const GSList *existing_connections, GError **error) { - NMSettingBond *s_bond, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; + NMSettingBond *s_bond; nm_utils_complete_generic (connection, NM_SETTING_BOND_SETTING_NAME, existing_connections, - _("Bond connection %d"), NULL, + _("Bond connection"), + "bond", TRUE); s_bond = nm_connection_get_setting_bond (connection); @@ -145,34 +131,6 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_bond)); } - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_bond_get_interface_name (s_bond)) { - name = g_strdup_printf ("bond%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing bond connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_bond (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_bond_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_bond), NM_SETTING_BOND_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - return TRUE; } @@ -181,14 +139,13 @@ complete_connection (NMDevice *device, static gboolean set_bond_attr (NMDevice *device, const char *attr, const char *value) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean ret; int ifindex = nm_device_get_ifindex (device); ret = nm_platform_master_set_option (ifindex, attr, value); - if (!ret) { - nm_log_warn (LOGD_HW, "(%s): failed to set bonding attribute " - "'%s' to '%s'", nm_device_get_ip_iface (device), attr, value); - } + if (!ret) + _LOGW (LOGD_HW, "failed to set bonding attribute '%s' to '%s'", attr, value); return ret; } @@ -209,14 +166,12 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingBond *s_bond = nm_connection_get_setting_bond (connection); - const char *ifname = nm_device_get_iface (device); int ifindex = nm_device_get_ifindex (device); const char **options; if (!s_bond) { s_bond = (NMSettingBond *) nm_setting_bond_new (); nm_connection_add_setting (connection, (NMSetting *) s_bond); - g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, ifname, NULL); } /* Read bond options from sysfs and update the Bond setting to match */ @@ -243,6 +198,19 @@ update_connection (NMDevice *device, NMConnection *connection) } } +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, nm_device_get_iface (self), + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + return TRUE; +} + static void set_arp_targets (NMDevice *device, const char *value, @@ -380,6 +348,10 @@ apply_bonding_config (NMDevice *device) set_simple_option (device, "xmit_hash_policy", s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY); set_simple_option (device, "resend_igmp", s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP); + if ( g_strcmp0 (mode, "4") == 0 + || g_strcmp0 (mode, "802.3ad") == 0) + set_simple_option (device, "lacp_rate", s_bond, NM_SETTING_BOND_OPTION_LACP_RATE); + return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -410,8 +382,8 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean success = TRUE, no_firmware = FALSE; - const char *iface = nm_device_get_ip_iface (device); const char *slave_iface = nm_device_get_ip_iface (slave); nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND); @@ -425,9 +397,9 @@ enslave_slave (NMDevice *device, if (!success) return FALSE; - nm_log_info (LOGD_BOND, "(%s): enslaved bond slave %s", iface, slave_iface); + _LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface); } else - nm_log_info (LOGD_BOND, "(%s): bond slave %s was enslaved", iface, slave_iface); + _LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface); g_object_notify (G_OBJECT (device), NM_DEVICE_BOND_SLAVES); return TRUE; @@ -438,6 +410,7 @@ release_slave (NMDevice *device, NMDevice *slave, gboolean configure) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean success = TRUE, no_firmware = FALSE; if (configure) { @@ -445,17 +418,14 @@ release_slave (NMDevice *device, nm_device_get_ip_ifindex (slave)); if (success) { - nm_log_info (LOGD_BOND, "(%s): released bond slave %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BOND, "released bond slave %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_warn (LOGD_BOND, "(%s): failed to release bond slave %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGW (LOGD_BOND, "failed to release bond slave %s", + nm_device_get_ip_iface (slave)); } } else { - nm_log_info (LOGD_BOND, "(%s): bond slave %s was released", - nm_device_get_ip_iface (device), + _LOGI (LOGD_BOND, "bond slave %s was released", nm_device_get_ip_iface (slave)); } @@ -467,10 +437,8 @@ release_slave (NMDevice *device, * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released slave. */ - if (!nm_device_bring_up (slave, TRUE, &no_firmware)) { - nm_log_warn (LOGD_BOND, "(%s): released bond slave could not be brought up.", - nm_device_get_iface (slave)); - } + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) + _LOGW (LOGD_BOND, "released bond slave could not be brought up."); } return success; @@ -478,57 +446,6 @@ release_slave (NMDevice *device, /******************************************************************/ -NMDevice * -nm_device_bond_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_DRIVER, "bonding", - NM_DEVICE_TYPE_DESC, "Bond", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -NMDevice * -nm_device_bond_new_for_connection (NMConnection *connection) -{ - const char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - if ( !nm_platform_bond_add (iface) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_BOND, "(%s): failed to create bonding master interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bonding", - NM_DEVICE_TYPE_DESC, "Bond", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_bond_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_BOND, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - static void nm_device_bond_init (NMDeviceBond * self) { @@ -579,7 +496,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->connection_type = NM_SETTING_BOND_SETTING_NAME; /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; @@ -590,6 +506,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; @@ -598,15 +515,69 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bond_object_info); +} + +/*************************************************************/ + +#define NM_TYPE_BOND_FACTORY (nm_bond_factory_get_type ()) +#define NM_BOND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BOND_FACTORY, NMBondFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_BOND) { + 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); + } + return NULL; +} + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + const char *iface; + + if (!nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + return NULL; + + iface = nm_connection_get_interface_name (connection); + g_return_val_if_fail (iface != NULL, NULL); - dbus_g_error_domain_register (NM_BOND_ERROR, NULL, NM_TYPE_BOND_ERROR); + if ( !nm_platform_bond_add (iface) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_BOND, "(%s): failed to create bonding master interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bonding", + NM_DEVICE_TYPE_DESC, "Bond", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NM_DEVICE_IS_MASTER, TRUE, + NULL); } + +DEFINE_DEVICE_FACTORY_INTERNAL(BOND, Bond, bond, + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-bond.h b/src/devices/nm-device-bond.h index f4683ad8..17217a57 100644 --- a/src/devices/nm-device-bond.h +++ b/src/devices/nm-device-bond.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_BOND_H -#define NM_DEVICE_BOND_H +#ifndef __NETWORKMANAGER_DEVICE_BOND_H__ +#define __NETWORKMANAGER_DEVICE_BOND_H__ #include <glib-object.h> @@ -34,29 +34,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) #define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) -typedef enum { - NM_BOND_ERROR_CONNECTION_NOT_BOND = 0, /*< nick=ConnectionNotBond >*/ - NM_BOND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBondError; - #define NM_DEVICE_BOND_SLAVES "slaves" -typedef struct { - NMDevice parent; -} NMDeviceBond; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceBondClass; - +typedef NMDevice NMDeviceBond; +typedef NMDeviceClass NMDeviceBondClass; GType nm_device_bond_get_type (void); -NMDevice *nm_device_bond_new (NMPlatformLink *platform_device); -NMDevice *nm_device_bond_new_for_connection (NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_BOND_H */ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index edc41838..a70cfd95 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -23,29 +23,29 @@ #include <glib.h> #include <glib/gi18n.h> -#include <netinet/ether.h> #include <stdlib.h> #include "gsystem-local-alloc.h" #include "nm-device-bridge.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" #include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-bridge-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBridge); G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) #define NM_DEVICE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgePrivate)) -#define NM_BRIDGE_ERROR (nm_bridge_error_quark ()) - typedef struct { int dummy; } NMDeviceBridgePrivate; @@ -59,17 +59,6 @@ enum { /******************************************************************/ -static GQuark -nm_bridge_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bridge-error"); - return quark; -} - -/******************************************************************/ - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -100,7 +89,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) { const char *iface; NMSettingBridge *s_bridge; - const GByteArray *mac_address; + const char *mac_address; if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -110,19 +99,16 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; /* Bridge connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; mac_address = nm_setting_bridge_get_mac_address (s_bridge); if (mac_address) { - guint hw_len; - const guint8 *hw_addr; + const char *hw_addr; - hw_addr = nm_device_get_hw_address (device, &hw_len); - if ( !hw_addr - || hw_len != mac_address->len - || memcmp (mac_address->data, hw_addr, hw_len) != 0) + hw_addr = nm_device_get_hw_address (device); + if (!hw_addr || !nm_utils_hwaddr_matches (hw_addr, -1, mac_address, -1)) return FALSE; } @@ -136,17 +122,14 @@ complete_connection (NMDevice *device, const GSList *existing_connections, GError **error) { - NMSettingBridge *s_bridge, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; + NMSettingBridge *s_bridge; nm_utils_complete_generic (connection, NM_SETTING_BRIDGE_SETTING_NAME, existing_connections, - _("Bridge connection %d"), NULL, + _("Bridge connection"), + "bridge", TRUE); s_bridge = nm_connection_get_setting_bridge (connection); @@ -155,34 +138,6 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_bridge)); } - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_bridge_get_interface_name (s_bridge)) { - name = g_strdup_printf ("br%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing bridge connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_bridge (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_BRIDGE_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_bridge_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_bridge), NM_SETTING_BRIDGE_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - return TRUE; } @@ -292,15 +247,14 @@ commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) static void update_connection (NMDevice *device, NMConnection *connection) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); - const char *ifname = nm_device_get_iface (device); int ifindex = nm_device_get_ifindex (device); const Option *option; if (!s_bridge) { s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); nm_connection_add_setting (connection, (NMSetting *) s_bridge); - g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, ifname, NULL); } for (option = master_options; option->name; option++) { @@ -315,34 +269,27 @@ update_connection (NMDevice *device, NMConnection *connection) value /= 100; g_object_set (s_bridge, option->name, value, NULL); - } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to read bridge setting '%s'", - nm_device_get_iface (device), option->sysname); - } + } else + _LOGW (LOGD_BRIDGE, "failed to read bridge setting '%s'", option->sysname); } } -/** - * nm_bridge_update_slave_connection: - * @slave: the slave #NMDevice, is *not* necessarily a bridge interface - * @connection: the #NMConnection to update with the bridge port settings - * - * Reads bridge port configuration and updates @connection with those - * properties. - * - * Returns: %TRUE if the port configuration was read and @connection updated, - * %FALSE if not. - */ -gboolean -nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) +static gboolean +master_update_slave_connection (NMDevice *device, + NMDevice *slave, + NMConnection *connection, + GError **error) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + NMSettingConnection *s_con; NMSettingBridgePort *s_port; - int ifindex = nm_device_get_ifindex (slave); + int ifindex_slave = nm_device_get_ifindex (slave); + const char *iface = nm_device_get_iface (device); const Option *option; - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (ifindex_slave > 0, FALSE); + s_con = nm_connection_get_setting_connection (connection); s_port = nm_connection_get_setting_bridge_port (connection); if (!s_port) { s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); @@ -350,7 +297,7 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) } for (option = slave_options; option->name; option++) { - gs_free char *str = nm_platform_slave_get_option (ifindex, option->sysname); + gs_free char *str = nm_platform_slave_get_option (ifindex_slave, option->sysname); int value; if (str) { @@ -361,12 +308,14 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) value /= 100; g_object_set (s_port, option->name, value, NULL); - } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to read bridge port setting '%s'", - nm_device_get_iface (slave), option->sysname); - } + } else + _LOGW (LOGD_BRIDGE, "failed to read bridge port setting '%s'", option->sysname); } + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, + NULL); return TRUE; } @@ -393,19 +342,19 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + if (configure) { if (!nm_platform_link_enslave (nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave))) return FALSE; commit_slave_options (slave, nm_connection_get_setting_bridge_port (connection)); - nm_log_info (LOGD_BRIDGE, "(%s): attached bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "attached bridge port %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_info (LOGD_BRIDGE, "(%s): bridge port %s was attached", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "bridge port %s was attached", + nm_device_get_ip_iface (slave)); } g_object_notify (G_OBJECT (device), NM_DEVICE_BRIDGE_SLAVES); @@ -418,6 +367,7 @@ release_slave (NMDevice *device, NMDevice *slave, gboolean configure) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); gboolean success = TRUE; if (configure) { @@ -425,18 +375,15 @@ release_slave (NMDevice *device, nm_device_get_ip_ifindex (slave)); if (success) { - nm_log_info (LOGD_BRIDGE, "(%s): detached bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "detached bridge port %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to detach bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGW (LOGD_BRIDGE, "failed to detach bridge port %s", + nm_device_get_ip_iface (slave)); } } else { - nm_log_info (LOGD_BRIDGE, "(%s): bridge port %s was detached", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "bridge port %s was detached", + nm_device_get_ip_iface (slave)); } g_object_notify (G_OBJECT (device), NM_DEVICE_BRIDGE_SLAVES); @@ -445,66 +392,6 @@ release_slave (NMDevice *device, /******************************************************************/ -NMDevice * -nm_device_bridge_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_DRIVER, "bridge", - NM_DEVICE_TYPE_DESC, "Bridge", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -NMDevice * -nm_device_bridge_new_for_connection (NMConnection *connection) -{ - const char *iface; - NMSettingBridge *s_bridge; - const GByteArray *mac_address; - - g_return_val_if_fail (connection != NULL, NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - s_bridge = nm_connection_get_setting_bridge (connection); - g_return_val_if_fail (s_bridge, NULL); - - mac_address = nm_setting_bridge_get_mac_address (s_bridge); - - if ( !nm_platform_bridge_add (iface, - mac_address ? mac_address->data : NULL, - mac_address ? mac_address->len : 0) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bridge", - NM_DEVICE_TYPE_DESC, "Bridge", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_bridge_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_BRIDGE, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - static void nm_device_bridge_init (NMDeviceBridge * self) { @@ -518,7 +405,6 @@ get_property (GObject *object, guint prop_id, GSList *list, *iter; switch (prop_id) { - break; case PROP_SLAVES: slaves = g_ptr_array_new (); list = nm_device_master_get_slaves (NM_DEVICE (object)); @@ -555,7 +441,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->connection_type = NM_SETTING_BRIDGE_SETTING_NAME; /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; @@ -566,6 +451,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; @@ -574,15 +460,85 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bridge_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_BRIDGE_ERROR, NULL, NM_TYPE_BRIDGE_ERROR); +#define NM_TYPE_BRIDGE_FACTORY (nm_bridge_factory_get_type ()) +#define NM_BRIDGE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BRIDGE_FACTORY, NMBridgeFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_BRIDGE) { + 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); + } + return NULL; } + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + const char *iface; + NMSettingBridge *s_bridge; + const char *mac_address_str; + guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; + + if (!nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (connection != NULL, NULL); + + iface = nm_connection_get_interface_name (connection); + g_return_val_if_fail (iface != NULL, NULL); + + s_bridge = nm_connection_get_setting_bridge (connection); + g_return_val_if_fail (s_bridge, NULL); + + 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; + } + + if ( !nm_platform_bridge_add (iface, + mac_address_str ? mac_address : NULL, + mac_address_str ? ETH_ALEN : 0) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bridge", + NM_DEVICE_TYPE_DESC, "Bridge", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, + NM_DEVICE_IS_MASTER, TRUE, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL(BRIDGE, Bridge, bridge, + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index 4194f5a4..c11a2c40 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_BRIDGE_H -#define NM_DEVICE_BRIDGE_H +#ifndef __NETWORKMANAGER_DEVICE_BRIDGE_H__ +#define __NETWORKMANAGER_DEVICE_BRIDGE_H__ #include <glib-object.h> @@ -34,31 +34,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BRIDGE)) #define NM_DEVICE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) -typedef enum { - NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE = 0, /*< nick=ConnectionNotBridge >*/ - NM_BRIDGE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBridgeError; - #define NM_DEVICE_BRIDGE_SLAVES "slaves" -typedef struct { - NMDevice parent; -} NMDeviceBridge; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceBridgeClass; - +typedef NMDevice NMDeviceBridge; +typedef NMDeviceClass NMDeviceBridgeClass; GType nm_device_bridge_get_type (void); -NMDevice *nm_device_bridge_new (NMPlatformLink *platform_device); -NMDevice *nm_device_bridge_new_for_connection (NMConnection *connection); - -gboolean nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_BRIDGE_H */ diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c new file mode 100644 index 00000000..585f6a0e --- /dev/null +++ b/src/devices/nm-device-ethernet-utils.c @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* 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. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> +#include <glib.h> +#include <glib/gi18n.h> + +#include <nm-connection.h> +#include "nm-device-ethernet-utils.h" + +char * +nm_device_ethernet_utils_get_default_wired_name (const GSList *connections) +{ + const GSList *iter; + char *cname = NULL; + int i = 0; + + /* Find the next available unique connection name */ + while (!cname && (i++ < 10000)) { + char *temp; + gboolean found = FALSE; + + temp = g_strdup_printf (_("Wired connection %d"), i); + for (iter = connections; iter; iter = iter->next) { + if (g_strcmp0 (nm_connection_get_id (NM_CONNECTION (iter->data)), temp) == 0) { + found = TRUE; + g_free (temp); + break; + } + } + + if (found == FALSE) + cname = temp; + } + + return cname; +} + diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h new file mode 100644 index 00000000..5848f7e6 --- /dev/null +++ b/src/devices/nm-device-ethernet-utils.h @@ -0,0 +1,26 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* 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. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ +#define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ + +#include <glib.h> + +char *nm_device_ethernet_utils_get_default_wired_name (const GSList *connections); + +#endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index f4a90c74..ac408d3d 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -20,6 +20,7 @@ */ #include "config.h" + #include <glib.h> #include <glib/gi18n.h> #include <netinet/in.h> @@ -30,9 +31,7 @@ #include <linux/version.h> #include <sys/ioctl.h> #include <unistd.h> -#include <linux/if.h> #include <errno.h> -#include <netinet/ether.h> #include <gudev/gudev.h> @@ -44,22 +43,23 @@ #include "nm-supplicant-manager.h" #include "nm-supplicant-interface.h" #include "nm-supplicant-config.h" -#include "nm-setting-connection.h" -#include "nm-setting-wired.h" -#include "nm-setting-8021x.h" -#include "nm-setting-pppoe.h" -#include "nm-setting-bond.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-logging.h" -#include "nm-utils.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" #include "nm-platform.h" #include "nm-dcb.h" #include "nm-settings-connection.h" +#include "nm-config.h" +#include "nm-device-ethernet-utils.h" +#include "nm-connection-provider.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-ethernet-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceEthernet); G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) @@ -69,8 +69,6 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) #define PPPOE_RECONNECT_DELAY 7 -#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ()) - static NMSetting *device_get_setting (NMDevice *device, GType setting_type); typedef struct Supplicant { @@ -101,8 +99,8 @@ typedef enum { } DcbWait; typedef struct { - guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ - guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ + char * perm_hw_addr; /* Permanent MAC address */ + char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */ guint32 speed; @@ -138,15 +136,6 @@ enum { }; -static GQuark -nm_ethernet_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-ethernet-error"); - return quark; -} - static char * get_link_basename (const char *parent_path, const char *name, GError **error) { @@ -167,7 +156,6 @@ static void _update_s390_subchannels (NMDeviceEthernet *self) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const char *iface; GUdevClient *client; GUdevDevice *dev; GUdevDevice *parent = NULL; @@ -176,17 +164,16 @@ _update_s390_subchannels (NMDeviceEthernet *self) GDir *dir; GError *error = NULL; - iface = nm_device_get_iface (NM_DEVICE (self)); - client = g_udev_client_new (subsystems); if (!client) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to initialize GUdev client", iface); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to initialize GUdev client"); return; } - dev = g_udev_client_query_by_subsystem_and_name (client, "net", iface); + dev = g_udev_client_query_by_subsystem_and_name (client, "net", + nm_device_get_iface (NM_DEVICE (self))); if (!dev) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to find device with udev", iface); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to find device with udev"); goto out; } @@ -203,9 +190,8 @@ _update_s390_subchannels (NMDeviceEthernet *self) parent_path = g_udev_device_get_sysfs_path (parent); dir = g_dir_open (parent_path, 0, &error); if (!dir) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to open directory '%s': %s", - iface, parent_path, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to open directory '%s': %s", + parent_path, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); goto out; } @@ -228,12 +214,12 @@ _update_s390_subchannels (NMDeviceEthernet *self) if (value && *value) g_hash_table_insert (priv->s390_options, g_strdup (item), g_strdup (value)); else - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): error reading %s", iface, path); + _LOGW (LOGD_DEVICE | LOGD_HW, "error reading %s", path); g_free (path); g_free (value); } if (error) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): %s", iface, error->message); + _LOGW (LOGD_DEVICE | LOGD_HW, "%s", error->message); g_clear_error (&error); } } @@ -253,9 +239,8 @@ _update_s390_subchannels (NMDeviceEthernet *self) priv->subchannels = g_strdup (priv->subchan1); driver = nm_device_get_driver (NM_DEVICE (self)); - nm_log_info (LOGD_DEVICE | LOGD_HW, - "(%s): found s390 '%s' subchannels [%s]", - iface, driver ? driver : "(unknown driver)", priv->subchannels); + _LOGI (LOGD_DEVICE | LOGD_HW, "found s390 '%s' subchannels [%s]", + driver ? driver : "(unknown driver)", priv->subchannels); out: if (parent) @@ -271,25 +256,22 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; - NMDevice *self; - int ifindex; object = G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructor (type, n_construct_params, construct_params); if (object) { - self = NM_DEVICE (object); - ifindex = nm_device_get_ifindex (self); +#ifndef G_DISABLE_ASSERT + int ifindex = nm_device_get_ifindex (NM_DEVICE (object)); + NMLinkType link_type = nm_platform_link_get_type (ifindex); - g_assert ( nm_platform_link_get_type (ifindex) == NM_LINK_TYPE_ETHERNET - || nm_platform_link_get_type (ifindex) == NM_LINK_TYPE_VETH); - - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); + g_assert ( link_type == NM_LINK_TYPE_ETHERNET + || link_type == NM_LINK_TYPE_VETH + || link_type == NM_LINK_TYPE_NONE); +#endif /* s390 stuff */ - _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); + _update_s390_subchannels (NM_DEVICE_ETHERNET (object)); } return object; @@ -328,18 +310,6 @@ nm_device_ethernet_init (NMDeviceEthernet *self) priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } -NMDevice * -nm_device_ethernet_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Ethernet", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, - NULL); -} - static void update_permanent_hw_address (NMDevice *dev) { @@ -347,12 +317,14 @@ update_permanent_hw_address (NMDevice *dev) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); struct ifreq req; struct ethtool_perm_addr *epaddr = NULL; - int fd, ret; - const guint8 *mac; + int fd, ret, errsv; + const char *mac; + + g_return_if_fail (priv->perm_hw_addr == NULL); fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); + _LOGW (LOGD_HW, "couldn't open control socket."); return; } @@ -367,21 +339,18 @@ update_permanent_hw_address (NMDevice *dev) errno = 0; ret = ioctl (fd, SIOCETHTOOL, &req); - if ((ret < 0) || !nm_ethernet_address_is_valid ((struct ether_addr *) epaddr->data)) { - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", - nm_device_get_iface (dev), errno); + errsv = errno; + if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) { + _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)", errsv); /* Fall back to current address */ - mac = nm_device_get_hw_address (dev, NULL); + mac = nm_device_get_hw_address (dev); if (mac) - memcpy (epaddr->data, mac, ETH_ALEN); + nm_utils_hwaddr_aton (mac, epaddr->data, ETH_ALEN); else memset (epaddr->data, 0, ETH_ALEN); } - if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { - memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN); - g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); - } + priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN); g_free (epaddr); close (fd); @@ -392,32 +361,25 @@ update_initial_hw_address (NMDevice *dev) { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - char *mac_str; - const guint8 *mac; /* This sets initial MAC address from current MAC address. It should only * be called from NMDevice constructor() to really get the initial address. */ - mac = nm_device_get_hw_address (dev, NULL); - if (mac) - memcpy (priv->initial_hw_addr, mac, ETH_ALEN); - - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev)); + + _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr); } static guint32 -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities (NMDevice *device) { - if (nm_platform_link_supports_carrier_detect (nm_device_get_ifindex (dev))) + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + + if (nm_platform_link_supports_carrier_detect (nm_device_get_ifindex (device))) return NM_DEVICE_CAP_CARRIER_DETECT; else { - nm_log_info (LOGD_HW, - "(%s): driver '%s' does not support carrier detection.", - nm_device_get_iface (dev), - nm_device_get_driver (dev)); + _LOGI (LOGD_HW, "driver '%s' does not support carrier detection.", + nm_device_get_driver (device)); return NM_DEVICE_CAP_NONE; } } @@ -426,7 +388,7 @@ static gboolean match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const GPtrArray *subchans; + const char * const *subchans; int i; *try_mac = TRUE; @@ -440,8 +402,8 @@ match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_m return FALSE; /* Make sure each subchannel in the connection is a subchannel of this device */ - for (i = 0; i < subchans->len; i++) { - const char *candidate = g_ptr_array_index (subchans, i); + for (i = 0; subchans[i]; i++) { + const char *candidate = subchans[i]; if ( (priv->subchan1 && !strcmp (priv->subchan1, candidate)) || (priv->subchan2 && !strcmp (priv->subchan2, candidate)) @@ -476,29 +438,27 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; if (s_wired) { - const GByteArray *mac; + const char *mac; gboolean try_mac = TRUE; - const GSList *mac_blacklist, *mac_blacklist_iter; + const char * const *mac_blacklist; + int i; if (!match_subchans (self, s_wired, &try_mac)) return FALSE; mac = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) + if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1)) return FALSE; /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { g_warn_if_reached (); return FALSE; } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1)) return FALSE; } } @@ -588,14 +548,15 @@ wired_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDevice *dev = NM_DEVICE (self); g_return_if_fail (req == nm_device_get_act_request (dev)); g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); g_return_if_fail (nm_act_request_get_connection (req) == connection); if (error) { - nm_log_warn (LOGD_ETHER, "%s", error->message); + _LOGW (LOGD_ETHER, "%s", error->message); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); @@ -637,16 +598,14 @@ link_timeout_cb (gpointer user_data) if (!setting_name) goto time_out; - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): disconnected during authentication," - " asking for new key.", - nm_device_get_iface (dev)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) disconnected during authentication, asking for new key."); supplicant_interface_release (self); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wired_secrets_cb, self); @@ -654,8 +613,7 @@ link_timeout_cb (gpointer user_data) return FALSE; time_out: - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "(%s): link timed out.", nm_device_get_iface (dev)); + _LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out."); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); return FALSE; @@ -677,7 +635,7 @@ build_supplicant_config (NMDeviceEthernet *self) security = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, TRUE)) { - nm_log_warn (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); + _LOGW (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); g_object_unref (config); config = NULL; } @@ -702,11 +660,9 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (new_state == old_state) return; - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "(%s): supplicant interface state: %s -> %s", - nm_device_get_iface (device), - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, "supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string (old_state), + nm_supplicant_interface_state_to_string (new_state)); devstate = nm_device_get_state (device); @@ -718,15 +674,12 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, g_object_unref (config); if (!success) { - nm_log_err (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): couldn't send security " - "configuration to the supplicant.", - nm_device_get_iface (device)); + _LOGE (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) couldn't send security configuration to the supplicant."); } } else { - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): couldn't build security configuration.", - nm_device_get_iface (device)); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) couldn't build security configuration."); } if (!success) { @@ -743,9 +696,8 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, * schedule the next activation stage. */ if (devstate == NM_DEVICE_STATE_CONFIG) { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.", - nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) Stage 2 of 5 (Device Configure) successful."); nm_device_activate_schedule_stage3_ip_config_start (device); } break; @@ -794,9 +746,9 @@ supplicant_iface_connection_error_cb (NMSupplicantInterface *iface, NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); guint id; - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): association request to the supplicant failed: %s - %s", - nm_device_get_iface (NM_DEVICE (self)), name, message); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) association request to the supplicant failed: %s - %s", + name, message); if (priv->supplicant.iface_con_error_cb_id) g_source_remove (priv->supplicant.iface_con_error_cb_id); @@ -826,16 +778,15 @@ handle_auth_or_fail (NMDeviceEthernet *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (new_secrets) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); - } else { - nm_log_info (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - } + } else + _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -848,19 +799,16 @@ supplicant_connection_timeout_cb (gpointer user_data) NMDevice *device = NM_DEVICE (self); NMActRequest *req; NMConnection *connection; - const char *iface; guint64 timestamp = 0; gboolean new_secrets = TRUE; priv->supplicant.con_timeout_id = 0; - iface = nm_device_get_iface (device); - /* Authentication failed; either driver problems, the encryption key is * wrong, the passwords or certificates were wrong or the Ethernet switch's * port is not configured for 802.1x. */ - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): association took too long.", iface); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) association took too long."); supplicant_interface_release (self); req = nm_device_get_act_request (device); @@ -876,10 +824,9 @@ supplicant_connection_timeout_cb (gpointer user_data) if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) new_secrets = !timestamp; - if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): asking for new secrets", iface); - } else + if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) + _LOGW (LOGD_DEVICE | LOGD_ETHER, "Activation: (ethernet) asking for new secrets"); + else nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); return FALSE; @@ -889,16 +836,14 @@ static gboolean supplicant_interface_init (NMDeviceEthernet *self) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const char *iface; - - iface = nm_device_get_iface (NM_DEVICE (self)); /* Create supplicant interface */ - priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, iface, FALSE); + priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, + nm_device_get_iface (NM_DEVICE (self)), + FALSE); if (!priv->supplicant.iface) { - nm_log_err (LOGD_DEVICE | LOGD_ETHER, - "Couldn't initialize supplicant interface for %s.", - iface); + _LOGE (LOGD_DEVICE | LOGD_ETHER, + "Couldn't initialize supplicant interface"); supplicant_interface_release (self); return FALSE; } @@ -924,13 +869,12 @@ supplicant_interface_init (NMDeviceEthernet *self) static gboolean pppoe_reconnect_delay (gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); priv->pppoe_wait_id = 0; - nm_log_info (LOGD_DEVICE, "(%s) PPPoE reconnect delay complete, resuming connection...", - nm_device_get_iface (device)); - nm_device_activate_schedule_stage2_device_config (device); + _LOGI (LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection..."); + nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self)); return FALSE; } @@ -941,7 +885,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMActRequest *req; NMSettingWired *s_wired; - const GByteArray *cloned_mac; + const char *cloned_mac; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -955,8 +899,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, cloned_mac->data, "set", LOGD_ETHER); + if (cloned_mac) + nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_ETHER); } /* If we're re-activating a PPPoE connection a short while after @@ -968,8 +912,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) gint32 delay = nm_utils_get_monotonic_timestamp_s () - priv->last_pppoe_time; if (delay < PPPOE_RECONNECT_DELAY && device_get_setting (dev, NM_TYPE_SETTING_PPPOE)) { - nm_log_info (LOGD_DEVICE, "(%s) delaying PPPoE reconnect for %d seconds to ensure peer is ready...", - nm_device_get_iface (dev), delay); + _LOGI (LOGD_DEVICE, "delaying PPPoE reconnect for %d seconds to ensure peer is ready...", + delay); g_assert (!priv->pppoe_wait_id); priv->pppoe_wait_id = g_timeout_add_seconds (delay, pppoe_reconnect_delay, @@ -990,14 +934,13 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) NMConnection *connection; NMSetting8021x *security; const char *setting_name; - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; connection = nm_device_get_connection (NM_DEVICE (self)); g_assert (connection); security = nm_connection_get_setting_802_1x (connection); if (!security) { - nm_log_err (LOGD_DEVICE, "Invalid or missing 802.1X security"); + _LOGE (LOGD_DEVICE, "Invalid or missing 802.1X security"); *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; return ret; } @@ -1005,24 +948,22 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) if (!priv->supplicant.mgr) priv->supplicant.mgr = nm_supplicant_manager_get (); - iface = nm_device_get_iface (NM_DEVICE (self)); - /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self)); - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): connection '%s' has security, but secrets are required.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' has security, but secrets are required.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, req, FALSE); if (ret != NM_ACT_STAGE_RETURN_POSTPONE) *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } else { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): connection '%s' requires no security. No secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id (connection)); if (supplicant_interface_init (self)) ret = NM_ACT_STAGE_RETURN_POSTPONE; @@ -1073,7 +1014,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMConnection *connection; - NMSettingPPPOE *s_pppoe; + NMSettingPppoe *s_pppoe; NMActRequest *req; GError *err = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; @@ -1097,8 +1038,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { - nm_log_warn (LOGD_DEVICE, "(%s): PPPoE failed to start: %s", - nm_device_get_iface (NM_DEVICE (self)), err->message); + _LOGW (LOGD_DEVICE, "PPPoE failed to start: %s", err->message); g_error_free (err); g_object_unref (priv->ppp_manager); @@ -1139,17 +1079,16 @@ static void dcb_state (NMDevice *device, gboolean timeout); static gboolean dcb_carrier_timeout (gpointer user_data) { + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); g_return_val_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE); priv->dcb_timeout_id = 0; if (priv->dcb_wait != DCB_WAIT_CARRIER_POSTCONFIG_DOWN) { - nm_log_warn (LOGD_DCB, - "(%s): DCB: timed out waiting for carrier (step %d)", - nm_device_get_iface (device), - priv->dcb_wait); + _LOGW (LOGD_DCB, "DCB: timed out waiting for carrier (step %d)", + priv->dcb_wait); } dcb_state (device, TRUE); return G_SOURCE_REMOVE; @@ -1158,19 +1097,18 @@ dcb_carrier_timeout (gpointer user_data) static gboolean dcb_configure (NMDevice *device) { + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingDcb *s_dcb; - const char *iface = nm_device_get_iface (device); GError *error = NULL; dcb_timeout_cleanup (device); s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB); g_assert (s_dcb); - if (!nm_dcb_setup (iface, s_dcb, &error)) { - nm_log_warn (LOGD_DCB, - "Activation (%s/wired) failed to enable DCB/FCoE: %s", - iface, error->message); + if (!nm_dcb_setup (nm_device_get_iface (device), s_dcb, &error)) { + _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", + error->message); g_clear_error (&error); return FALSE; } @@ -1178,7 +1116,7 @@ dcb_configure (NMDevice *device) /* Pause again just in case the device takes the carrier down when * setting specific DCB attributes. */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (postconfig down)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (postconfig down)"); priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_DOWN; priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); return TRUE; @@ -1187,15 +1125,14 @@ dcb_configure (NMDevice *device) static gboolean dcb_enable (NMDevice *device) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); GError *error = NULL; dcb_timeout_cleanup (device); - if (!nm_dcb_enable (iface, TRUE, &error)) { - nm_log_warn (LOGD_DCB, - "Activation (%s/wired) failed to enable DCB/FCoE: %s", - iface, error->message); + if (!nm_dcb_enable (nm_device_get_iface (device), TRUE, &error)) { + _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", + error->message); g_clear_error (&error); return FALSE; } @@ -1207,7 +1144,7 @@ dcb_enable (NMDevice *device) * is down. But NM might get the carrier-down signal long after calling * "dcbtool dcb on", so we have to first wait for the carrier to go down. */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preconfig down)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (preconfig down)"); priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_DOWN; priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); return TRUE; @@ -1216,25 +1153,25 @@ dcb_enable (NMDevice *device) static void dcb_state (NMDevice *device, gboolean timeout) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); gboolean carrier; g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); carrier = nm_platform_link_is_connected (nm_device_get_ifindex (device)); - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() wait %d carrier %d timeout %d", iface, priv->dcb_wait, carrier, timeout); + _LOGD (LOGD_DCB, "dcb_state() wait %d carrier %d timeout %d", priv->dcb_wait, carrier, timeout); switch (priv->dcb_wait) { case DCB_WAIT_CARRIER_PREENABLE_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() enabling DCB", iface); + _LOGD (LOGD_DCB, "dcb_state() enabling DCB"); dcb_timeout_cleanup (device); if (!dcb_enable (device)) { dcb_carrier_cleanup (device); nm_device_state_changed (device, - NM_ACT_STAGE_RETURN_FAILURE, + NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); } } @@ -1245,20 +1182,20 @@ dcb_state (NMDevice *device, gboolean timeout) if (!carrier) { /* Wait for the carrier to come back up */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preconfig up)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (preconfig up)"); priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); break; } - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() preconfig down falling through", iface); + _LOGD (LOGD_DCB, "dcb_state() preconfig down falling through"); /* carrier never went down? fall through */ case DCB_WAIT_CARRIER_PRECONFIG_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() preconfig up configuring DCB", iface); + _LOGD (LOGD_DCB, "dcb_state() preconfig up configuring DCB"); dcb_timeout_cleanup (device); if (!dcb_configure (device)) { dcb_carrier_cleanup (device); nm_device_state_changed (device, - NM_ACT_STAGE_RETURN_FAILURE, + NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); } } @@ -1269,15 +1206,15 @@ dcb_state (NMDevice *device, gboolean timeout) if (!carrier) { /* Wait for the carrier to come back up */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (postconfig up)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (postconfig up)"); priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); break; } - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() postconfig down falling through", iface); + _LOGD (LOGD_DCB, "dcb_state() postconfig down falling through"); /* carrier never went down? fall through */ case DCB_WAIT_CARRIER_POSTCONFIG_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() postconfig up starting IP", iface); + _LOGD (LOGD_DCB, "dcb_state() postconfig up starting IP"); dcb_timeout_cleanup (device); dcb_carrier_cleanup (device); priv->dcb_wait = DCB_WAIT_UNKNOWN; @@ -1292,12 +1229,13 @@ dcb_state (NMDevice *device, gboolean timeout) static void dcb_carrier_changed (NMDevice *device, GParamSpec *pspec, gpointer unused) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); if (priv->dcb_timeout_id) { - nm_log_dbg (LOGD_DCB, "(%s): carrier_changed() calling dcb_state()", nm_device_get_iface (device)); + _LOGD (LOGD_DCB, "carrier_changed() calling dcb_state()"); dcb_state (device, FALSE); } } @@ -1307,7 +1245,8 @@ dcb_carrier_changed (NMDevice *device, GParamSpec *pspec, gpointer unused) static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMSettingConnection *s_con; const char *connection_type; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; @@ -1331,7 +1270,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) security = (NMSetting8021x *) device_get_setting (device, NM_TYPE_SETTING_802_1X); if (security) { /* FIXME: for now 802.1x is mutually exclusive with DCB */ - return nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device), reason); + return nm_8021x_stage2_config (self, reason); } } @@ -1345,8 +1284,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_FAILURE; } } else { - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preenable up)", - nm_device_get_iface (device)); + _LOGD (LOGD_DCB, "waiting for carrier (preenable up)"); priv->dcb_wait = DCB_WAIT_CARRIER_PREENABLE_UP; priv->dcb_timeout_id = g_timeout_add_seconds (4, dcb_carrier_timeout, device); } @@ -1403,7 +1341,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) /* MTU override */ mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static void @@ -1442,9 +1380,8 @@ deactivate (NMDevice *device) s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB); if (s_dcb) { if (!nm_dcb_cleanup (nm_device_get_iface (device), &error)) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, - "(%s) failed to disable DCB/FCoE: %s", - nm_device_get_iface (device), error->message); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to disable DCB/FCoE: %s", + error->message); g_clear_error (&error); } } @@ -1454,7 +1391,8 @@ deactivate (NMDevice *device) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s (); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER); } static gboolean @@ -1466,8 +1404,8 @@ complete_connection (NMDevice *device, { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingWired *s_wired; - NMSettingPPPOE *s_pppoe; - const GByteArray *setting_mac; + NMSettingPppoe *s_pppoe; + const char *setting_mac; s_pppoe = nm_connection_get_setting_pppoe (connection); @@ -1483,7 +1421,8 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME, existing_connections, - s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"), + NULL, + s_pppoe ? _("PPPoE connection") : _("Wired connection"), NULL, s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ @@ -1496,29 +1435,66 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) { g_set_error_literal (error, - NM_SETTING_WIRED_ERROR, - NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_MAC_ADDRESS); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - - /* Lock the connection to this device by default */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); - g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) { + g_object_set (G_OBJECT (s_wired), + NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, + NULL); } } return TRUE; } +static NMConnection * +new_default_connection (NMDevice *self) +{ + NMConnection *connection; + const GSList *connections; + NMSetting *setting; + const char *hw_address; + char *defname, *uuid; + + if (!nm_config_get_ethernet_can_auto_default (nm_config_get (), self)) + return NULL; + + hw_address = nm_device_get_hw_address (self); + if (!hw_address) + return NULL; + + connection = nm_simple_connection_new (); + setting = nm_setting_connection_new (); + nm_connection_add_setting (connection, setting); + + connections = nm_connection_provider_get_connections (nm_connection_provider_get ()); + defname = nm_device_ethernet_utils_get_default_wired_name (connections); + uuid = nm_utils_uuid_generate (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, defname, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), + NULL); + g_free (uuid); + g_free (defname); + + /* Lock the connection to the device */ + setting = nm_setting_wired_new (); + g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, hw_address, NULL); + nm_connection_add_setting (connection, setting); + + return connection; +} + static gboolean spec_match_list (NMDevice *device, const GSList *specs) { @@ -1535,11 +1511,8 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); - guint maclen; - const guint8 *mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + const char *mac = nm_device_get_hw_address (device); const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; - GByteArray *array; GHashTableIter iter; gpointer key, value; @@ -1551,37 +1524,29 @@ update_connection (NMDevice *device, NMConnection *connection) /* If the device reports a permanent address, use that for the MAC address * and the current MAC, if different, is the cloned MAC. */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, priv->perm_hw_addr, ETH_ALEN); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, array, NULL); - g_byte_array_unref (array); + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) { + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, NULL); mac_prop = NULL; - if (mac && memcmp (priv->perm_hw_addr, mac, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, mac, -1)) mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS; } - if (mac_prop && mac && maclen == ETH_ALEN) { - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, (guint8 *) mac, maclen); - g_object_set (s_wired, mac_prop, array, NULL); - g_byte_array_unref (array); - } + if (mac_prop && mac && nm_utils_hwaddr_valid (mac, ETH_ALEN)) + g_object_set (s_wired, mac_prop, mac, NULL); /* We don't set the MTU as we don't know whether it was set explicitly */ /* s390 */ if (priv->subchannels) { - GPtrArray *subchan_arr = g_ptr_array_sized_new (3); - if (priv->subchan1) - g_ptr_array_add (subchan_arr, priv->subchan1); - if (priv->subchan2) - g_ptr_array_add (subchan_arr, priv->subchan2); - if (priv->subchan3) - g_ptr_array_add (subchan_arr, priv->subchan3); - g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, NULL); - g_ptr_array_free (subchan_arr, TRUE); + char **subchannels = g_new (char *, 3 + 1); + + subchannels[0] = g_strdup (priv->subchan1); + subchannels[1] = g_strdup (priv->subchan2); + subchannels[2] = g_strdup (priv->subchan3); + subchannels[3] = NULL; + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels, NULL); + g_strfreev (subchannels); } if (priv->s390_nettype) g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL); @@ -1595,7 +1560,8 @@ update_connection (NMDevice *device, NMConnection *connection) static void get_link_speed (NMDevice *device) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); struct ifreq ifr; struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET, @@ -1605,7 +1571,7 @@ get_link_speed (NMDevice *device) fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW | LOGD_ETHER, "couldn't open ethtool control socket."); + _LOGW (LOGD_HW | LOGD_ETHER, "couldn't open ethtool control socket."); return; } @@ -1633,8 +1599,7 @@ get_link_speed (NMDevice *device) priv->speed = speed; g_object_notify (G_OBJECT (device), "speed"); - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): speed is now %d Mb/s", - nm_device_get_iface (device), speed); + _LOGD (LOGD_HW | LOGD_ETHER, "speed is now %d Mb/s", speed); } static void @@ -1669,6 +1634,8 @@ finalize (GObject *object) NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + g_free (priv->perm_hw_addr); + g_free (priv->initial_hw_addr); g_clear_object (&priv->supplicant.mgr); g_free (priv->subchan1); g_free (priv->subchan2); @@ -1689,7 +1656,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); + g_value_set_string (value, priv->perm_hw_addr); break; case PROP_SPEED: g_value_set_uint (value, priv->speed); @@ -1733,6 +1700,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->update_initial_hw_address = update_initial_hw_address; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; + parent_class->new_default_connection = new_default_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->act_stage2_config = act_stage2_config; @@ -1748,23 +1716,42 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SPEED, - g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, - "Speed", - "Speed", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_ethernet_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_ETHERNET_ERROR, NULL, NM_TYPE_ETHERNET_ERROR); +#define NM_TYPE_ETHERNET_FACTORY (nm_ethernet_factory_get_type ()) +#define NM_ETHERNET_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ETHERNET_FACTORY, NMEthernetFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_ETHERNET) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Ethernet", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NULL); + } + return NULL; } + +DEFINE_DEVICE_FACTORY_INTERNAL(ETHERNET, Ethernet, ethernet, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-ethernet.h b/src/devices/nm-device-ethernet.h index bcaf270a..ad9ce856 100644 --- a/src/devices/nm-device-ethernet.h +++ b/src/devices/nm-device-ethernet.h @@ -19,8 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_ETHERNET_H -#define NM_DEVICE_ETHERNET_H +#ifndef __NETWORKMANAGER_DEVICE_ETHERNET_H__ +#define __NETWORKMANAGER_DEVICE_ETHERNET_H__ #include <glib-object.h> @@ -35,31 +35,14 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) #define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) -typedef enum -{ - NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED = 0, /*< nick=ConnectionNotWired >*/ - NM_ETHERNET_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMEthernetError; - #define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" -typedef struct { - NMDevice parent; -} NMDeviceEthernet; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceEthernetClass; - +typedef NMDevice NMDeviceEthernet; +typedef NMDeviceClass NMDeviceEthernetClass; GType nm_device_ethernet_get_type (void); - -NMDevice *nm_device_ethernet_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_ETHERNET_H */ diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index fc4d1c24..abfb8d4a 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -18,6 +18,8 @@ * Copyright (C) 2014 Red Hat, Inc. */ +#include "config.h" + #include "nm-device-factory.h" enum { @@ -27,6 +29,21 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +static GSList *internal_types = NULL; + +void +_nm_device_factory_internal_register_type (GType factory_type) +{ + g_return_if_fail (g_slist_find (internal_types, GUINT_TO_POINTER (factory_type)) == NULL); + internal_types = g_slist_prepend (internal_types, GUINT_TO_POINTER (factory_type)); +} + +const GSList * +nm_device_factory_get_internal_factory_types (void) +{ + return internal_types; +} + gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component) { @@ -91,6 +108,23 @@ nm_device_factory_get_type (void) return device_factory_type; } +NMDeviceType +nm_device_factory_get_device_type (NMDeviceFactory *factory) +{ + g_return_val_if_fail (factory != NULL, NM_DEVICE_TYPE_UNKNOWN); + + return NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_device_type (factory); +} + +void +nm_device_factory_start (NMDeviceFactory *factory) +{ + g_return_if_fail (factory != NULL); + + if (NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start) + NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start (factory); +} + NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, NMPlatformLink *plink, @@ -104,3 +138,21 @@ nm_device_factory_new_link (NMDeviceFactory *factory, return NULL; } +NMDevice * +nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + NMDeviceFactory *interface; + + g_return_val_if_fail (factory, NULL); + g_return_val_if_fail (connection, NULL); + g_return_val_if_fail (!error || !*error, NULL); + + interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory); + if (interface->create_virtual_device_for_connection) + return interface->create_virtual_device_for_connection (factory, connection, parent, error); + return NULL; +} + diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index f0e3dc19..ce672b8b 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -18,14 +18,13 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_DEVICE_FACTORY_H -#define NM_DEVICE_FACTORY_H +#ifndef __NETWORKMANAGER_DEVICE_FACTORY_H__ +#define __NETWORKMANAGER_DEVICE_FACTORY_H__ #include <glib.h> #include <glib-object.h> -#include "NetworkManager.h" -#include "nm-platform.h" +#include "nm-dbus-interface.h" #include "nm-device.h" /* WARNING: this file is private API between NetworkManager and its internal @@ -43,7 +42,7 @@ typedef struct _NMDeviceFactory NMDeviceFactory; * Creates a #GObject that implements the #NMDeviceFactory interface. This * function must not emit any signals or perform any actions that would cause * devices or components to be created immediately. Instead these should be - * deferred to an idle handler. + * deferred to the "start" interface method. * * Returns: the #GObject implementing #NMDeviceFactory or %NULL */ @@ -52,16 +51,6 @@ NMDeviceFactory *nm_device_factory_create (GError **error); /* Should match nm_device_factory_create() */ typedef NMDeviceFactory * (*NMDeviceFactoryCreateFunc) (GError **error); -/** - * nm_device_factory_get_device_type: - * - * Returns: the #NMDeviceType that this plugin creates - */ -NMDeviceType nm_device_factory_get_device_type (void); - -/* Should match nm_device_factory_get_device_type() */ -typedef NMDeviceType (*NMDeviceFactoryDeviceTypeFunc) (void); - /********************************************************************/ #define NM_TYPE_DEVICE_FACTORY (nm_device_factory_get_type ()) @@ -77,6 +66,25 @@ struct _NMDeviceFactory { GTypeInterface g_iface; /** + * get_device_type: + * @factory: the #NMDeviceFactory + * + * This function MUST be implemented. + * + * Returns: the #NMDeviceType that this plugin creates + */ + NMDeviceType (*get_device_type) (NMDeviceFactory *factory); + + /** + * start: + * @factory: the #NMDeviceFactory + * + * Start the factory and discover any existing devices that the factory + * can manage. + */ + void (*start) (NMDeviceFactory *factory); + + /** * new_link: * @factory: the #NMDeviceFactory * @link: the new link @@ -95,6 +103,25 @@ struct _NMDeviceFactory { NMPlatformLink *plink, 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); + + /* Signals */ /** @@ -124,13 +151,77 @@ struct _NMDeviceFactory { GType nm_device_factory_get_type (void); +NMDeviceType nm_device_factory_get_device_type (NMDeviceFactory *factory); + +void nm_device_factory_start (NMDeviceFactory *factory); + NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error); +NMDevice * nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error); + /* For use by implementations */ gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component); -#endif /* NM_DEVICE_FACTORY_H */ - +/************************************************************************** + * INTERNAL DEVICE FACTORY FUNCTIONS - devices provided by plugins should + * not use these functions. + **************************************************************************/ + +#define DEFINE_DEVICE_FACTORY_INTERNAL(upper, mixed, lower, dfi_code) \ + DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, upper, dfi_code) + +#define DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, devtype, dfi_code) \ + typedef GObject NM##mixed##Factory; \ + typedef GObjectClass NM##mixed##FactoryClass; \ + \ + static GType nm_##lower##_factory_get_type (void); \ + static void device_factory_interface_init (NMDeviceFactory *factory_iface); \ + \ + G_DEFINE_TYPE_EXTENDED (NM##mixed##Factory, nm_##lower##_factory, G_TYPE_OBJECT, 0, \ + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init) \ + _nm_device_factory_internal_register_type (g_define_type_id);) \ + \ + /* Use a module constructor to register the factory's GType at load \ + * time, which then calls _nm_device_factory_internal_register_type() \ + * to register the factory's GType with the Manager. \ + */ \ + static void __attribute__((constructor)) \ + register_device_factory_internal_##lower (void) \ + { \ + g_type_init (); \ + g_type_ensure (NM_TYPE_##upper##_FACTORY); \ + } \ + \ + static NMDeviceType \ + get_device_type (NMDeviceFactory *factory) \ + { \ + return NM_DEVICE_TYPE_##devtype; \ + } \ + \ + static void \ + device_factory_interface_init (NMDeviceFactory *factory_iface) \ + { \ + factory_iface->get_device_type = get_device_type; \ + dfi_code \ + } \ + \ + static void \ + nm_##lower##_factory_init (NM##mixed##Factory *self) \ + { \ + } \ + \ + static void \ + nm_##lower##_factory_class_init (NM##mixed##FactoryClass *lower##_class) \ + { \ + } + +void _nm_device_factory_internal_register_type (GType factory_type); +const GSList *nm_device_factory_get_internal_factory_types (void); + +#endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index 5261c133..f103ef83 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -24,9 +24,9 @@ #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-platform.h" -#include "nm-utils.h" #include "nm-glib-compat.h" #include "nm-dbus-manager.h" +#include "nm-core-internal.h" #include "nm-device-generic-glue.h" @@ -45,19 +45,6 @@ enum { LAST_PROP }; -#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) { @@ -203,15 +190,12 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_TYPE_DESCRIPTION, - g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, - "Type Description", - "Type description", + g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), 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/devices/nm-device-generic.h b/src/devices/nm-device-generic.h index e7b7090b..c889b1dd 100644 --- a/src/devices/nm-device-generic.h +++ b/src/devices/nm-device-generic.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_GENERIC_H -#define NM_DEVICE_GENERIC_H +#ifndef __NETWORKMANAGER_DEVICE_GENERIC_H__ +#define __NETWORKMANAGER_DEVICE_GENERIC_H__ #include <glib-object.h> @@ -34,13 +34,6 @@ G_BEGIN_DECLS #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_TYPE_DESCRIPTION "type-description" typedef struct { diff --git a/src/devices/nm-device-gre.c b/src/devices/nm-device-gre.c index 0412e993..9c25b398 100644 --- a/src/devices/nm-device-gre.c +++ b/src/devices/nm-device-gre.c @@ -21,6 +21,7 @@ #include "config.h" #include <string.h> +#include <arpa/inet.h> #include "nm-device-gre.h" #include "nm-device-private.h" @@ -28,9 +29,14 @@ #include "nm-logging.h" #include "nm-manager.h" #include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-gre-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceGre); + G_DEFINE_TYPE (NMDeviceGre, nm_device_gre, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_GRE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GRE, NMDeviceGrePrivate)) @@ -60,13 +66,13 @@ enum { static void update_properties (NMDevice *device) { - NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (device); + NMDeviceGre *self = NM_DEVICE_GRE (device); + NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (self); GObject *object = G_OBJECT (device); NMPlatformGreProperties props; if (!nm_platform_gre_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read gre properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read gre properties"); return; } @@ -107,18 +113,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_gre_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GRE, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Gre", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_gre_init (NMDeviceGre *self) { @@ -194,85 +188,98 @@ nm_device_gre_class_init (NMDeviceGreClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_GRE_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_GRE_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INPUT_FLAGS, - g_param_spec_uint (NM_DEVICE_GRE_INPUT_FLAGS, - "Input flags", - "Input flags", + g_param_spec_uint (NM_DEVICE_GRE_INPUT_FLAGS, "", "", 0, G_MAXUINT16, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_OUTPUT_FLAGS, - g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_FLAGS, - "Output flags", - "Output flags", + g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_FLAGS, "", "", 0, G_MAXUINT16, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INPUT_KEY, - g_param_spec_uint (NM_DEVICE_GRE_INPUT_KEY, - "Input key", - "Input key", + g_param_spec_uint (NM_DEVICE_GRE_INPUT_KEY, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_OUTPUT_KEY, - g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_KEY, - "Output key", - "Output key", + g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_KEY, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LOCAL, - g_param_spec_string (NM_DEVICE_GRE_LOCAL, - "Local", - "Local", + g_param_spec_string (NM_DEVICE_GRE_LOCAL, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_REMOTE, - g_param_spec_string (NM_DEVICE_GRE_REMOTE, - "Remote", - "Remote", + g_param_spec_string (NM_DEVICE_GRE_REMOTE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TTL, - g_param_spec_uchar (NM_DEVICE_GRE_TTL, - "TTL", - "TTL", + g_param_spec_uchar (NM_DEVICE_GRE_TTL, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TOS, - g_param_spec_uchar (NM_DEVICE_GRE_TOS, - "ToS", - "ToS", + g_param_spec_uchar (NM_DEVICE_GRE_TOS, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH_MTU_DISCOVERY, - g_param_spec_boolean (NM_DEVICE_GRE_PATH_MTU_DISCOVERY, - "Path MTU Discovery", - "Path MTU Discovery", + g_param_spec_boolean (NM_DEVICE_GRE_PATH_MTU_DISCOVERY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_gre_object_info); } + +/*************************************************************/ + +#define NM_TYPE_GRE_FACTORY (nm_gre_factory_get_type ()) +#define NM_GRE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GRE_FACTORY, NMGreFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_GRE || plink->type == NM_LINK_TYPE_GRETAP) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GRE, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Gre", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(GRE, Gre, gre, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-gre.h b/src/devices/nm-device-gre.h index 610b3805..7acff5f7 100644 --- a/src/devices/nm-device-gre.h +++ b/src/devices/nm-device-gre.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_GRE_H -#define NM_DEVICE_GRE_H +#ifndef __NETWORKMANAGER_DEVICE_GRE_H__ +#define __NETWORKMANAGER_DEVICE_GRE_H__ #include <glib-object.h> @@ -45,19 +45,11 @@ G_BEGIN_DECLS #define NM_DEVICE_GRE_TOS "tos" #define NM_DEVICE_GRE_PATH_MTU_DISCOVERY "path-mtu-discovery" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceGre; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceGreClass; +typedef NMDeviceGeneric NMDeviceGre; +typedef NMDeviceGenericClass NMDeviceGreClass; GType nm_device_gre_get_type (void); -NMDevice *nm_device_gre_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_GRE_H */ diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 8ec79157..e1af8995 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -24,15 +24,18 @@ #include <glib/gi18n.h> #include <linux/if_infiniband.h> -#include <netinet/ether.h> #include "nm-device-infiniband.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" +#include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-infiniband-glue.h" @@ -41,8 +44,6 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) #define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate)) -#define NM_INFINIBAND_ERROR (nm_infiniband_error_quark ()) - typedef struct { int dummy; } NMDeviceInfinibandPrivate; @@ -53,88 +54,11 @@ enum { LAST_PROP }; -static GQuark -nm_infiniband_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-infiniband-error"); - return quark; -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMDevice *self; - - object = G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - self = NM_DEVICE (object); - - nm_log_dbg (LOGD_HW | LOGD_INFINIBAND, "(%s): kernel ifindex %d", - nm_device_get_iface (self), - nm_device_get_ifindex (self)); - return object; -} - static void nm_device_infiniband_init (NMDeviceInfiniband * self) { } -NMDevice * -nm_device_infiniband_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "InfiniBand", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, - NULL); -} - -NMDevice * -nm_device_infiniband_new_partition (NMConnection *connection, - NMDevice *parent) -{ - NMSettingInfiniband *s_infiniband; - int p_key, parent_ifindex; - const char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (parent), NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - parent_ifindex = nm_device_get_ifindex (parent); - s_infiniband = nm_connection_get_setting_infiniband (connection); - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - - if ( !nm_platform_infiniband_partition_add (parent_ifindex, p_key) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_INFINIBAND, "(%s): failed to add InfiniBand P_Key interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - 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, - NULL); -} - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -207,14 +131,13 @@ ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) /* MTU override */ mtu = nm_setting_infiniband_get_mtu (s_infiniband); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband; - const GByteArray *mac; if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -227,11 +150,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; if (s_infiniband) { + const char *mac; + mac = nm_setting_infiniband_get_mac_address (s_infiniband); - /* We only compare the last 8 bytes */ - if (mac && memcmp (mac->data + INFINIBAND_ALEN - 8, - nm_device_get_hw_address (device, NULL) + INFINIBAND_ALEN - 8, - 8)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1)) return FALSE; } @@ -246,13 +168,14 @@ complete_connection (NMDevice *device, GError **error) { NMSettingInfiniband *s_infiniband; - const GByteArray *setting_mac; - const guint8 *hw_address; + const char *setting_mac; + const char *hw_address; nm_utils_complete_generic (connection, NM_SETTING_INFINIBAND_SETTING_NAME, existing_connections, - _("InfiniBand connection %d"), + NULL, + _("InfiniBand connection"), NULL, TRUE); @@ -263,24 +186,20 @@ complete_connection (NMDevice *device, } setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband); - hw_address = nm_device_get_hw_address (device, NULL); + hw_address = nm_device_get_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's MAC */ - if (memcmp (setting_mac->data, hw_address, INFINIBAND_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { g_set_error_literal (error, - NM_SETTING_INFINIBAND_ERROR, - NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY, - NM_SETTING_INFINIBAND_MAC_ADDRESS); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - /* Lock the connection to this device by default */ - mac = g_byte_array_sized_new (INFINIBAND_ALEN); - g_byte_array_append (mac, hw_address, INFINIBAND_ALEN); - g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, hw_address, NULL); } if (!nm_setting_infiniband_get_transport_mode (s_infiniband)) @@ -293,10 +212,7 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); - guint maclen; - gconstpointer mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[INFINIBAND_ALEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - GByteArray *array; + const char *mac = nm_device_get_hw_address (device); char *mode_path, *contents = NULL; const char *transport_mode = "datagram"; @@ -305,12 +221,8 @@ update_connection (NMDevice *device, NMConnection *connection) nm_connection_add_setting (connection, (NMSetting *) s_infiniband); } - if (mac && (maclen == INFINIBAND_ALEN) && (memcmp (mac, null_mac, maclen) != 0)) { - array = g_byte_array_sized_new (maclen); - g_byte_array_append (array, (guint8 *) mac, maclen); - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, array, NULL); - g_byte_array_unref (array); - } + if (mac && !nm_utils_hwaddr_matches (mac, -1, NULL, INFINIBAND_ALEN)) + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); mode_path = g_strdup_printf ("/sys/class/net/%s/mode", ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (device))); @@ -326,38 +238,6 @@ update_connection (NMDevice *device, NMConnection *connection) g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL); } -static gboolean -spec_match_list (NMDevice *device, const GSList *specs) -{ - char *hwaddr_str, *spec_str; - const GSList *iter; - - if (NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->spec_match_list (device, specs)) - return TRUE; - - hwaddr_str = nm_utils_hwaddr_ntoa (nm_device_get_hw_address (device, NULL), - ARPHRD_INFINIBAND); - - /* InfiniBand hardware address matches only need to match the last - * 8 bytes. In string format, that means we skip the first 36 - * characters of hwaddr_str, and the first 40 of the spec (to skip - * "mac:" too). - */ - for (iter = specs; iter; iter = g_slist_next (iter)) { - spec_str = iter->data; - - if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) - && strlen (spec_str) > 40 - && !g_ascii_strcasecmp (spec_str + 40, hwaddr_str + 36)) { - g_free (hwaddr_str); - return TRUE; - } - } - - g_free (hwaddr_str); - return FALSE; -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -389,7 +269,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceInfinibandPrivate)); /* virtual methods */ - object_class->constructor = constructor; object_class->get_property = get_property; object_class->set_property = set_property; @@ -397,7 +276,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; - parent_class->spec_match_list = spec_match_list; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->ip4_config_pre_commit = ip4_config_pre_commit; @@ -407,6 +285,67 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_infiniband_object_info); +} - dbus_g_error_domain_register (NM_INFINIBAND_ERROR, NULL, NM_TYPE_INFINIBAND_ERROR); +/*************************************************************/ + +#define NM_TYPE_INFINIBAND_FACTORY (nm_infiniband_factory_get_type ()) +#define NM_INFINIBAND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INFINIBAND_FACTORY, NMInfinibandFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_INFINIBAND) { + 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, + NULL); + } + return NULL; } + +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; + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (parent), NULL); + + s_infiniband = nm_connection_get_setting_infiniband (connection); + + iface = nm_setting_infiniband_get_virtual_interface_name (s_infiniband); + g_return_val_if_fail (iface != NULL, NULL); + + parent_ifindex = nm_device_get_ifindex (parent); + p_key = nm_setting_infiniband_get_p_key (s_infiniband); + + if ( !nm_platform_infiniband_partition_add (parent_ifindex, p_key) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_INFINIBAND, "(%s): failed to add InfiniBand P_Key interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + 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, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL(INFINIBAND, Infiniband, infiniband, \ + factory_iface->new_link = new_link; \ + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-infiniband.h b/src/devices/nm-device-infiniband.h index 45dc1ab6..b81b762a 100644 --- a/src/devices/nm-device-infiniband.h +++ b/src/devices/nm-device-infiniband.h @@ -18,8 +18,8 @@ * Copyright 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_INFINIBAND_H -#define NM_DEVICE_INFINIBAND_H +#ifndef __NETWORKMANAGER_DEVICE_INFINIBAND_H__ +#define __NETWORKMANAGER_DEVICE_INFINIBAND_H__ #include <glib-object.h> @@ -34,28 +34,11 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_INFINIBAND)) #define NM_DEVICE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) -typedef enum { - NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND = 0, /*< nick=ConnectionNotInfiniband >*/ - NM_INFINIBAND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMInfinibandError; - -typedef struct { - NMDevice parent; -} NMDeviceInfiniband; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceInfinibandClass; - +typedef NMDevice NMDeviceInfiniband; +typedef NMDeviceClass NMDeviceInfinibandClass; GType nm_device_infiniband_get_type (void); -NMDevice *nm_device_infiniband_new (NMPlatformLink *platform_device); -NMDevice *nm_device_infiniband_new_partition (NMConnection *connection, - NMDevice *parent); - G_END_DECLS #endif /* NM_DEVICE_INFINIBAND_H */ diff --git a/src/devices/nm-device-logging.h b/src/devices/nm-device-logging.h new file mode 100644 index 00000000..acca32e5 --- /dev/null +++ b/src/devices/nm-device-logging.h @@ -0,0 +1,46 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DEVICE_LOGGING_H__ +#define __NETWORKMANAGER_DEVICE_LOGGING_H__ + +#include "nm-logging.h" +#include "nm-device.h" + +#define _LOG_DECLARE_SELF(t) \ +inline static NMDevice * \ +_nm_device_log_self_to_device (t *self) \ +{ \ + return (NMDevice *) self; \ +} + +#define _LOG(level, domain, ...) \ + nm_log_obj ((level), (domain), (self), \ + "(%s): " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + (self) ? str_if_set (nm_device_get_iface (_nm_device_log_self_to_device (self)), "(null)") : "(none)" \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +#define _LOGT(domain, ...) _LOG (LOGL_TRACE, domain, __VA_ARGS__) +#define _LOGD(domain, ...) _LOG (LOGL_DEBUG, domain, __VA_ARGS__) +#define _LOGI(domain, ...) _LOG (LOGL_INFO, domain, __VA_ARGS__) +#define _LOGW(domain, ...) _LOG (LOGL_WARN, domain, __VA_ARGS__) +#define _LOGE(domain, ...) _LOG (LOGL_ERR, domain, __VA_ARGS__) + +#endif /* __NETWORKMANAGER_DEVICE_LOGGING_H__ */ diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index 22848fe7..bcd38617 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -28,9 +28,13 @@ #include "nm-logging.h" #include "nm-manager.h" #include "nm-platform.h" +#include "nm-device-factory.h" #include "nm-device-macvlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceMacvlan); + G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate)) @@ -55,13 +59,13 @@ enum { static void update_properties (NMDevice *device) { + NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformMacvlanProperties props; if (!nm_platform_macvlan_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read macvlan properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read macvlan properties"); return; } @@ -88,18 +92,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_macvlan_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Macvlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_macvlan_init (NMDeviceMacvlan *self) { @@ -153,29 +145,49 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_MACVLAN_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_MACVLAN_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_string (NM_DEVICE_MACVLAN_MODE, - "Mode", - "Mode: 'private', 'vepa', 'bridge', or 'passthru'", + g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NO_PROMISC, - g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, - "No-promisc", - "No promiscuous mode", + g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_macvlan_object_info); } + +/*************************************************************/ + +#define NM_TYPE_MACVLAN_FACTORY (nm_macvlan_factory_get_type ()) +#define NM_MACVLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MACVLAN_FACTORY, NMMacvlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_MACVLAN || plink->type == NM_LINK_TYPE_MACVTAP) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Macvlan", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(MACVLAN, Macvlan, macvlan, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-macvlan.h b/src/devices/nm-device-macvlan.h index 348ed2f9..24f15437 100644 --- a/src/devices/nm-device-macvlan.h +++ b/src/devices/nm-device-macvlan.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_MACVLAN_H -#define NM_DEVICE_MACVLAN_H +#ifndef __NETWORKMANAGER_DEVICE_MACVLAN_H__ +#define __NETWORKMANAGER_DEVICE_MACVLAN_H__ #include <glib-object.h> @@ -38,19 +38,11 @@ G_BEGIN_DECLS #define NM_DEVICE_MACVLAN_MODE "mode" #define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceMacvlan; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceMacvlanClass; +typedef NMDeviceGeneric NMDeviceMacvlan; +typedef NMDeviceGenericClass NMDeviceMacvlanClass; GType nm_device_macvlan_get_type (void); -NMDevice *nm_device_macvlan_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_MACVLAN_H */ diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 24bb0b33..65a9a71a 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_PRIVATE_H -#define NM_DEVICE_PRIVATE_H +#ifndef __NETWORKMANAGER_DEVICE_PRIVATE_H__ +#define __NETWORKMANAGER_DEVICE_PRIVATE_H__ #include "nm-device.h" @@ -37,8 +37,9 @@ enum NMActStageReturn { }; #define NM_DEVICE_CAP_NONSTANDARD_CARRIER 0x80000000 +#define NM_DEVICE_CAP_IS_NON_KERNEL 0x40000000 -#define NM_DEVICE_CAP_INTERNAL_MASK 0x80000000 +#define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000 void nm_device_set_ip_iface (NMDevice *self, const char *iface); @@ -52,12 +53,9 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar void nm_device_take_down (NMDevice *self, gboolean block); -gboolean nm_device_update_hw_address (NMDevice *self); -gboolean nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, +gboolean nm_device_set_hw_addr (NMDevice *device, const char *addr, const char *detail, guint64 hw_log_domain); -gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6); - void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); @@ -76,7 +74,7 @@ gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device); gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device); void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); -void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); +void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr); gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release); @@ -91,12 +89,17 @@ gboolean nm_device_get_enslaved (NMDevice *device); NMDevice *nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex); -void nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, +void nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, guint64 log_domain); -void nm_device_set_carrier (NMDevice *device, gboolean carrier); +void nm_device_set_carrier (NMDevice *self, gboolean carrier); void nm_device_emit_recheck_auto_activate (NMDevice *device); void nm_device_queue_recheck_assume (NMDevice *device); +void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config); +void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config); + +gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index d52228f9..9a3fab5e 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -28,9 +28,13 @@ #include "nm-dbus-manager.h" #include "nm-logging.h" #include "nm-platform.h" +#include "nm-device-factory.h" #include "nm-device-tun-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceTun); + G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_TUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TUN, NMDeviceTunPrivate)) @@ -55,15 +59,14 @@ enum { }; static void -reload_tun_properties (NMDeviceTun *device) +reload_tun_properties (NMDeviceTun *self) { - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (device); - GObject *object = G_OBJECT (device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); + GObject *object = G_OBJECT (self); NMPlatformTunProperties props; - if (!nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (device)), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read tun properties", - nm_device_get_iface (NM_DEVICE (device))); + if (!nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (self)), &props)) { + _LOGD (LOGD_HW, "could not read tun properties"); return; } @@ -108,27 +111,6 @@ delay_tun_get_properties_cb (gpointer user_data) /**************************************************************/ -NMDevice * -nm_device_tun_new (NMPlatformLink *platform_device) -{ - const char *mode = NULL; - - g_return_val_if_fail (platform_device != NULL, NULL); - - if (platform_device->type == NM_LINK_TYPE_TUN) - mode = "tun"; - else if (platform_device->type == NM_LINK_TYPE_TAP) - mode = "tap"; - g_return_val_if_fail (mode != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Tun", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NM_DEVICE_TUN_MODE, mode, - NULL); -} - static void nm_device_tun_init (NMDeviceTun *self) { @@ -137,18 +119,18 @@ 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 (object); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - properties_read = nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (object)), &priv->props); + properties_read = nm_platform_tun_get_properties (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. */ - nm_log_dbg (LOGD_HW, "(%s): could not read tun properties (retry)", - nm_device_get_iface (NM_DEVICE (object))); - priv->delay_tun_get_properties_id = g_timeout_add_seconds (1, delay_tun_get_properties_cb, object); + _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); } } @@ -174,10 +156,10 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_OWNER: - g_value_set_uint (value, priv->props.owner); + g_value_set_int64 (value, priv->props.owner); break; case PROP_GROUP: - g_value_set_uint (value, priv->props.group); + g_value_set_int64 (value, priv->props.group); break; case PROP_MODE: g_value_set_string (value, priv->mode); @@ -242,49 +224,37 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_OWNER, - g_param_spec_int64 (NM_DEVICE_TUN_OWNER, - "Owner", - "Owner", + g_param_spec_int64 (NM_DEVICE_TUN_OWNER, "", "", -1, G_MAXUINT32, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_GROUP, - g_param_spec_int64 (NM_DEVICE_TUN_GROUP, - "Group", - "Group", + g_param_spec_int64 (NM_DEVICE_TUN_GROUP, "", "", -1, G_MAXUINT32, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_string (NM_DEVICE_TUN_MODE, - "Mode", - "Mode", + g_param_spec_string (NM_DEVICE_TUN_MODE, "", "", "tun", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NO_PI, - g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, - "No Protocol Info", - "No Protocol Info", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, "", "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_VNET_HDR, - g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, - "Virtio networking header", - "Virtio networking header", + g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, "", "", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MULTI_QUEUE, - g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, - "Multi-queue", - "Multi-queue", + g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, "", "", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); @@ -292,3 +262,34 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_tun_object_info); } + + +/*************************************************************/ + +#define NM_TYPE_TUN_FACTORY (nm_tun_factory_get_type ()) +#define NM_TUN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TUN_FACTORY, NMTunFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + const char *mode = NULL; + + if (plink->type == NM_LINK_TYPE_TUN) + mode = "tun"; + else if (plink->type == NM_LINK_TYPE_TAP) + mode = "tap"; + else + return NULL; + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Tun", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NM_DEVICE_TUN_MODE, mode, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(TUN, Tun, tun, GENERIC, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-tun.h b/src/devices/nm-device-tun.h index cfcf4d7b..393c5801 100644 --- a/src/devices/nm-device-tun.h +++ b/src/devices/nm-device-tun.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_TUN_H -#define NM_DEVICE_TUN_H +#ifndef __NETWORKMANAGER_DEVICE_TUN_H__ +#define __NETWORKMANAGER_DEVICE_TUN_H__ #include <glib-object.h> @@ -41,19 +41,11 @@ G_BEGIN_DECLS #define NM_DEVICE_TUN_VNET_HDR "vnet-hdr" #define NM_DEVICE_TUN_MULTI_QUEUE "multi-queue" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceTun; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceTunClass; +typedef NMDeviceGeneric NMDeviceTun; +typedef NMDeviceGenericClass NMDeviceTunClass; GType nm_device_tun_get_type (void); -NMDevice *nm_device_tun_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_TUN_H */ diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index df107523..db29c00d 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -33,9 +33,13 @@ #include "nm-manager.h" #include "nm-platform.h" #include "nm-dbus-manager.h" +#include "nm-device-factory.h" #include "nm-device-veth-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVeth); + G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) #define NM_DEVICE_VETH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VETH, NMDeviceVethPrivate)) @@ -79,8 +83,7 @@ get_peer (NMDeviceVeth *self) return priv->peer; if (!nm_platform_veth_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read veth properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read veth properties"); return NULL; } @@ -96,18 +99,6 @@ get_peer (NMDeviceVeth *self) /**************************************************************/ -NMDevice * -nm_device_veth_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Veth", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, - NULL); -} - static void nm_device_veth_init (NMDeviceVeth *self) { @@ -159,13 +150,35 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PEER, - g_param_spec_boxed (NM_DEVICE_VETH_PEER, - "Peer", - "Peer device", + g_param_spec_boxed (NM_DEVICE_VETH_PEER, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_veth_object_info); } + +/*************************************************************/ + +#define NM_TYPE_VETH_FACTORY (nm_veth_factory_get_type ()) +#define NM_VETH_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VETH_FACTORY, NMVethFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_VETH) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Veth", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(VETH, Veth, veth, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-veth.h b/src/devices/nm-device-veth.h index bc8fedff..51e8db45 100644 --- a/src/devices/nm-device-veth.h +++ b/src/devices/nm-device-veth.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_VETH_H -#define NM_DEVICE_VETH_H +#ifndef __NETWORKMANAGER_DEVICE_VETH_H__ +#define __NETWORKMANAGER_DEVICE_VETH_H__ #include <glib-object.h> @@ -36,19 +36,11 @@ G_BEGIN_DECLS #define NM_DEVICE_VETH_PEER "peer" -typedef struct { - NMDeviceEthernet parent; -} NMDeviceVeth; - -typedef struct { - NMDeviceEthernetClass parent; - -} NMDeviceVethClass; +typedef NMDeviceEthernet NMDeviceVeth; +typedef NMDeviceEthernetClass NMDeviceVethClass; GType nm_device_veth_get_type (void); -NMDevice *nm_device_veth_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_VETH_H */ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 348be352..c69bcded 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -24,8 +24,6 @@ #include <glib/gi18n.h> #include <sys/socket.h> -#include <linux/if.h> -#include <netinet/ether.h> #include "nm-device-vlan.h" #include "nm-manager.h" @@ -35,20 +33,25 @@ #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-connection-provider.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" #include "nm-platform.h" -#include "nm-utils.h" +#include "nm-device-factory.h" +#include "nm-manager.h" +#include "nm-core-internal.h" #include "nm-device-vlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVlan); 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)) -#define NM_VLAN_ERROR (nm_vlan_error_quark ()) - typedef struct { - guint8 initial_hw_addr[ETH_ALEN]; + char *initial_hw_addr; gboolean disposed; gboolean invalid; @@ -64,35 +67,21 @@ enum { PROP_PARENT, PROP_VLAN_ID, + PROP_INT_PARENT_DEVICE, + LAST_PROP }; /******************************************************************/ -static GQuark -nm_vlan_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-vlan-error"); - return quark; -} - -/******************************************************************/ - static void update_initial_hw_address (NMDevice *dev) { NMDeviceVlan *self = NM_DEVICE_VLAN (dev); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); - char *mac_str; - memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); - - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_VLAN, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev)); + _LOGD (LOGD_DEVICE | LOGD_VLAN, "read initial MAC address %s", priv->initial_hw_addr); } static guint32 @@ -156,22 +145,20 @@ static gboolean match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) { NMSettingWired *s_wired; - const GByteArray *mac; - const guint8 *device_mac; - guint device_mac_len; + const char *setting_mac; + const char *device_mac; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) return !fail_if_no_hwaddr; - mac = nm_setting_wired_get_mac_address (s_wired); - if (!mac) + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (!setting_mac) return !fail_if_no_hwaddr; - device_mac = nm_device_get_hw_address (device, &device_mac_len); + device_mac = nm_device_get_hw_address (device); - return ( mac->len == device_mac_len - && memcmp (mac->data, device_mac, device_mac_len) == 0); + return nm_utils_hwaddr_matches (setting_mac, -1, device_mac, -1); } static gboolean @@ -206,7 +193,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) * since both the parent interface and the VLAN ID matched by the time we * get here. */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (iface) { if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0) return FALSE; @@ -227,13 +214,14 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, NM_SETTING_VLAN_SETTING_NAME, existing_connections, - _("VLAN connection %d"), + NULL, + _("VLAN connection"), NULL, TRUE); s_vlan = nm_connection_get_setting_vlan (connection); if (!s_vlan) { - g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'vlan' setting is required."); return FALSE; } @@ -243,7 +231,7 @@ complete_connection (NMDevice *device, */ if ( !nm_setting_vlan_get_parent (s_vlan) && !match_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "The 'vlan' setting had no interface name, parent, or hardware address."); return FALSE; } @@ -280,6 +268,7 @@ nm_device_vlan_set_parent (NMDeviceVlan *device, NMDevice *parent) static void update_connection (NMDevice *device, NMConnection *connection) { + NMDeviceVlan *self = NM_DEVICE_VLAN (device); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); int ifindex = nm_device_get_ifindex (device); @@ -290,12 +279,10 @@ update_connection (NMDevice *device, NMConnection *connection) if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); nm_connection_add_setting (connection, (NMSetting *) s_vlan); - g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, nm_device_get_iface (device), NULL); } if (!nm_platform_vlan_get_info (ifindex, &parent_ifindex, &vlan_id)) { - nm_log_warn (LOGD_VLAN, "(%s): failed to get VLAN interface info while updating connection.", - nm_device_get_iface (device)); + _LOGW (LOGD_VLAN, "failed to get VLAN interface info while updating connection."); return; } @@ -334,7 +321,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) NMConnection *connection; NMSettingVlan *s_vlan; NMSettingWired *s_wired; - const GByteArray *cloned_mac; + const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -353,8 +340,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_VLAN); + if (cloned_mac) + nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN); } s_vlan = nm_connection_get_setting_vlan (connection); @@ -392,7 +379,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) if (s_wired) { mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } } @@ -403,7 +390,8 @@ deactivate (NMDevice *device) NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN); } /******************************************************************/ @@ -421,89 +409,11 @@ parent_state_changed (NMDevice *parent, if (reason == NM_DEVICE_STATE_REASON_CARRIER) return; - if (new_state < NM_DEVICE_STATE_DISCONNECTED) { - /* If the parent becomes unavailable or unmanaged so does the VLAN */ - nm_device_state_changed (NM_DEVICE (self), new_state, reason); - } else if ( new_state == NM_DEVICE_STATE_DISCONNECTED - && old_state < NM_DEVICE_STATE_DISCONNECTED) { - /* Mark VLAN interface as available/disconnected when the parent - * becomes available as a result of becoming initialized. - */ - nm_device_state_changed (NM_DEVICE (self), new_state, reason); - } + nm_device_set_unmanaged (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason); } /******************************************************************/ -NMDevice * -nm_device_vlan_new (NMPlatformLink *platform_device, NMDevice *parent) -{ - NMDevice *device; - - g_return_val_if_fail (platform_device != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); - - device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_VLAN_PARENT, 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_object_unref (device); - device = NULL; - } - - return device; -} - -NMDevice * -nm_device_vlan_new_for_connection (NMConnection *connection, NMDevice *parent) -{ - NMDevice *device; - NMSettingVlan *s_vlan; - char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); - - s_vlan = nm_connection_get_setting_vlan (connection); - g_return_val_if_fail (s_vlan != NULL, NULL); - - iface = g_strdup (nm_connection_get_virtual_iface_name (connection)); - if (!iface) { - iface = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), - nm_setting_vlan_get_id (s_vlan)); - } - - if ( !nm_platform_vlan_add (iface, - nm_device_get_ifindex (parent), - nm_setting_vlan_get_id (s_vlan), - nm_setting_vlan_get_flags (s_vlan)) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_VLAN, "(%s): failed to add VLAN interface for '%s'", - iface, nm_connection_get_id (connection)); - g_free (iface); - return NULL; - } - - device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_VLAN_PARENT, parent, - NM_DEVICE_DRIVER, "8021q", - NM_DEVICE_TYPE_DESC, "VLAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, - NULL); - g_free (iface); - if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { - g_object_unref (device); - device = NULL; - } - - return device; -} - static void nm_device_vlan_init (NMDeviceVlan * self) { @@ -512,10 +422,9 @@ nm_device_vlan_init (NMDeviceVlan * self) static void constructed (GObject *object) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - NMDevice *device = NM_DEVICE (object); - const char *iface = nm_device_get_iface (device); - int ifindex = nm_device_get_ifindex (device); + 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; @@ -523,20 +432,20 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed (object); if (!priv->parent) { - nm_log_err (LOGD_VLAN, "(%s): no parent specified.", iface); + _LOGE (LOGD_VLAN, "no parent specified."); priv->invalid = TRUE; return; } itype = nm_platform_link_get_type (ifindex); if (itype != NM_LINK_TYPE_VLAN) { - nm_log_err (LOGD_VLAN, "(%s): failed to get VLAN interface type.", iface); + _LOGE (LOGD_VLAN, "failed to get VLAN interface type."); priv->invalid = TRUE; return; } if (!nm_platform_vlan_get_info (ifindex, &parent_ifindex, &vlan_id)) { - nm_log_warn (LOGD_VLAN, "(%s): failed to get VLAN interface info.", iface); + _LOGW (LOGD_VLAN, "failed to get VLAN interface info."); priv->invalid = TRUE; return; } @@ -544,16 +453,15 @@ constructed (GObject *object) if ( parent_ifindex < 0 || parent_ifindex != nm_device_get_ip_ifindex (priv->parent) || vlan_id < 0) { - nm_log_warn (LOGD_VLAN, "(%s): VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", - iface, parent_ifindex, priv->vlan_id); + _LOGW (LOGD_VLAN, "VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", + parent_ifindex, priv->vlan_id); priv->invalid = TRUE; return; } priv->vlan_id = vlan_id; - nm_log_dbg (LOGD_HW | LOGD_VLAN, "(%s): kernel ifindex %d", iface, ifindex); - nm_log_info (LOGD_HW | LOGD_VLAN, "(%s): VLAN ID %d with parent %s", - iface, priv->vlan_id, nm_device_get_iface (priv->parent)); + _LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s", + priv->vlan_id, nm_device_get_iface (priv->parent)); } static void @@ -563,6 +471,12 @@ get_property (GObject *object, guint prop_id, NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); switch (prop_id) { + case PROP_PARENT: + g_value_set_boxed (value, priv->parent ? nm_device_get_path (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; @@ -579,7 +493,7 @@ set_property (GObject *object, guint prop_id, NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); switch (prop_id) { - case PROP_PARENT: + case PROP_INT_PARENT_DEVICE: nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), g_value_get_object (value)); break; case PROP_VLAN_ID: @@ -609,6 +523,17 @@ dispose (GObject *object) } static void +finalize (GObject *object) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (object); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + g_free (priv->initial_hw_addr); + + G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object); +} + +static void nm_device_vlan_class_init (NMDeviceVlanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -623,6 +548,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; + object_class->finalize = finalize; parent_class->update_initial_hw_address = update_initial_hw_address; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -638,22 +564,137 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_object (NM_DEVICE_VLAN_PARENT, - "Parent", - "Parent", - NM_TYPE_DEVICE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_boxed (NM_DEVICE_VLAN_PARENT, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_VLAN_ID, - g_param_spec_uint (NM_DEVICE_VLAN_ID, - "VLAN ID", - "VLAN ID", + g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "", 0, 4095, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + 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)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_vlan_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_VLAN_ERROR, NULL, NM_TYPE_VLAN_ERROR); +#define NM_TYPE_VLAN_FACTORY (nm_vlan_factory_get_type ()) +#define NM_VLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VLAN_FACTORY, NMVlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + int parent_ifindex = -1; + NMDevice *parent, *device; + + if (plink->type != NM_LINK_TYPE_VLAN) + return NULL; + + /* Have to find the parent device */ + if (!nm_platform_vlan_get_info (plink->ifindex, &parent_ifindex, NULL)) { + nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", plink->name); + return NULL; + } + + parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex); + if (!parent) { + /* If udev signaled the VLAN interface before it signaled + * the VLAN's parent at startup we may not know about the + * parent device yet. But we'll find it on the second pass + * from nm_manager_start(). + */ + nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", plink->name); + return NULL; + } + + 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_object_unref (device); + device = NULL; + } + + /* Set initial parent-dependent unmanaged flag */ + if (device) + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent)); + + return device; } + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + NMDevice *device; + NMSettingVlan *s_vlan; + char *iface; + + if (!nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan != NULL, NULL); + + 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)); + } + + if ( !nm_platform_vlan_add (iface, + nm_device_get_ifindex (parent), + nm_setting_vlan_get_id (s_vlan), + nm_setting_vlan_get_flags (s_vlan)) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_VLAN, "(%s) failed to add VLAN interface for '%s'", + iface, nm_connection_get_id (connection)); + g_free (iface); + 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); + g_free (iface); + if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { + g_object_unref (device); + device = NULL; + } + + /* Set initial parent-dependent unmanaged flag */ + if (device) + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent)); + + return device; +} + +DEFINE_DEVICE_FACTORY_INTERNAL(VLAN, Vlan, vlan, \ + factory_iface->new_link = new_link; \ + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h index 0f2ac70d..20fc3453 100644 --- a/src/devices/nm-device-vlan.h +++ b/src/devices/nm-device-vlan.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_VLAN_H -#define NM_DEVICE_VLAN_H +#ifndef __NETWORKMANAGER_DEVICE_VLAN_H__ +#define __NETWORKMANAGER_DEVICE_VLAN_H__ #include <glib-object.h> @@ -40,26 +40,18 @@ typedef enum { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ } NMVlanError; +/* D-Bus exported properties */ #define NM_DEVICE_VLAN_PARENT "parent" #define NM_DEVICE_VLAN_ID "vlan-id" -typedef struct { - NMDevice parent; -} NMDeviceVlan; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceVlanClass; +/* Internal non-exported properties */ +#define NM_DEVICE_VLAN_INT_PARENT_DEVICE "int-parent-device" +typedef NMDevice NMDeviceVlan; +typedef NMDeviceClass NMDeviceVlanClass; GType nm_device_vlan_get_type (void); -NMDevice *nm_device_vlan_new (NMPlatformLink *platform_link, - NMDevice *parent); -NMDevice *nm_device_vlan_new_for_connection (NMConnection *connection, - NMDevice *parent); - G_END_DECLS #endif /* NM_DEVICE_VLAN_H */ diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 0be57106..ed6b8fa0 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -29,9 +29,13 @@ #include "nm-manager.h" #include "nm-platform.h" #include "nm-utils.h" +#include "nm-device-factory.h" #include "nm-device-vxlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVxlan); + G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanPrivate)) @@ -67,13 +71,13 @@ enum { static void update_properties (NMDevice *device) { + NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformVxlanProperties props; if (!nm_platform_vxlan_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read vxlan properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read vxlan properties"); return; } @@ -130,18 +134,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_vxlan_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Vxlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_vxlan_init (NMDeviceVxlan *self) { @@ -240,133 +232,140 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_VXLAN_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_VXLAN_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ID, - g_param_spec_uint (NM_DEVICE_VXLAN_ID, - "Id", - "Id", + g_param_spec_uint (NM_DEVICE_VXLAN_ID, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_GROUP, - g_param_spec_string (NM_DEVICE_VXLAN_GROUP, - "Group", - "Group", + g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LOCAL, - g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, - "Local", - "Local", + g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TOS, - g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, - "ToS", - "ToS", + g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TTL, - g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, - "TTL", - "TTL", + g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LEARNING, - g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, - "Learning", - "Learning", + g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AGEING, - g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, - "Ageing", - "Ageing", + g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LIMIT, - g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, - "Limit", - "Limit", + g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DST_PORT, - g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, - "Destination port", - "Destination port", + g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SRC_PORT_MIN, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, - "Source port min", - "Minimum source port", + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SRC_PORT_MAX, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, - "Source port max", - "Maximum source port", + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PROXY, - g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, - "Proxy", - "Proxy", + g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSC, - g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, - "RSC", - "RSC", + g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_L2MISS, - g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, - "L2miss", - "L2miss", + g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_L3MISS, - g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, - "L3miss", - "L3miss", + g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_vxlan_object_info); } + +/*************************************************************/ + +#define NM_TYPE_VXLAN_FACTORY (nm_vxlan_factory_get_type ()) +#define NM_VXLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VXLAN_FACTORY, NMVxlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_VXLAN) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Vxlan", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(VXLAN, Vxlan, vxlan, GENERIC, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index 14b158de..cc6081e6 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -18,8 +18,8 @@ * Copyright 2013, 2014 Red Hat, Inc. */ -#ifndef NM_DEVICE_VXLAN_H -#define NM_DEVICE_VXLAN_H +#ifndef __NETWORKMANAGER_DEVICE_VXLAN_H__ +#define __NETWORKMANAGER_DEVICE_VXLAN_H__ #include <glib-object.h> @@ -51,19 +51,11 @@ G_BEGIN_DECLS #define NM_DEVICE_VXLAN_L2MISS "l2miss" #define NM_DEVICE_VXLAN_L3MISS "l3miss" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceVxlan; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceVxlanClass; +typedef NMDeviceGeneric NMDeviceVxlan; +typedef NMDeviceGenericClass NMDeviceVxlanClass; GType nm_device_vxlan_get_type (void); -NMDevice *nm_device_vxlan_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_VXLAN_H */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4788a604..a9899535 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -19,7 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include <config.h> +#include "config.h" + #include <glib.h> #include <glib/gi18n.h> #include <dbus/dbus.h> @@ -35,10 +36,9 @@ #include <sys/wait.h> #include <arpa/inet.h> #include <fcntl.h> -#include <linux/if.h> #include <netlink/route/addr.h> -#include "libgsystem.h" +#include "gsystem-local-alloc.h" #include "nm-glib-compat.h" #include "nm-device.h" #include "nm-device-private.h" @@ -49,13 +49,13 @@ #include "nm-lndp-rdisc.h" #include "nm-dhcp-manager.h" #include "nm-dbus-manager.h" -#include "nm-utils.h" #include "nm-logging.h" -#include "nm-setting-ip4-config.h" -#include "nm-setting-ip6-config.h" -#include "nm-setting-connection.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-dnsmasq-manager.h" #include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" #include "nm-rfkill-manager.h" #include "nm-firewall-manager.h" #include "nm-properties-changed-signal.h" @@ -63,25 +63,23 @@ #include "nm-settings-connection.h" #include "nm-connection-provider.h" #include "nm-posix-signals.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-dbus-glib-types.h" #include "nm-dispatcher.h" -#include "nm-config-device.h" #include "nm-config.h" #include "nm-dns-manager.h" +#include "nm-core-internal.h" +#include "nm-default-route-manager.h" -#include "nm-device-bridge.h" -#include "nm-device-bond.h" -#include "nm-device-team.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF (NMDevice); -static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); +static void impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context); +static void impl_device_delete (NMDevice *self, DBusGMethodInvocation *context); #include "nm-device-glue.h" -static void nm_device_config_device_interface_init (NMConfigDeviceInterface *iface); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMDevice, nm_device, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (NM_TYPE_CONFIG_DEVICE, nm_device_config_device_interface_init)) +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, G_TYPE_OBJECT) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) @@ -176,6 +174,7 @@ typedef struct { typedef struct { gboolean in_state_changed; + gboolean initialized; NMDeviceState state; NMDeviceStateReason state_reason; @@ -199,7 +198,7 @@ typedef struct { RfKillType rfkill_type; gboolean firmware_missing; GHashTable * available_connections; - guint8 hw_addr[NM_UTILS_HWADDR_LEN_MAX]; + char * hw_addr; guint hw_addr_len; char * physical_port_id; @@ -230,22 +229,32 @@ typedef struct { guint carrier_wait_id; gboolean ignore_carrier; guint32 mtu; + gboolean up; /* IFF_UP */ /* Generic DHCP stuff */ guint32 dhcp_timeout; - GByteArray * dhcp_anycast_address; + char * dhcp_anycast_address; /* IP4 configuration info */ NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */ IpState ip4_state; NMIP4Config * dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */ NMIP4Config * ext_ip4_config; /* Stuff added outside NM */ + gboolean ext_ip4_config_had_any_addresses; + NMIP4Config * wwan_ip4_config; /* WWAN configuration */ + struct { + gboolean v4_has; + gboolean v4_is_assumed; + NMPlatformIP4Route v4; + gboolean v6_has; + gboolean v6_is_assumed; + NMPlatformIP6Route v6; + } default_route; /* DHCPv4 tracking */ - NMDHCPClient * dhcp4_client; + NMDhcpClient * dhcp4_client; gulong dhcp4_state_sigid; - gulong dhcp4_timeout_sigid; - NMDHCP4Config * dhcp4_config; + NMDhcp4Config * dhcp4_config; NMIP4Config * vpn4_config; /* routes added by a VPN which uses this device */ guint arp_round2_id; @@ -255,9 +264,8 @@ typedef struct { NMDnsMasqManager *dnsmasq_manager; gulong dnsmasq_state_id; - /* Firewall Manager */ - NMFirewallManager *fw_manager; - DBusGProxyCall *fw_call; + /* Firewall */ + NMFirewallPendingCall fw_call; /* avahi-autoipd stuff */ GPid aipd_pid; @@ -268,10 +276,14 @@ typedef struct { NMIP6Config * ip6_config; IpState ip6_state; NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */ + NMIP6Config * wwan_ip6_config; NMIP6Config * ext_ip6_config; /* Stuff added outside NM */ + gboolean ext_ip6_config_had_any_addresses; + gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */ NMRDisc * rdisc; - gulong rdisc_config_changed_sigid; + gulong rdisc_changed_id; + gulong rdisc_timeout_id; NMSettingIP6ConfigPrivacy rdisc_use_tempaddr; /* IP6 config from autoconf */ NMIP6Config * ac_ip6_config; @@ -280,11 +292,10 @@ typedef struct { GHashTable * ip6_saved_properties; - NMDHCPClient * dhcp6_client; + NMDhcpClient * dhcp6_client; NMRDiscDHCPLevel dhcp6_mode; gulong dhcp6_state_sigid; - gulong dhcp6_timeout_sigid; - NMDHCP6Config * dhcp6_config; + NMDhcp6Config * dhcp6_config; /* IP6 config from DHCP */ NMIP6Config * dhcp6_ip6_config; @@ -303,8 +314,9 @@ typedef struct { NMConnectionProvider *con_provider; } NMDevicePrivate; -static gboolean nm_device_set_ip4_config (NMDevice *dev, +static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, + guint32 default_route_metric, gboolean commit, NMDeviceStateReason *reason); static gboolean ip4_config_merge_and_apply (NMDevice *self, @@ -312,36 +324,27 @@ static gboolean ip4_config_merge_and_apply (NMDevice *self, gboolean commit, NMDeviceStateReason *out_reason); -static gboolean nm_device_set_ip6_config (NMDevice *dev, +static gboolean nm_device_set_ip6_config (NMDevice *self, NMIP6Config *config, gboolean commit, NMDeviceStateReason *reason); -static gboolean nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure); -static void nm_device_slave_notify_enslave (NMDevice *dev, gboolean success); -static void nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason); +static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); +static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); +static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason); -static void addrconf6_start_with_link_ready (NMDevice *self); +static gboolean addrconf6_start_with_link_ready (NMDevice *self); +static gboolean dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection); +static NMActStageReturn linklocal6_start (NMDevice *self); -static gboolean nm_device_get_default_unmanaged (NMDevice *device); +static gboolean nm_device_get_default_unmanaged (NMDevice *self); -static void _set_state_full (NMDevice *device, +static void _set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting); -/***********************************************************/ - -static GQuark -nm_device_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-device-error"); - return quark; -} - -#define NM_DEVICE_ERROR (nm_device_error_quark ()) +static void nm_device_update_hw_address (NMDevice *self); /***********************************************************/ @@ -366,7 +369,7 @@ static const char *state_table[] = { static const char * queued_state_to_string (NMDeviceState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return state_table[NM_DEVICE_STATE_UNKNOWN]; } @@ -442,41 +445,41 @@ static const char *reason_table[] = { static const char * reason_to_string (NMDeviceStateReason reason) { - if (reason >= 0 && reason < G_N_ELEMENTS (reason_table)) + if ((gsize) reason < G_N_ELEMENTS (reason_table)) return reason_table[reason]; return reason_table[NM_DEVICE_STATE_REASON_UNKNOWN]; } /***********************************************************/ -static inline gboolean +gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value) { return nm_platform_sysctl_set (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value); } static gboolean -device_has_capability (NMDevice *device, NMDeviceCapabilities caps) +device_has_capability (NMDevice *self, NMDeviceCapabilities caps) { - return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & caps); + return !!(NM_DEVICE_GET_PRIVATE (self)->capabilities & caps); } /***********************************************************/ void -nm_device_dbus_export (NMDevice *device) +nm_device_dbus_export (NMDevice *self) { static guint32 devcount = 0; NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->path == NULL); priv->path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++); - nm_log_info (LOGD_DEVICE, "(%s): exported as %s", priv->iface, priv->path); - nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, device); + _LOGI (LOGD_DEVICE, "exported as %s", priv->path); + nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, self); } const char * @@ -498,7 +501,7 @@ nm_device_get_udi (NMDevice *self) const char * nm_device_get_iface (NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_DEVICE (self), 0); return NM_DEVICE_GET_PRIVATE (self)->iface; } @@ -512,9 +515,9 @@ nm_device_get_ifindex (NMDevice *self) } gboolean -nm_device_is_software (NMDevice *device) +nm_device_is_software (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return priv->is_software; } @@ -562,11 +565,14 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) if (priv->ip_iface) { priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface); if (priv->ip_ifindex > 0) { + if (nm_platform_check_support_user_ipv6ll ()) + nm_platform_link_set_user_ipv6ll_enabled (priv->ip_ifindex, TRUE); + if (!nm_platform_link_is_up (priv->ip_ifindex)) nm_platform_link_set_up (priv->ip_ifindex); } else { /* Device IP interface must always be a kernel network interface */ - nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", iface); + _LOGW (LOGD_HW, "failed to look up interface index"); } } @@ -579,6 +585,43 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) g_free (old_ip_iface); } +static gboolean +get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) +{ + NMLinkType link_type; + const guint8 *hwaddr = NULL; + size_t hwaddr_len = 0; + int ifindex; + gboolean success; + + /* If we get here, we *must* have a kernel netdev, which implies an ifindex */ + ifindex = nm_device_get_ip_ifindex (self); + g_assert (ifindex); + + link_type = nm_platform_link_get_type (ifindex); + g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0); + + hwaddr = nm_platform_link_get_address (ifindex, &hwaddr_len); + if (!hwaddr_len) + return FALSE; + + success = nm_utils_get_ipv6_interface_identifier (link_type, + hwaddr, + hwaddr_len, + out_iid); + if (!success) { + _LOGW (LOGD_HW, "failed to generate interface identifier " + "for link type %u hwaddr_len %zu", link_type, hwaddr_len); + } + return success; +} + +static gboolean +nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid) +{ + return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); +} + const char * nm_device_get_driver (NMDevice *self) { @@ -606,54 +649,124 @@ nm_device_get_device_type (NMDevice *self) /** * nm_device_get_priority(): - * @dev: the #NMDevice + * @self: the #NMDevice * * Returns: the device's routing priority. Lower numbers means a "better" * device, eg higher priority. */ int -nm_device_get_priority (NMDevice *dev) +nm_device_get_priority (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (dev), 100); + g_return_val_if_fail (NM_IS_DEVICE (self), 1000); - /* Device 'priority' is used for two things: + /* Device 'priority' is used for the default route-metric and is based on + * the device type. The settings ipv4.route-metric and ipv6.route-metric + * can overwrite this default. + * + * Currently for both IPv4 and IPv6 we use the same default values. + * + * The route-metric is used for the metric of the routes of device. + * This also applies to the default route. Therefore it affects also + * which device is the "best". * - * a) two devices on the same IP subnet: the "better" (ie, lower number) - * device is the default outgoing device for that subnet - * b) default route: the "better" device gets the default route. This can - * always be modified by setting a connection to never-default=TRUE, in - * which case that device will never take the default route when - * it's using that connection. + * For comparison, note that iproute2 by default adds IPv4 routes with + * metric 0, and IPv6 routes with metric 1024. The latter is the IPv6 + * "user default" in the kernel (NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6). + * In kernel, the full uint32_t range is available for route + * metrics (except for IPv6, where 0 means 1024). */ - switch (nm_device_get_device_type (dev)) { + switch (nm_device_get_device_type (self)) { + /* 50 is reserved for VPN (NM_VPN_ROUTE_METRIC_DEFAULT) */ case NM_DEVICE_TYPE_ETHERNET: - return 1; + return 100; case NM_DEVICE_TYPE_INFINIBAND: - return 2; + return 150; case NM_DEVICE_TYPE_ADSL: - return 3; + return 200; case NM_DEVICE_TYPE_WIMAX: - return 4; + return 250; case NM_DEVICE_TYPE_BOND: - return 5; + return 300; case NM_DEVICE_TYPE_TEAM: - return 6; + return 350; case NM_DEVICE_TYPE_VLAN: - return 7; + return 400; case NM_DEVICE_TYPE_MODEM: - return 8; + return 450; case NM_DEVICE_TYPE_BT: - return 9; + return 550; case NM_DEVICE_TYPE_WIFI: - return 10; + return 600; case NM_DEVICE_TYPE_OLPC_MESH: - return 11; + return 650; default: - return 20; + return 950; } } +guint32 +nm_device_get_ip4_route_metric (NMDevice *self) +{ + NMConnection *connection; + gint64 route_metric = -1; + + g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); + + connection = nm_device_get_connection (self); + + if (connection) + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (connection)); + + return route_metric >= 0 ? route_metric : nm_device_get_priority (self); +} + +guint32 +nm_device_get_ip6_route_metric (NMDevice *self) +{ + NMConnection *connection; + gint64 route_metric = -1; + + g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); + + connection = nm_device_get_connection (self); + + if (connection) + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (connection)); + + return route_metric >= 0 ? route_metric : nm_device_get_priority (self); +} + +const NMPlatformIP4Route * +nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (out_is_assumed) + *out_is_assumed = priv->default_route.v4_is_assumed; + + return priv->default_route.v4_has ? &priv->default_route.v4 : NULL; +} + +const NMPlatformIP6Route * +nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (out_is_assumed) + *out_is_assumed = priv->default_route.v6_is_assumed; + + return priv->default_route.v6_has ? &priv->default_route.v6 : NULL; +} + const char * nm_device_get_type_desc (NMDevice *self) { @@ -663,9 +776,9 @@ nm_device_get_type_desc (NMDevice *self) } gboolean -nm_device_has_carrier (NMDevice *device) +nm_device_has_carrier (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->carrier; + return NM_DEVICE_GET_PRIVATE (self)->carrier; } NMActRequest * @@ -693,22 +806,38 @@ nm_device_get_rfkill_type (NMDevice *self) } static const char * -nm_device_get_physical_port_id (NMDevice *device) +nm_device_get_physical_port_id (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->physical_port_id; + return NM_DEVICE_GET_PRIVATE (self)->physical_port_id; } /***********************************************************/ static gboolean -nm_device_uses_generated_connection (NMDevice *self) +nm_device_uses_generated_assumed_connection (NMDevice *self) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - connection = nm_device_get_connection (self); - if (!connection) - return FALSE; - return nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (connection)); + if ( priv->act_request + && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) { + connection = nm_act_request_get_connection (priv->act_request); + if ( connection + && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + return TRUE; + } + return FALSE; +} + +gboolean +nm_device_uses_assumed_connection (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if ( priv->act_request + && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) + return TRUE; + return FALSE; } static SlaveInfo * @@ -737,28 +866,28 @@ free_slave_info (SlaveInfo *info) /** * nm_device_enslave_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to enslave * @connection: (allow-none): the slave device's connection * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function enslaves @slave. * * Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave * other devices. */ static gboolean -nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connection) +nm_device_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection) { SlaveInfo *info; gboolean success = FALSE; gboolean configure; - g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->enslave_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); - info = find_slave_info (dev, slave); + info = find_slave_info (self, slave); if (!info) return FALSE; @@ -769,7 +898,7 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio if (configure) g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - success = NM_DEVICE_GET_CLASS (dev)->enslave_slave (dev, slave, connection, configure); + success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure); info->enslaved = success; } @@ -778,18 +907,18 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio /* Ensure the device's hardware address is up-to-date; it often changes * when slaves change. */ - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); /* Restart IP configuration if we're waiting for slaves. Do this * after updating the hardware address as IP config may need the * new address. */ if (success) { - if (NM_DEVICE_GET_PRIVATE (dev)->ip4_state == IP_WAIT) - nm_device_activate_stage3_ip4_start (dev); + if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT) + nm_device_activate_stage3_ip4_start (self); - if (NM_DEVICE_GET_PRIVATE (dev)->ip6_state == IP_WAIT) - nm_device_activate_stage3_ip6_start (dev); + if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT) + nm_device_activate_stage3_ip6_start (self); } return success; @@ -797,42 +926,42 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio /** * nm_device_release_one_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to release - * @configure: whether @dev needs to actually release @slave + * @configure: whether @self needs to actually release @slave * @reason: the state change reason for the @slave * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function releases the previously enslaved @slave and/or - * updates the state of @dev and @slave to reflect its release. + * updates the state of @self and @slave to reflect its release. * * Returns: %TRUE on success, %FALSE on failure, if this device cannot enslave * other devices, or if @slave was never enslaved. */ static gboolean -nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure, NMDeviceStateReason reason) +nm_device_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); SlaveInfo *info; gboolean success = FALSE; g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->release_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->release_slave != NULL, FALSE); - info = find_slave_info (dev, slave); + info = find_slave_info (self, slave); if (!info) return FALSE; priv->slaves = g_slist_remove (priv->slaves, info); if (info->enslaved) { - success = NM_DEVICE_GET_CLASS (dev)->release_slave (dev, slave, configure); + success = NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure); /* The release_slave() implementation logs success/failure (in the * correct device-specific log domain), so we don't have to do anything. */ } if (!configure) { - g_warn_if_fail (reason == NM_DEVICE_STATE_REASON_NONE); + g_warn_if_fail (reason == NM_DEVICE_STATE_REASON_NONE || reason == NM_DEVICE_STATE_REASON_REMOVED); reason = NM_DEVICE_STATE_REASON_NONE; } else if (reason == NM_DEVICE_STATE_REASON_NONE) { g_warn_if_reached (); @@ -845,20 +974,53 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure, /* Ensure the device's hardware address is up-to-date; it often changes * when slaves change. */ - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); return success; } +static gboolean +is_software_external (NMDevice *self) +{ + return nm_device_is_software (self) + && !nm_device_get_is_nm_owned (self); +} + +/** + * nm_device_finish_init: + * @self: the master device + * + * Whatever needs to be done post-initialization, when the device has a DBus + * object name. + */ +void +nm_device_finish_init (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + g_assert (priv->initialized == FALSE); + + /* Do not manage externally created software devices until they are IFF_UP */ + if ( is_software_external (self) + && !nm_platform_link_is_up (priv->ifindex) + && priv->ifindex > 0) + nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN, TRUE); + + if (priv->master) + nm_device_enslave_slave (priv->master, self, NULL); + + priv->initialized = TRUE; +} + static void -carrier_changed (NMDevice *device, gboolean carrier) +carrier_changed (NMDevice *self, gboolean carrier) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!nm_device_get_managed (device)) + if (!nm_device_get_managed (self)) return; - nm_device_recheck_available_connections (device); + nm_device_recheck_available_connections (self); /* ignore-carrier devices ignore all carrier-down events */ if (priv->ignore_carrier && !carrier) @@ -872,13 +1034,13 @@ carrier_changed (NMDevice *device, gboolean carrier) if (!carrier) return; - if (nm_device_activate_ip4_state_in_wait (device)) - nm_device_activate_stage3_ip4_start (device); - if (nm_device_activate_ip6_state_in_wait (device)) - nm_device_activate_stage3_ip6_start (device); + if (nm_device_activate_ip4_state_in_wait (self)) + nm_device_activate_stage3_ip4_start (self); + if (nm_device_activate_ip6_state_in_wait (self)) + nm_device_activate_stage3_ip6_start (self); return; - } else if (nm_device_get_enslaved (device) && !carrier) { + } else if (nm_device_get_enslaved (self) && !carrier) { /* Slaves don't deactivate when they lose carrier; for * bonds/teams in particular that would be actively * counterproductive. @@ -890,7 +1052,7 @@ carrier_changed (NMDevice *device, gboolean carrier) g_warn_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE); if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { /* If the device is already in DISCONNECTED state without a carrier @@ -898,14 +1060,16 @@ carrier_changed (NMDevice *device, gboolean carrier) * when the carrier appears, auto connections are rechecked for * the device. */ - nm_device_emit_recheck_auto_activate (device); + nm_device_emit_recheck_auto_activate (self); } } else { + g_return_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE); + if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - if (nm_device_queued_state_peek (device) >= NM_DEVICE_STATE_DISCONNECTED) - nm_device_queued_state_clear (device); - } else if (priv->state >= NM_DEVICE_STATE_DISCONNECTED) { - nm_device_queue_state (device, NM_DEVICE_STATE_UNAVAILABLE, + if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED) + nm_device_queued_state_clear (self); + } else { + nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); } } @@ -916,18 +1080,16 @@ carrier_changed (NMDevice *device, gboolean carrier) static gboolean link_disconnect_action_cb (gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (calling deferred action) (id=%u)", - nm_device_get_iface (device), priv->carrier_defer_id); + _LOGD (LOGD_DEVICE, "link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id); priv->carrier_defer_id = 0; - nm_log_info (LOGD_DEVICE, "(%s): link disconnected (calling deferred action)", - nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)"); - NM_DEVICE_GET_CLASS (device)->carrier_changed (device, FALSE); + NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE); return FALSE; } @@ -939,67 +1101,64 @@ link_disconnect_action_cancel (NMDevice *self) if (priv->carrier_defer_id) { g_source_remove (priv->carrier_defer_id); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (canceling deferred action) (id=%u)", - nm_device_get_iface (self), priv->carrier_defer_id); + _LOGD (LOGD_DEVICE, "link disconnected (canceling deferred action) (id=%u)", priv->carrier_defer_id); priv->carrier_defer_id = 0; } } void -nm_device_set_carrier (NMDevice *device, gboolean carrier) +nm_device_set_carrier (NMDevice *self, gboolean carrier) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDeviceState state = nm_device_get_state (device); - const char *iface = nm_device_get_iface (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDeviceState state = nm_device_get_state (self); if (priv->carrier == carrier) return; priv->carrier = carrier; - g_object_notify (G_OBJECT (device), NM_DEVICE_CARRIER); + g_object_notify (G_OBJECT (self), NM_DEVICE_CARRIER); if (priv->carrier) { - nm_log_info (LOGD_DEVICE, "(%s): link connected", iface); - link_disconnect_action_cancel (device); - klass->carrier_changed (device, TRUE); + _LOGI (LOGD_DEVICE, "link connected"); + link_disconnect_action_cancel (self); + klass->carrier_changed (self, TRUE); if (priv->carrier_wait_id) { g_source_remove (priv->carrier_wait_id); priv->carrier_wait_id = 0; - nm_device_remove_pending_action (device, "carrier wait", TRUE); + nm_device_remove_pending_action (self, "carrier wait", TRUE); } } else if (state <= NM_DEVICE_STATE_DISCONNECTED) { - nm_log_info (LOGD_DEVICE, "(%s): link disconnected", iface); - klass->carrier_changed (device, FALSE); + _LOGI (LOGD_DEVICE, "link disconnected"); + klass->carrier_changed (self, FALSE); } else { - nm_log_info (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds)", - iface, LINK_DISCONNECT_DELAY); + _LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY); priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY, - link_disconnect_action_cb, device); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds) (id=%u)", - iface, LINK_DISCONNECT_DELAY, priv->carrier_defer_id); + link_disconnect_action_cb, self); + _LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)", + LINK_DISCONNECT_DELAY, priv->carrier_defer_id); } } static void -update_for_ip_ifname_change (NMDevice *device) +update_for_ip_ifname_change (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_hash_table_remove_all (priv->ip6_saved_properties); if (priv->dhcp4_client) { - if (!nm_device_dhcp4_renew (device, FALSE)) { - nm_device_state_changed (device, + if (!nm_device_dhcp4_renew (self, FALSE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); return; } } if (priv->dhcp6_client) { - if (!nm_device_dhcp6_renew (device, FALSE)) { - nm_device_state_changed (device, + if (!nm_device_dhcp6_renew (self, FALSE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); return; @@ -1014,98 +1173,152 @@ update_for_ip_ifname_change (NMDevice *device) } static void -device_link_changed (NMDevice *device, NMPlatformLink *info) +device_set_master (NMDevice *self, int ifindex) +{ + NMDevice *master; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + master = nm_manager_get_device_by_ifindex (nm_manager_get (), ifindex); + if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) { + g_clear_object (&priv->master); + priv->master = g_object_ref (master); + nm_device_master_add_slave (master, self, FALSE); + } else if (master) { + _LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring", + nm_device_get_iface (master)); + } else { + _LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s", + ifindex, + nm_platform_link_get_name (ifindex)); + } +} + +static void +device_link_changed (NMDevice *self, NMPlatformLink *info) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean ip_ifname_changed = FALSE; if (info->udi && g_strcmp0 (info->udi, priv->udi)) { /* Update UDI to what udev gives us */ g_free (priv->udi); priv->udi = g_strdup (info->udi); - g_object_notify (G_OBJECT (device), NM_DEVICE_UDI); + g_object_notify (G_OBJECT (self), NM_DEVICE_UDI); } /* Update MTU if it has changed. */ if (priv->mtu != info->mtu) { priv->mtu = info->mtu; - g_object_notify (G_OBJECT (device), NM_DEVICE_MTU); + g_object_notify (G_OBJECT (self), NM_DEVICE_MTU); } if (info->name[0] && strcmp (priv->iface, info->name) != 0) { - nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed iface from '%s' to '%s'", - priv->iface, priv->ifindex, priv->iface, info->name); + _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'", + priv->ifindex, priv->iface, info->name); g_free (priv->iface); priv->iface = g_strdup (info->name); /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */ ip_ifname_changed = !priv->ip_iface; - g_object_notify (G_OBJECT (device), NM_DEVICE_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IFACE); if (ip_ifname_changed) - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); /* Re-match available connections against the new interface name */ - nm_device_recheck_available_connections (device); + nm_device_recheck_available_connections (self); /* Let any connections that use the new interface name have a chance * to auto-activate on the device. */ - nm_device_emit_recheck_auto_activate (device); + nm_device_emit_recheck_auto_activate (self); } /* Update slave status for external changes */ + if (priv->enslaved && info->master != nm_device_get_ifindex (priv->master)) + nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); if (info->master && !priv->enslaved) { - NMDevice *master; - - master = nm_manager_get_device_by_ifindex (nm_manager_get (), info->master); - if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) { - g_clear_object (&priv->master); - priv->master = g_object_ref (master); - nm_device_master_add_slave (master, device, FALSE); - nm_device_enslave_slave (master, device, NULL); - } else if (master) { - nm_log_info (LOGD_DEVICE, "(%s): enslaved to non-master-type device %s; ignoring", - nm_device_get_iface (device), - nm_device_get_iface (master)); - } else { - nm_log_warn (LOGD_DEVICE, "(%s): enslaved to unknown device %d %s", - nm_device_get_iface (device), - info->master, - nm_platform_link_get_name (info->master)); - } - } else if (priv->enslaved && !info->master) - nm_device_release_one_slave (priv->master, device, FALSE, NM_DEVICE_STATE_REASON_NONE); + device_set_master (self, info->master); + if (priv->master) + nm_device_enslave_slave (priv->master, self, NULL); + } if (klass->link_changed) - klass->link_changed (device, info); - + klass->link_changed (self, info); /* Update DHCP, etc, if needed */ if (ip_ifname_changed) - update_for_ip_ifname_change (device); + update_for_ip_ifname_change (self); + + if (priv->up != info->up) { + priv->up = info->up; + + /* Manage externally-created software interfaces only when they are IFF_UP */ + g_assert (priv->ifindex > 0); + if (is_software_external (self)) { + gboolean external_down = nm_device_get_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN); + + if (external_down && info->up) { + if (nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume (self); + + /* Resetting the EXTERNAL_DOWN flag may change the device's state + * to UNAVAILABLE. To ensure that the state change doesn't touch + * the device before assumption occurs, pass + * NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED as the reason. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } else { + /* Don't trigger a state change; if the device is in a + * state higher than UNAVAILABLE, it is already IFF_UP + * or an explicit activation request was received. + */ + priv->unmanaged_flags &= ~NM_UNMANAGED_EXTERNAL_DOWN; + } + } else if (!external_down && !info->up && nm_device_get_state (self) <= NM_DEVICE_STATE_DISCONNECTED) { + /* If the device is already disconnected and is set !IFF_UP, + * unmanage it. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + TRUE, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } + } } static void -device_ip_link_changed (NMDevice *device, NMPlatformLink *info) +device_ip_link_changed (NMDevice *self, NMPlatformLink *info) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (info->name[0] && g_strcmp0 (priv->ip_iface, info->name)) { - nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed ip_iface (%d) from '%s' to '%s'", - priv->iface, priv->ifindex, nm_device_get_ip_ifindex (device), - priv->ip_iface, info->name); + _LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'", + priv->ifindex, nm_device_get_ip_ifindex (self), + priv->ip_iface, info->name); g_free (priv->ip_iface); priv->ip_iface = g_strdup (info->name); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); - update_for_ip_ifname_change (device); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + update_for_ip_ifname_change (self); } } static void -link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDevice *device) +link_changed_cb (NMPlatform *platform, + int ifindex, + NMPlatformLink *info, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDevice *self) { if (change_type != NM_PLATFORM_SIGNAL_CHANGED) return; @@ -1116,24 +1329,24 @@ link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlat * and it results in also setting IFF_LOWER_UP. */ - if (ifindex == nm_device_get_ifindex (device)) - device_link_changed (device, info); - else if (ifindex == nm_device_get_ip_ifindex (device)) - device_ip_link_changed (device, info); + if (ifindex == nm_device_get_ifindex (self)) + device_link_changed (self, info); + else if (ifindex == nm_device_get_ip_ifindex (self)) + device_ip_link_changed (self, info); } static void -link_changed (NMDevice *device, NMPlatformLink *info) +link_changed (NMDevice *self, NMPlatformLink *info) { /* Update carrier from link event if applicable. */ - if ( device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT) - && !device_has_capability (device, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) - nm_device_set_carrier (device, info->connected); + if ( device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT) + && !device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) + nm_device_set_carrier (self, info->connected); } /** * nm_device_notify_component_added(): - * @device: the #NMDevice + * @self: the #NMDevice * @component: the component being added by a plugin * * Called by the manager to notify the device that a new component has @@ -1144,16 +1357,16 @@ link_changed (NMDevice *device, NMPlatformLink *info) * claimed. */ gboolean -nm_device_notify_component_added (NMDevice *device, GObject *component) +nm_device_notify_component_added (NMDevice *self, GObject *component) { - if (NM_DEVICE_GET_CLASS (device)->component_added) - return NM_DEVICE_GET_CLASS (device)->component_added (device, component); + if (NM_DEVICE_GET_CLASS (self)->component_added) + return NM_DEVICE_GET_CLASS (self)->component_added (self, component); return FALSE; } /** * nm_device_owns_iface(): - * @device: the #NMDevice + * @self: the #NMDevice * @iface: an interface name * * Called by the manager to ask if the device or any of its components owns @@ -1162,17 +1375,25 @@ nm_device_notify_component_added (NMDevice *device, GObject *component) * because that ethernet interface is controlled by the WWAN device and cannot * be used independently of the WWAN device. * - * Returns: %TRUE if @device or it's components owns the interface name, + * Returns: %TRUE if @self or it's components owns the interface name, * %FALSE if not */ gboolean -nm_device_owns_iface (NMDevice *device, const char *iface) +nm_device_owns_iface (NMDevice *self, const char *iface) { - if (NM_DEVICE_GET_CLASS (device)->owns_iface) - return NM_DEVICE_GET_CLASS (device)->owns_iface (device, iface); + if (NM_DEVICE_GET_CLASS (self)->owns_iface) + return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface); return FALSE; } +NMConnection * +nm_device_new_default_connection (NMDevice *self) +{ + if (NM_DEVICE_GET_CLASS (self)->new_default_connection) + return NM_DEVICE_GET_CLASS (self)->new_default_connection (self); + return NULL; +} + static void slave_state_changed (NMDevice *slave, NMDeviceState slave_new_state, @@ -1183,13 +1404,12 @@ slave_state_changed (NMDevice *slave, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean release = FALSE; - nm_log_dbg (LOGD_DEVICE, "(%s): slave %s state change %d (%s) -> %d (%s)", - nm_device_get_iface (self), - nm_device_get_iface (slave), - slave_old_state, - state_to_string (slave_old_state), - slave_new_state, - state_to_string (slave_new_state)); + _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)", + nm_device_get_iface (slave), + slave_old_state, + state_to_string (slave_old_state), + slave_new_state, + state_to_string (slave_new_state)); /* Don't try to enslave slaves until the master is ready */ if (priv->state < NM_DEVICE_STATE_CONFIG) @@ -1208,46 +1428,45 @@ slave_state_changed (NMDevice *slave, if (release) { nm_device_release_one_slave (self, slave, TRUE, reason); /* Bridge/bond/team interfaces are left up until manually deactivated */ - if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED) { - nm_log_dbg (LOGD_DEVICE, "(%s): last slave removed; remaining activated", - nm_device_get_iface (self)); - } + if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED) + _LOGD (LOGD_DEVICE, "last slave removed; remaining activated"); } } /** * nm_device_master_add_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to enslave * @configure: pass %TRUE if the slave should be configured by the master, or * %FALSE if it is already configured outside NetworkManager * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function adds @slave to the slave list for later enslavement. * * Returns: %TRUE on success, %FALSE on failure */ static gboolean -nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure) +nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); SlaveInfo *info; - g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->enslave_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); if (configure) g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - if (!find_slave_info (dev, slave)) { + if (!find_slave_info (self, slave)) { info = g_malloc0 (sizeof (SlaveInfo)); info->slave = g_object_ref (slave); info->configure = configure; info->watch_id = g_signal_connect (slave, "state-changed", - G_CALLBACK (slave_state_changed), dev); + G_CALLBACK (slave_state_changed), self); priv->slaves = g_slist_append (priv->slaves, info); } + nm_device_queue_recheck_assume (self); return TRUE; } @@ -1255,14 +1474,14 @@ nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure) /** * nm_device_master_get_slaves: - * @dev: the master device + * @self: the master device * - * Returns: any slaves of which @device is the master. Caller owns returned list. + * Returns: any slaves of which @self is the master. Caller owns returned list. */ GSList * -nm_device_master_get_slaves (NMDevice *dev) +nm_device_master_get_slaves (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *slaves = NULL, *iter; for (iter = priv->slaves; iter; iter = g_slist_next (iter)) @@ -1273,18 +1492,18 @@ nm_device_master_get_slaves (NMDevice *dev) /** * nm_device_master_get_slave_by_ifindex: - * @dev: the master device + * @self: the master device * @ifindex: the slave's interface index * - * Returns: the slave with the given @ifindex of which @device is the master, - * or %NULL if no device with @ifindex is a slave of @device. + * Returns: the slave with the given @ifindex of which @self is the master, + * or %NULL if no device with @ifindex is a slave of @self. */ NMDevice * -nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex) +nm_device_master_get_slave_by_ifindex (NMDevice *self, int ifindex) { GSList *iter; - for (iter = NM_DEVICE_GET_PRIVATE (dev)->slaves; iter; iter = g_slist_next (iter)) { + for (iter = NM_DEVICE_GET_PRIVATE (self)->slaves; iter; iter = g_slist_next (iter)) { SlaveInfo *info = iter->data; if (nm_device_get_ip_ifindex (info->slave) == ifindex) @@ -1295,18 +1514,18 @@ nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex) /** * nm_device_master_check_slave_physical_port: - * @dev: the master device + * @self: the master device * @slave: a slave device * @log_domain: domain to log a warning in * - * Checks if @dev already has a slave with the same #NMDevice:physical-port-id + * Checks if @self already has a slave with the same #NMDevice:physical-port-id * as @slave, and logs a warning if so. */ void -nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, +nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, guint64 log_domain) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *slave_physical_port_id, *existing_physical_port_id; SlaveInfo *info; GSList *iter; @@ -1322,10 +1541,9 @@ nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, existing_physical_port_id = nm_device_get_physical_port_id (info->slave); if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) { - nm_log_warn (log_domain, "(%s): slave %s shares a physical port with existing slave %s", - nm_device_get_ip_iface (dev), - nm_device_get_ip_iface (slave), - nm_device_get_ip_iface (info->slave)); + _LOGW (log_domain, "slave %s shares a physical port with existing slave %s", + nm_device_get_ip_iface (slave), + nm_device_get_ip_iface (info->slave)); /* Since this function will get called for every slave, we only have * to warn about the first match we find; if there are other matches * later in the list, we will have already warned about them matching @@ -1344,7 +1562,7 @@ nm_device_master_release_slaves (NMDevice *self) NMDeviceStateReason reason; /* Don't release the slaves if this connection doesn't belong to NM. */ - if (nm_device_uses_generated_connection (self)) + if (nm_device_uses_generated_assumed_connection (self)) return; reason = priv->state_reason; @@ -1360,19 +1578,19 @@ nm_device_master_release_slaves (NMDevice *self) /** * nm_device_get_master: - * @dev: the device + * @self: the device * - * If @dev has been enslaved by another device, this returns that + * If @self has been enslaved by another device, this returns that * device. Otherwise it returns %NULL. (In particular, note that if - * @dev is in the process of activating as a slave, but has not yet + * @self is in the process of activating as a slave, but has not yet * been enslaved by its master, this will return %NULL.) * - * Returns: (transfer none): @dev's master, or %NULL + * Returns: (transfer none): @self's master, or %NULL */ NMDevice * -nm_device_get_master (NMDevice *dev) +nm_device_get_master (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->enslaved) return priv->master; @@ -1382,17 +1600,17 @@ nm_device_get_master (NMDevice *dev) /** * nm_device_slave_notify_enslave: - * @dev: the slave device + * @self: the slave device * @success: whether the enslaving operation succeeded * * Notifies a slave that either it has been enslaved, or else its master tried * to enslave it and failed. */ static void -nm_device_slave_notify_enslave (NMDevice *dev, gboolean success) +nm_device_slave_notify_enslave (NMDevice *self, gboolean success) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - NMConnection *connection = nm_device_get_connection (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection = nm_device_get_connection (self); gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); g_assert (priv->master); @@ -1400,49 +1618,41 @@ nm_device_slave_notify_enslave (NMDevice *dev, gboolean success) if (!priv->enslaved) { if (success) { if (activating) { - nm_log_info (LOGD_DEVICE, - "Activation (%s) connection '%s' enslaved, continuing activation", - nm_device_get_iface (dev), - nm_connection_get_id (connection)); - } else { - nm_log_info (LOGD_DEVICE, - "(%s): enslaved to %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->master)); - } + _LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation", + nm_connection_get_id (connection)); + } else + _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master)); priv->enslaved = TRUE; - g_object_notify (G_OBJECT (dev), NM_DEVICE_MASTER); + g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER); } else if (activating) { - nm_log_warn (LOGD_DEVICE, - "Activation (%s) connection '%s' could not be enslaved", - nm_device_get_iface (dev), - nm_connection_get_id (connection)); + _LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved", + nm_connection_get_id (connection)); } } if (activating) { priv->ip4_state = IP_DONE; priv->ip6_state = IP_DONE; - nm_device_queue_state (dev, + nm_device_queue_state (self, success ? NM_DEVICE_STATE_SECONDARIES : NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); } else - nm_device_queue_recheck_assume (dev); + nm_device_queue_recheck_assume (self); } /** * nm_device_slave_notify_release: - * @dev: the slave device + * @self: the slave device * @reason: the reason associated with the state change * * Notifies a slave that it has been released, and why. */ static void -nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason) +nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - NMConnection *connection = nm_device_get_connection (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection = nm_device_get_connection (self); NMDeviceState new_state; const char *master_status; @@ -1460,43 +1670,56 @@ nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason) master_status = "deactivated"; } - nm_log_dbg (LOGD_DEVICE, - "Activation (%s) connection '%s' master %s", - nm_device_get_iface (dev), - nm_connection_get_id (connection), - master_status); + _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s", + nm_connection_get_id (connection), + master_status); - nm_device_queue_state (dev, new_state, reason); - } else { - nm_log_info (LOGD_DEVICE, - "(%s): released from master %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->master)); - } + nm_device_queue_state (self, new_state, reason); + } else if (priv->master) + _LOGI (LOGD_DEVICE, "released from master %s", nm_device_get_iface (priv->master)); + else + _LOGD (LOGD_DEVICE, "released from master%s", priv->enslaved ? "" : " (was not enslaved)"); if (priv->enslaved) { priv->enslaved = FALSE; - g_object_notify (G_OBJECT (dev), NM_DEVICE_MASTER); + g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER); } } /** * nm_device_get_enslaved: - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is enslaved to a master device (eg bridge or * bond or team), %FALSE if not */ gboolean -nm_device_get_enslaved (NMDevice *device) +nm_device_get_enslaved (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->enslaved; + return NM_DEVICE_GET_PRIVATE (self)->enslaved; } +/** + * nm_device_removed: + * @self: the #NMDevice + * + * Called by the manager when the device was removed. Releases the device from + * the master in case it's enslaved. + */ +void +nm_device_removed (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->enslaved) + nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_REMOVED); +} + + static gboolean -is_available (NMDevice *device) +is_available (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return priv->carrier || priv->ignore_carrier; } @@ -1548,12 +1771,44 @@ nm_device_set_enabled (NMDevice *self, gboolean enabled) NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled); } +/** + * nm_device_get_autoconnect: + * @self: the #NMDevice + * + * Returns: %TRUE if the device allows autoconnect connections, or %FALSE if the + * device is explicitly blocking all autoconnect connections. Does not take + * into account transient conditions like companion devices that may wish to + * block the device. + */ gboolean -nm_device_get_autoconnect (NMDevice *device) +nm_device_get_autoconnect (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - return NM_DEVICE_GET_PRIVATE (device)->autoconnect; + return NM_DEVICE_GET_PRIVATE (self)->autoconnect; +} + +static void +nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->autoconnect == autoconnect) + return; + + if (autoconnect) { + /* Default-unmanaged devices never autoconnect */ + if (!nm_device_get_default_unmanaged (self)) { + priv->autoconnect = TRUE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } + } else { + priv->autoconnect = FALSE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } } static gboolean @@ -1566,6 +1821,14 @@ autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, return TRUE; } +/** + * nm_device_autoconnect_allowed: + * @self: the #NMDevice + * + * Returns: %TRUE if the device can be auto-connected immediately, taking + * transient conditions into account (like companion devices that may wish to + * block autoconnect for a time). + */ gboolean nm_device_autoconnect_allowed (NMDevice *self) { @@ -1573,6 +1836,16 @@ nm_device_autoconnect_allowed (NMDevice *self) GValue instance = G_VALUE_INIT; GValue retval = G_VALUE_INIT; + if (priv->state < NM_DEVICE_STATE_DISCONNECTED || !priv->autoconnect) + return FALSE; + + /* The 'autoconnect-allowed' signal is emitted on a device to allow + * other listeners to block autoconnect on the device if they wish. + * This is mainly used by the OLPC Mesh devices to block autoconnect + * on their companion WiFi device as they share radio resources and + * cannot be connected at the same time. + */ + g_value_init (&instance, G_TYPE_OBJECT); g_value_set_object (&instance, self); @@ -1590,7 +1863,7 @@ nm_device_autoconnect_allowed (NMDevice *self) } static gboolean -can_auto_connect (NMDevice *device, +can_auto_connect (NMDevice *self, NMConnection *connection, char **specific_object) { @@ -1600,13 +1873,44 @@ can_auto_connect (NMDevice *device, if (!nm_setting_connection_get_autoconnect (s_con)) return FALSE; - return nm_device_connection_is_available (device, connection, FALSE); + return nm_device_connection_is_available (self, connection, FALSE); +} + +/** + * nm_device_can_auto_connect: + * @self: an #NMDevice + * @connection: a #NMConnection + * @specific_object: (out) (transfer full): on output, the path of an + * object associated with the returned connection, to be passed to + * nm_manager_activate_connection(), or %NULL. + * + * Checks if @connection can be auto-activated on @self right now. + * This requires, at a minimum, that the connection be compatible with + * @self, and that it have the #NMSettingConnection:autoconnect property + * set, and that the device allow auto connections. Some devices impose + * additional requirements. (Eg, a Wi-Fi connection can only be activated + * if its SSID was seen in the last scan.) + * + * Returns: %TRUE, if the @connection can be auto-activated. + **/ +gboolean +nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (specific_object && !*specific_object, FALSE); + + if (nm_device_autoconnect_allowed (self)) + return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object); + return FALSE; } static gboolean -device_has_config (NMDevice *device) +device_has_config (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); /* Check for IP configuration. */ if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config)) @@ -1615,7 +1919,7 @@ device_has_config (NMDevice *device) return TRUE; /* The existence of a software device is good enough. */ - if (nm_device_is_software (device)) + if (nm_device_is_software (self)) return TRUE; /* Slaves are also configured by definition */ @@ -1625,20 +1929,64 @@ device_has_config (NMDevice *device) return FALSE; } +/** + * nm_device_master_update_slave_connection: + * @self: the master #NMDevice + * @slave: the slave #NMDevice + * @connection: the #NMConnection to update with the slave settings + * @GError: (out): error description + * + * Reads the slave configuration for @slave and updates @connection with those + * properties. This invokes a virtual function on the master device @self. + * + * Returns: %TRUE if the configuration was read and @connection updated, + * %FALSE on failure. + */ +gboolean +nm_device_master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + NMDeviceClass *klass; + gboolean success; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (slave, FALSE); + g_return_val_if_fail (connection, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE); + + g_return_val_if_fail (nm_device_get_iface (self), FALSE); + + klass = NM_DEVICE_GET_CLASS (self); + if (klass->master_update_slave_connection) { + success = klass->master_update_slave_connection (self, slave, connection, error); + + g_return_val_if_fail (!error || (success && !*error) || *error, success); + return success; + } + + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)", + nm_device_get_iface (self), nm_device_get_iface (slave)); + return FALSE; +} + NMConnection * -nm_device_generate_connection (NMDevice *device) +nm_device_generate_connection (NMDevice *self, NMDevice *master) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *ifname = nm_device_get_iface (device); - int ifindex = nm_device_get_ifindex (device); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + const char *ifname = nm_device_get_iface (self); NMConnection *connection; NMSetting *s_con; NMSetting *s_ip4; NMSetting *s_ip6; gs_free char *uuid = NULL; - gs_free char *name = NULL; - int master_ifindex = 0; const char *ip4_method, *ip6_method; GError *error = NULL; @@ -1647,32 +1995,18 @@ nm_device_generate_connection (NMDevice *device) return NULL; /* Return NULL if device is unconfigured. */ - if (!device_has_config (device)) { - nm_log_dbg (LOGD_DEVICE, "(%s): device has no existing configuration", ifname); + if (!device_has_config (self)) { + _LOGD (LOGD_DEVICE, "device has no existing configuration"); return NULL; } - if (ifindex) - master_ifindex = nm_platform_link_get_master (ifindex); - if (master_ifindex) { - NMDevice *master; - - master = nm_manager_get_device_by_ifindex (nm_manager_get (), master_ifindex); - if (!master || !nm_device_get_act_request (master)) { - nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s)", - ifname, nm_platform_link_get_name (master_ifindex)); - return NULL; - } - } - - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_con = nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); - name = g_strdup_printf ("%s", ifname); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_ID, name, + NM_SETTING_CONNECTION_ID, ifname, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), @@ -1682,36 +2016,18 @@ nm_device_generate_connection (NMDevice *device) nm_connection_add_setting (connection, s_con); /* If the device is a slave, update various slave settings */ - if (master_ifindex) { - const char *master_iface = nm_platform_link_get_name (master_ifindex); - const char *slave_type = NULL; - gboolean success = FALSE; - - switch (nm_platform_link_get_type (master_ifindex)) { - case NM_LINK_TYPE_BRIDGE: - slave_type = NM_SETTING_BRIDGE_SETTING_NAME; - success = nm_bridge_update_slave_connection (device, connection); - break; - case NM_LINK_TYPE_BOND: - slave_type = NM_SETTING_BOND_SETTING_NAME; - success = TRUE; - break; - case NM_LINK_TYPE_TEAM: - slave_type = NM_SETTING_TEAM_SETTING_NAME; - success = nm_team_update_slave_connection (device, connection); - break; - default: - g_warn_if_reached (); - break; + if (master) { + if (!nm_device_master_update_slave_connection (master, + self, + connection, + &error)) + { + _LOGE (LOGD_DEVICE, "master device '%s' failed to update slave connection: %s", + nm_device_get_iface (master), error ? error->message : "(unknown error)"); + g_error_free (error); + g_object_unref (connection); + return NULL; } - - if (!success) - nm_log_err (LOGD_DEVICE, "(%s): failed to read slave configuration", ifname); - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, master_iface, - NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, - NULL); } else { /* Only regular and master devices get IP configuration; slaves do not */ s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); @@ -1721,12 +2037,11 @@ nm_device_generate_connection (NMDevice *device) nm_connection_add_setting (connection, s_ip6); } - klass->update_connection (device, connection); + klass->update_connection (self, connection); /* Check the connection in case of update_connection() bug. */ if (!nm_connection_verify (connection, &error)) { - nm_log_err (LOGD_DEVICE, "(%s): Generated connection does not verify: %s", - nm_device_get_iface (device), error->message); + _LOGE (LOGD_DEVICE, "Generated connection does not verify: %s", error->message); g_clear_error (&error); g_object_unref (connection); return NULL; @@ -1739,8 +2054,9 @@ nm_device_generate_connection (NMDevice *device) ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0 && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0 - && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))) { - nm_log_dbg (LOGD_DEVICE, "(%s): ignoring generated connection (no IP and not slave)", ifname); + && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con)) + && !priv->slaves) { + _LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not in master-slave relationship)"); g_object_unref (connection); connection = NULL; } @@ -1748,46 +2064,6 @@ nm_device_generate_connection (NMDevice *device) return connection; } -/** - * nm_device_get_best_auto_connection: - * @dev: an #NMDevice - * @connections: (element-type #NMConnection): a list of connections - * @specific_object: (out) (transfer full): on output, the path of an - * object associated with the returned connection, to be passed to - * nm_manager_activate_connection(), or %NULL. - * - * Looks through @connections to see if there is a connection that can - * be auto-activated on @dev right now. This requires, at a minimum, - * that the connection be compatible with @dev, and that it have the - * #NMSettingConnection:autoconnect property set. Some devices impose - * additional requirements. (Eg, a Wi-Fi connection can only be - * activated if its SSID was seen in the last scan.) - * - * Returns: an auto-activatable #NMConnection, or %NULL if none are - * available. - */ - -NMConnection * -nm_device_get_best_auto_connection (NMDevice *dev, - GSList *connections, - char **specific_object) -{ - GSList *iter; - - g_return_val_if_fail (NM_IS_DEVICE (dev), NULL); - g_return_val_if_fail (specific_object != NULL, NULL); - g_return_val_if_fail (*specific_object == NULL, NULL); - - for (iter = connections; iter; iter = iter->next) { - NMConnection *connection = NM_CONNECTION (iter->data); - - if (NM_DEVICE_GET_CLASS (dev)->can_auto_connect (dev, connection, specific_object)) - return connection; - } - - return NULL; -} - gboolean nm_device_complete_connection (NMDevice *self, NMConnection *connection, @@ -1801,7 +2077,7 @@ nm_device_complete_connection (NMDevice *self, g_return_val_if_fail (connection != NULL, FALSE); if (!NM_DEVICE_GET_CLASS (self)->complete_connection) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CONNECTION_INVALID, + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "Device class %s had no complete_connection method", G_OBJECT_TYPE_NAME (self)); return FALSE; @@ -1819,7 +2095,7 @@ nm_device_complete_connection (NMDevice *self, } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection) +check_connection_compatible (NMDevice *self, NMConnection *connection) { NMSettingConnection *s_con; const char *config_iface, *device_iface; @@ -1828,7 +2104,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) g_assert (s_con); config_iface = nm_setting_connection_get_interface_name (s_con); - device_iface = nm_device_get_iface (device); + device_iface = nm_device_get_iface (self); if (config_iface && strcmp (config_iface, device_iface) != 0) return FALSE; @@ -1837,43 +2113,31 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) /** * nm_device_check_connection_compatible: - * @device: an #NMDevice + * @self: an #NMDevice * @connection: an #NMConnection * - * Checks if @connection could potentially be activated on @device. - * This means only that @device has the proper capabilities, and that + * Checks if @connection could potentially be activated on @self. + * This means only that @self has the proper capabilities, and that * @connection is not locked to some other device. It does not - * necessarily mean that @connection could be activated on @device + * necessarily mean that @connection could be activated on @self * right now. (Eg, it might refer to a Wi-Fi network that is not * currently available.) * * Returns: #TRUE if @connection could potentially be activated on - * @device. + * @self. */ gboolean -nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection) +nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - return NM_DEVICE_GET_CLASS (device)->check_connection_compatible (device, connection); -} - -static gboolean -string_in_list (const char *str, const char **array, gsize array_len) -{ - gsize i; - - for (i = 0; i < array_len; i++) { - if (strcmp (str, array[i]) == 0) - return TRUE; - } - return FALSE; + return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection); } /** * nm_device_can_assume_connections: - * @device: #NMDevice instance + * @self: #NMDevice instance * * This is a convenience function to determine whether connection assumption * is available for this device. @@ -1881,14 +2145,14 @@ string_in_list (const char *str, const char **array, gsize array_len) * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not */ static gboolean -nm_device_can_assume_connections (NMDevice *device) +nm_device_can_assume_connections (NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (device)->update_connection; + return !!NM_DEVICE_GET_CLASS (self)->update_connection; } /** * nm_device_can_assume_active_connection: - * @device: #NMDevice instance + * @self: #NMDevice instance * * This is a convenience function to determine whether the device's active * connection can be assumed if NetworkManager restarts. This method returns @@ -1900,9 +2164,9 @@ nm_device_can_assume_connections (NMDevice *device) * assumed. */ gboolean -nm_device_can_assume_active_connection (NMDevice *device) +nm_device_can_assume_active_connection (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; const char *method; const char *assumable_ip6_methods[] = { @@ -1911,17 +2175,19 @@ nm_device_can_assume_active_connection (NMDevice *device) NM_SETTING_IP6_CONFIG_METHOD_DHCP, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL }; const char *assumable_ip4_methods[] = { NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL }; - if (!nm_device_can_assume_connections (device)) + if (!nm_device_can_assume_connections (self)) return FALSE; - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); if (!connection) return FALSE; @@ -1934,11 +2200,11 @@ nm_device_can_assume_active_connection (NMDevice *device) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (!string_in_list (method, assumable_ip6_methods, G_N_ELEMENTS (assumable_ip6_methods))) + if (!_nm_utils_string_in_list (method, assumable_ip6_methods)) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!string_in_list (method, assumable_ip4_methods, G_N_ELEMENTS (assumable_ip4_methods))) + if (!_nm_utils_string_in_list (method, assumable_ip4_methods)) return FALSE; return TRUE; @@ -1950,8 +2216,10 @@ nm_device_emit_recheck_assume (gpointer self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); priv->recheck_assume_id = 0; - if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config)) + if (!nm_device_get_act_request (self)) { + _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal"); g_signal_emit (self, signals[RECHECK_ASSUME], 0); + } return G_SOURCE_REMOVE; } @@ -2022,9 +2290,8 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) act_source_func = &priv->act_source_func; } - if (*act_source_id) { - nm_log_err (LOGD_DEVICE, "activation stage already scheduled"); - } + if (*act_source_id) + _LOGE (LOGD_DEVICE, "activation stage already scheduled"); /* Don't bother rescheduling the same function that's about to * run anyway. Fixes issues with crappy wireless drivers sending @@ -2038,12 +2305,11 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) } } -gboolean -nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) +static gboolean +get_ip_config_may_fail (NMDevice *self, int family) { NMConnection *connection; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip = NULL; g_return_val_if_fail (self != NULL, TRUE); @@ -2051,17 +2317,18 @@ nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) g_assert (connection); /* Fail the connection if the failed IP method is required to complete */ - if (ip6) { - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!nm_setting_ip6_config_get_may_fail (s_ip6)) - return TRUE; - } else { - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!nm_setting_ip4_config_get_may_fail (s_ip4)) - return TRUE; + switch (family) { + case AF_INET: + s_ip = nm_connection_get_setting_ip4_config (connection); + break; + case AF_INET6: + s_ip = nm_connection_get_setting_ip6_config (connection); + break; + default: + g_assert_not_reached (); } - return FALSE; + return nm_setting_ip_config_get_may_fail (s_ip); } static void @@ -2083,9 +2350,8 @@ master_ready_cb (NMActiveConnection *active, self, nm_active_connection_get_assumed (active) ? FALSE : TRUE); - nm_log_dbg (LOGD_DEVICE, "(%s): master connection ready; master device %s", - nm_device_get_iface (self), - nm_device_get_iface (priv->master)); + _LOGD (LOGD_DEVICE, "master connection ready; master device %s", + nm_device_get_iface (priv->master)); if (priv->master_ready_id) { g_signal_handler_disconnect (active, priv->master_ready_id); @@ -2112,7 +2378,6 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); @@ -2125,8 +2390,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) /* Notify the new ActiveConnection along with the state change */ g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) started..."); nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE); /* Assumed connections were already set up outside NetworkManager */ @@ -2146,8 +2410,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) if (nm_active_connection_get_master_ready (active)) master_ready_cb (active, NULL, self); else { - nm_log_dbg (LOGD_DEVICE, "(%s): waiting for master connection to become ready", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); /* Attach a signal handler and wait for the master connection to begin activating */ g_assert (priv->master_ready_id == 0); @@ -2161,7 +2424,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) nm_device_activate_schedule_stage2_device_config (self); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) complete."); return FALSE; } @@ -2184,12 +2447,11 @@ nm_device_activate_schedule_stage1_device_prepare (NMDevice *self) activation_source_schedule (self, nm_device_activate_stage1_device_prepare, 0); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) scheduled..."); } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *self, NMDeviceStateReason *reason) { /* Nothing to do */ return NM_ACT_STAGE_RETURN_SUCCESS; @@ -2207,7 +2469,6 @@ nm_device_activate_stage2_device_config (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; gboolean no_firmware = FALSE; @@ -2217,8 +2478,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) starting..."); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); /* Assumed connections were already set up outside NetworkManager */ @@ -2248,17 +2508,17 @@ nm_device_activate_stage2_device_config (gpointer user_data) if (slave_state == NM_DEVICE_STATE_IP_CONFIG) nm_device_enslave_slave (self, info->slave, nm_device_get_connection (info->slave)); - else if ( nm_device_uses_generated_connection (self) + else if ( nm_device_uses_generated_assumed_connection (self) && slave_state <= NM_DEVICE_STATE_DISCONNECTED) nm_device_queue_recheck_assume (info->slave); } - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) successful.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) successful."); nm_device_activate_schedule_stage3_ip_config_start (self); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) complete."); return FALSE; } @@ -2281,8 +2541,7 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) activation_source_schedule (self, nm_device_activate_stage2_device_config, 0); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) scheduled..."); } /*********************************************/ @@ -2310,13 +2569,7 @@ aipd_cleanup (NMDevice *self) } if (priv->aipd_pid > 0) { - kill (priv->aipd_pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_AUTOIP4, "waiting for avahi-autoipd pid %d to exit", priv->aipd_pid); - waitpid (priv->aipd_pid, NULL, 0); - nm_log_dbg (LOGD_AUTOIP4, "avahi-autoip pid %d cleaned up", priv->aipd_pid); - + nm_utils_kill_child_sync (priv->aipd_pid, SIGKILL, LOGD_AUTOIP4, "avahi-autoipd", NULL, 0, 0); priv->aipd_pid = -1; } @@ -2336,15 +2589,15 @@ aipd_get_ip4_config (NMDevice *self, guint32 lla) memset (&address, 0, sizeof (address)); address.address = lla; address.plen = 16; - address.source = NM_PLATFORM_SOURCE_IP4LL; + address.source = NM_IP_CONFIG_SOURCE_IP4LL; nm_ip4_config_add_address (config, &address); /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */ memset (&route, 0, sizeof (route)); route.network = htonl (0xE0000000L); route.plen = 4; - route.source = NM_PLATFORM_SOURCE_IP4LL; - route.metric = nm_device_get_priority (self); + route.source = NM_IP_CONFIG_SOURCE_IP4LL; + route.metric = nm_device_get_ip4_route_metric (self); nm_ip4_config_add_route (config, &route); return config; @@ -2360,7 +2613,7 @@ nm_device_handle_autoip4_event (NMDevice *self, { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection = NULL; - const char *iface, *method; + const char *method; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; g_return_if_fail (event != NULL); @@ -2376,29 +2629,25 @@ nm_device_handle_autoip4_event (NMDevice *self, if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0) return; - iface = nm_device_get_iface (self); - if (strcmp (event, "BIND") == 0) { guint32 lla; NMIP4Config *config; if (inet_pton (AF_INET, address, &lla) <= 0) { - nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd.", - iface, address); + _LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd.", address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } if ((lla & IPV4LL_NETMASK) != IPV4LL_NETWORK) { - nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd (not link-local).", - iface, address); + _LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd (not link-local).", address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } config = aipd_get_ip4_config (self, lla); if (config == NULL) { - nm_log_err (LOGD_AUTOIP4, "failed to get autoip config"); + _LOGE (LOGD_AUTOIP4, "failed to get autoip config"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); return; } @@ -2408,8 +2657,7 @@ nm_device_handle_autoip4_event (NMDevice *self, nm_device_activate_schedule_ip4_config_result (self, config); } else if (priv->ip4_state == IP_DONE) { if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) { - nm_log_err (LOGD_AUTOIP4, "(%s): failed to update IP4 config for autoip change.", - nm_device_get_iface (self)); + _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } } else @@ -2417,8 +2665,7 @@ nm_device_handle_autoip4_event (NMDevice *self, g_object_unref (config); } else { - nm_log_warn (LOGD_AUTOIP4, "(%s): autoip address %s no longer valid because '%s'.", - iface, address, event); + _LOGW (LOGD_AUTOIP4, "autoip address %s no longer valid because '%s'.", address, event); /* The address is gone; terminate the connection or fail activation */ nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); @@ -2431,26 +2678,19 @@ aipd_watch_cb (GPid pid, gint status, gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; - const char *iface; if (!priv->aipd_watch) return; priv->aipd_watch = 0; - iface = nm_device_get_iface (self); - - if (WIFEXITED (status)) { - nm_log_dbg (LOGD_AUTOIP4, "(%s): avahi-autoipd exited with error code %d", - iface, WEXITSTATUS (status)); - } else if (WIFSTOPPED (status)) { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd stopped unexpectedly with signal %d", - iface, WSTOPSIG (status)); - } else if (WIFSIGNALED (status)) { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd died with signal %d", - iface, WTERMSIG (status)); - } else { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd died from an unknown cause", iface); - } + if (WIFEXITED (status)) + _LOGD (LOGD_AUTOIP4, "avahi-autoipd exited with error code %d", WEXITSTATUS (status)); + else if (WIFSTOPPED (status)) + _LOGW (LOGD_AUTOIP4, "avahi-autoipd stopped unexpectedly with signal %d", WSTOPSIG (status)); + else if (WIFSIGNALED (status)) + _LOGW (LOGD_AUTOIP4, "avahi-autoipd died with signal %d", WTERMSIG (status)); + else + _LOGW (LOGD_AUTOIP4, "avahi-autoipd died from an unknown cause"); aipd_cleanup (self); @@ -2466,7 +2706,7 @@ aipd_timeout_cb (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->aipd_timeout) { - nm_log_info (LOGD_AUTOIP4, "(%s): avahi-autoipd timed out.", nm_device_get_iface (self)); + _LOGI (LOGD_AUTOIP4, "avahi-autoipd timed out."); priv->aipd_timeout = 0; aipd_cleanup (self); @@ -2501,63 +2741,51 @@ static NMActStageReturn aipd_start (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (self); - char *argv[6], *cmdline; - const char **aipd_binary = NULL; - static const char *aipd_paths[] = { - "/usr/sbin/avahi-autoipd", - "/usr/local/sbin/avahi-autoipd", - NULL - }; + const char *argv[6]; + char *cmdline; + const char *aipd_binary; int i = 0; GError *error = NULL; aipd_cleanup (self); /* Find avahi-autoipd */ - aipd_binary = aipd_paths; - while (*aipd_binary != NULL) { - if (g_file_test (*aipd_binary, G_FILE_TEST_EXISTS)) - break; - aipd_binary++; - } - - if (!*aipd_binary) { - nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" - " to start avahi-autoipd: not found", iface); + aipd_binary = nm_utils_find_helper ("avahi-autoipd", NULL, NULL); + if (!aipd_binary) { + _LOGW (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: not found"); *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } - argv[i++] = (char *) (*aipd_binary); + argv[i++] = aipd_binary; argv[i++] = "--script"; - argv[i++] = (char *) nm_device_autoipd_helper_path; + argv[i++] = nm_device_autoipd_helper_path; if (nm_logging_enabled (LOGL_DEBUG, LOGD_AUTOIP4)) argv[i++] = "--debug"; - argv[i++] = (char *) nm_device_get_ip_iface (self); + argv[i++] = nm_device_get_ip_iface (self); argv[i++] = NULL; - cmdline = g_strjoinv (" ", argv); - nm_log_dbg (LOGD_AUTOIP4, "running: %s", cmdline); + cmdline = g_strjoinv (" ", (char **) argv); + _LOGD (LOGD_AUTOIP4, "running: %s", cmdline); g_free (cmdline); - if (!g_spawn_async ("/", argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, + if (!g_spawn_async ("/", (char **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, &aipd_child_setup, NULL, &(priv->aipd_pid), &error)) { - nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" - " to start avahi-autoipd: %s", - iface, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: %s", + error && error->message ? error->message : "(unknown)"); g_clear_error (&error); aipd_cleanup (self); return NM_ACT_STAGE_RETURN_FAILURE; } - nm_log_info (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) started" - " avahi-autoipd...", iface); + _LOGI (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) started" + " avahi-autoipd..."); /* Monitor the child process so we know when it dies */ priv->aipd_watch = g_child_watch_add (priv->aipd_pid, aipd_watch_cb, self); @@ -2569,6 +2797,52 @@ aipd_start (NMDevice *self, NMDeviceStateReason *reason) } /*********************************************/ + +static gboolean +_device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlatformIPRoute *out_route) +{ + gboolean success = FALSE; + int ifindex = nm_device_get_ip_ifindex (self); + GArray *routes; + + if (addr_family == AF_INET) + routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + else + routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + + if (routes) { + guint route_metric = G_MAXUINT32, m; + const NMPlatformIPRoute *route = NULL, *r; + guint i; + + /* if there are several default routes, find the one with the best metric */ + for (i = 0; i < routes->len; i++) { + if (addr_family == AF_INET) { + r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, i); + m = r->metric; + } else { + r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, i); + m = nm_utils_ip6_route_metric_normalize (r->metric); + } + if (!route || m < route_metric) { + route = r; + route_metric = m; + } + } + + if (route) { + if (addr_family == AF_INET) + *((NMPlatformIP4Route *) out_route) = *((NMPlatformIP4Route *) route); + else + *((NMPlatformIP6Route *) out_route) = *((NMPlatformIP6Route *) route); + success = TRUE; + } + g_array_free (routes, TRUE); + } + return success; +} + +/*********************************************/ /* DHCPv4 stuff */ static void @@ -2583,11 +2857,6 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) priv->dhcp4_state_sigid = 0; } - if (priv->dhcp4_timeout_sigid) { - g_signal_handler_disconnect (priv->dhcp4_client, priv->dhcp4_timeout_sigid); - priv->dhcp4_timeout_sigid = 0; - } - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); if (stop) @@ -2602,14 +2871,6 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) } } -static void -dhcp4_add_option_cb (gpointer key, gpointer value, gpointer user_data) -{ - nm_dhcp4_config_add_option (NM_DHCP4_CONFIG (user_data), - (const char *) key, - (const char *) value); -} - static gboolean ip4_config_merge_and_apply (NMDevice *self, NMIP4Config *config, @@ -2620,6 +2881,7 @@ ip4_config_merge_and_apply (NMDevice *self, NMConnection *connection; gboolean success; NMIP4Config *composite; + const guint32 default_route_metric = nm_device_get_ip4_route_metric (self); /* Merge all the configs into the composite config */ if (config) { @@ -2635,12 +2897,79 @@ ip4_config_merge_and_apply (NMDevice *self, if (priv->ext_ip4_config) nm_ip4_config_merge (composite, priv->ext_ip4_config); - /* Merge user overrides into the composite config */ + /* Merge WWAN config *last* to ensure modem-given settings overwrite + * any external stuff set by pppd or other scripts. + */ + if (priv->wwan_ip4_config) + nm_ip4_config_merge (composite, priv->wwan_ip4_config); + + /* Merge user overrides into the composite config. Generated+assumed + * connections come from the system not the user and merging them would + * be redundant, so don't bother. + */ connection = nm_device_get_connection (self); + priv->default_route.v4_has = FALSE; + priv->default_route.v4_is_assumed = TRUE; if (connection) { - nm_ip4_config_merge_setting (composite, - nm_connection_get_setting_ip4_config (connection), - nm_device_get_priority (self)); + gboolean assumed = nm_device_uses_assumed_connection (self); + NMPlatformIP4Route *route = &priv->default_route.v4; + + if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) { + nm_ip4_config_merge_setting (composite, + nm_connection_get_setting_ip4_config (connection), + default_route_metric); + } + + /* Add the default route. + * + * We keep track of the default route of a device in a private field. + * NMDevice needs to know the default route at this point, because the gateway + * might require a direct route (see below). + * + * But also, we don't want to add the default route to priv->ip4_config, + * because the default route from the setting might not be the same that + * NMDefaultRouteManager eventually configures (because the it might + * tweak the effective metric). + */ + if ( !assumed + && nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection)) { + guint32 gateway = 0; + + priv->default_route.v4_is_assumed = FALSE; + if ( (!commit && priv->ext_ip4_config_had_any_addresses) + || ( commit && nm_ip4_config_get_num_addresses (composite))) { + /* For managed interfaces, we can only configure a gateway, if either the external config indicates + * that we already have addresses, or if we are about to commit any addresses. + * Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any + * addresses for the route. */ + gateway = nm_ip4_config_get_gateway (composite); + if ( gateway + || nm_device_get_device_type (self) == NM_DEVICE_TYPE_MODEM) { + memset (route, 0, sizeof (*route)); + route->source = NM_IP_CONFIG_SOURCE_USER; + route->gateway = gateway; + route->metric = default_route_metric; + route->mss = nm_ip4_config_get_mss (composite); + priv->default_route.v4_has = TRUE; + + if ( gateway + && !nm_ip4_config_get_subnet_for_host (composite, gateway) + && !nm_ip4_config_get_direct_route_for_host (composite, gateway)) { + /* add a direct route to the gateway */ + NMPlatformIP4Route r = *route; + + r.network = gateway; + r.plen = 32; + r.gateway = 0; + nm_ip4_config_add_route (composite, &r); + } + } + } + } else { + /* For interfaces that are assumed and that have no default-route by configuration, we assume + * the default connection and pick up whatever is configured. */ + priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) route); + } } /* Allow setting MTU etc */ @@ -2649,7 +2978,7 @@ ip4_config_merge_and_apply (NMDevice *self, NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite); } - success = nm_device_set_ip4_config (self, composite, commit, out_reason); + success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, out_reason); g_object_unref (composite); return success; } @@ -2662,8 +2991,7 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) g_return_if_fail (config != NULL); if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) { - nm_log_warn (LOGD_DHCP4, "(%s): failed to update IPv4 config for DHCP change.", - nm_device_get_ip_iface (self)); + _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change."); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } else { /* Notify dispatcher scripts of new DHCP4 config */ @@ -2677,94 +3005,93 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) } static void -dhcp4_fail (NMDevice *device, gboolean timeout) +dhcp4_fail (NMDevice *self, gboolean timeout) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - nm_dhcp4_config_reset (priv->dhcp4_config); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + dhcp4_cleanup (self, TRUE, FALSE); if (timeout || (priv->ip4_state == IP_CONF)) - nm_device_activate_schedule_ip4_config_timeout (device); - else if (priv->ip4_state == IP_FAIL) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + nm_device_activate_schedule_ip4_config_timeout (self); + else if (priv->ip4_state == IP_DONE) + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + else + g_warn_if_reached (); +} + +static void +dhcp4_update_config (NMDevice *self, NMDhcp4Config *config, GHashTable *options) +{ + GHashTableIter iter; + const char *key, *value; + + /* Update the DHCP4 config object with new DHCP options */ + nm_dhcp4_config_reset (config); + + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) + nm_dhcp4_config_add_option (config, key, value); + + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG); } static void -dhcp4_state_changed (NMDHCPClient *client, - NMDHCPState state, +dhcp4_state_changed (NMDhcpClient *client, + NMDhcpState state, + NMIP4Config *ip4_config, + GHashTable *options, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMIP4Config *config; + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); + g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config)); - nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", - nm_device_get_iface (device), state); + _LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state); switch (state) { - case DHC_BOUND4: /* lease obtained */ - case DHC_RENEW4: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND4: /* new, different lease */ - config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); - if (!config) { - nm_log_warn (LOGD_DHCP4, "(%s): failed to get IPv4 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, + case NM_DHCP_STATE_BOUND: + if (!ip4_config) { + _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event."); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); break; } - /* Update the DHCP4 config object with new DHCP options */ - nm_dhcp4_config_reset (priv->dhcp4_config); - nm_dhcp_client_foreach_option (priv->dhcp4_client, - dhcp4_add_option_cb, - priv->dhcp4_config); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP4_CONFIG); + dhcp4_update_config (self, priv->dhcp4_config, options); if (priv->ip4_state == IP_CONF) - nm_device_activate_schedule_ip4_config_result (device, config); + nm_device_activate_schedule_ip4_config_result (self, ip4_config); else if (priv->ip4_state == IP_DONE) - dhcp4_lease_change (device, config); - g_object_unref (config); - + dhcp4_lease_change (self, ip4_config); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ - dhcp4_fail (device, TRUE); + case NM_DHCP_STATE_TIMEOUT: + dhcp4_fail (self, TRUE); break; - case DHC_END: /* dhclient exited normally */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ - /* dhclient quit and can't get/renew a lease; so kill the connection */ - dhcp4_fail (device, FALSE); + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip4_state == IP_CONF) + break; + /* Fall through */ + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: + dhcp4_fail (self, FALSE); break; default: break; } } -static void -dhcp4_timeout (NMDHCPClient *client, gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - - g_return_if_fail (nm_device_get_act_request (device) != NULL); - g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); - - nm_dhcp_client_stop (client, FALSE); - dhcp4_fail (device, TRUE); -} - static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; + const guint8 *hw_addr; + size_t hw_addr_len = 0; GByteArray *tmp = NULL; s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -2774,21 +3101,26 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); - if (priv->hw_addr_len) { - tmp = g_byte_array_sized_new (priv->hw_addr_len); - g_byte_array_append (tmp, priv->hw_addr, priv->hw_addr_len); + hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len); + if (hw_addr_len) { + tmp = g_byte_array_sized_new (hw_addr_len); + g_byte_array_append (tmp, hw_addr, hw_addr_len); } /* Begin DHCP on the interface */ g_warn_if_fail (priv->dhcp4_client == NULL); priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), nm_device_get_ip_iface (self), + nm_device_get_ip_ifindex (self), tmp, nm_connection_get_uuid (connection), - nm_device_get_priority (self), - s_ip4, + nm_device_get_ip4_route_metric (self), + nm_setting_ip_config_get_dhcp_send_hostname (s_ip4), + nm_setting_ip_config_get_dhcp_hostname (s_ip4), + nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)), priv->dhcp_timeout, - priv->dhcp_anycast_address); + priv->dhcp_anycast_address, + NULL); if (tmp) g_byte_array_free (tmp, TRUE); @@ -2802,10 +3134,6 @@ dhcp4_start (NMDevice *self, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp4_state_changed), self); - priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client, - NM_DHCP_CLIENT_SIGNAL_TIMEOUT, - G_CALLBACK (dhcp4_timeout), - self); nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE); @@ -2823,8 +3151,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); - nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 lease renewal requested", - nm_device_get_iface (self)); + _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested"); /* Terminate old DHCP instance and release the old lease */ dhcp4_cleanup (self, TRUE, release); @@ -2849,20 +3176,20 @@ release_shared_ip (gpointer data) } static gboolean -reserve_shared_ip (NMSettingIP4Config *s_ip4, NMPlatformIP4Address *address) +reserve_shared_ip (NMDevice *self, NMSettingIPConfig *s_ip4, NMPlatformIP4Address *address) { if (G_UNLIKELY (shared_ips == NULL)) shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal); memset (address, 0, sizeof (*address)); - if (s_ip4 && nm_setting_ip4_config_get_num_addresses (s_ip4)) { + if (s_ip4 && nm_setting_ip_config_get_num_addresses (s_ip4)) { /* Use the first user-supplied address */ - NMIP4Address *user = nm_setting_ip4_config_get_address (s_ip4, 0); + NMIPAddress *user = nm_setting_ip_config_get_address (s_ip4, 0); g_assert (user); - address->address = nm_ip4_address_get_address (user); - address->plen = nm_ip4_address_get_prefix (user); + nm_ip_address_get_address_binary (user, &address->address); + address->plen = nm_ip_address_get_prefix (user); } else { /* Find an unused address in the 10.42.x.x range */ guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */ @@ -2871,7 +3198,7 @@ reserve_shared_ip (NMSettingIP4Config *s_ip4, NMPlatformIP4Address *address) while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) { count += ntohl (0x100); if (count > ntohl (0xFE00)) { - nm_log_err (LOGD_SHARING, "ran out of shared IP addresses!"); + _LOGE (LOGD_SHARING, "ran out of shared IP addresses!"); return FALSE; } } @@ -2894,13 +3221,13 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso g_return_val_if_fail (self != NULL, NULL); - if (!reserve_shared_ip (nm_connection_get_setting_ip4_config (connection), &address)) { + if (!reserve_shared_ip (self, nm_connection_get_setting_ip4_config (connection), &address)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NULL; } config = nm_ip4_config_new (); - address.source = NM_PLATFORM_SOURCE_SHARED; + address.source = NM_IP_CONFIG_SOURCE_SHARED; nm_ip4_config_add_address (config, &address); /* Remove the address lock when the object gets disposed */ @@ -2914,7 +3241,79 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso /*********************************************/ static gboolean -have_any_ready_slaves (NMDevice *device, const GSList *slaves) +connection_ip4_method_requires_carrier (NMConnection *connection, + gboolean *out_ip4_enabled) +{ + const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + static const char *ip4_carrier_methods[] = { + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NULL + }; + + if (out_ip4_enabled) + *out_ip4_enabled = !!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + return _nm_utils_string_in_list (method, ip4_carrier_methods); +} + +static gboolean +connection_ip6_method_requires_carrier (NMConnection *connection, + gboolean *out_ip6_enabled) +{ + const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + static const char *ip6_carrier_methods[] = { + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NULL + }; + + if (out_ip6_enabled) + *out_ip6_enabled = !!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + return _nm_utils_string_in_list (method, ip6_carrier_methods); +} + +static gboolean +connection_requires_carrier (NMConnection *connection) +{ + NMSettingIPConfig *s_ip4, *s_ip6; + gboolean ip4_carrier_wanted, ip6_carrier_wanted; + gboolean ip4_used = FALSE, ip6_used = FALSE; + + ip4_carrier_wanted = connection_ip4_method_requires_carrier (connection, &ip4_used); + if (ip4_carrier_wanted) { + /* If IPv4 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv6 method. + */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4 && !nm_setting_ip_config_get_may_fail (s_ip4)) + return TRUE; + } + + ip6_carrier_wanted = connection_ip6_method_requires_carrier (connection, &ip6_used); + if (ip6_carrier_wanted) { + /* If IPv6 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv4 method. + */ + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6 && !nm_setting_ip_config_get_may_fail (s_ip6)) + return TRUE; + } + + /* If an IP version wants a carrier and and the other IP version isn't + * used, the connection requires carrier since it will just fail without one. + */ + if (ip4_carrier_wanted && !ip6_used) + return TRUE; + if (ip6_carrier_wanted && !ip4_used) + return TRUE; + + /* If both want a carrier, the whole connection wants a carrier */ + return ip4_carrier_wanted && ip6_carrier_wanted; +} + +static gboolean +have_any_ready_slaves (NMDevice *self, const GSList *slaves) { const GSList *iter; @@ -2955,16 +3354,11 @@ act_stage3_ip4_config_start (NMDevice *self, connection = nm_device_get_connection (self); g_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (priv->master) - g_assert_cmpstr (method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - - if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0 + if ( connection_ip4_method_requires_carrier (connection, NULL) && priv->is_master && !priv->carrier) { - nm_log_info (LOGD_IP4 | LOGD_DEVICE, - "(%s): IPv4 config waiting until carrier is on", - nm_device_get_ip_iface (self)); + _LOGI (LOGD_IP4 | LOGD_DEVICE, + "IPv4 config waiting until carrier is on"); return NM_ACT_STAGE_RETURN_WAIT; } @@ -2977,13 +3371,14 @@ act_stage3_ip4_config_start (NMDevice *self, g_slist_free (slaves); if (ready_slaves == FALSE) { - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "(%s): IPv4 config waiting until slaves are ready", - nm_device_get_ip_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "IPv4 config waiting until slaves are ready"); return NM_ACT_STAGE_RETURN_WAIT; } } + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + /* Start IPv4 addressing based on the method requested */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) ret = dhcp4_start (self, connection, reason); @@ -3004,10 +3399,8 @@ act_stage3_ip4_config_start (NMDevice *self, } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) { /* Nothing to do... */ ret = NM_ACT_STAGE_RETURN_STOP; - } else { - nm_log_warn (LOGD_IP4, "(%s): unhandled IPv4 config method '%s'; will fail", - nm_device_get_ip_iface (self), method); - } + } else + _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); return ret; } @@ -3029,33 +3422,20 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) priv->dhcp6_state_sigid = 0; } - if (priv->dhcp6_timeout_sigid) { - g_signal_handler_disconnect (priv->dhcp6_client, priv->dhcp6_timeout_sigid); - priv->dhcp6_timeout_sigid = 0; - } - - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); - if (stop) nm_dhcp_client_stop (priv->dhcp6_client, release); g_clear_object (&priv->dhcp6_client); } + nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + if (priv->dhcp6_config) { g_clear_object (&priv->dhcp6_config); g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); } } -static void -dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data) -{ - nm_dhcp6_config_add_option (NM_DHCP6_CONFIG (user_data), - (const char *) key, - (const char *) value); -} - static gboolean ip6_config_merge_and_apply (NMDevice *self, gboolean commit, @@ -3080,109 +3460,216 @@ ip6_config_merge_and_apply (NMDevice *self, if (priv->ext_ip6_config) nm_ip6_config_merge (composite, priv->ext_ip6_config); - /* Merge user overrides into the composite config */ + /* Merge WWAN config *last* to ensure modem-given settings overwrite + * any external stuff set by pppd or other scripts. + */ + if (priv->wwan_ip6_config) + nm_ip6_config_merge (composite, priv->wwan_ip6_config); + + /* Merge user overrides into the composite config. Generated+assumed + * connections come from the system not the user and merging them would + * be redundant, so don't bother. + */ connection = nm_device_get_connection (self); + priv->default_route.v6_has = FALSE; + priv->default_route.v6_is_assumed = TRUE; if (connection) { - nm_ip6_config_merge_setting (composite, - nm_connection_get_setting_ip6_config (connection), - nm_device_get_priority (self)); + gboolean assumed = nm_device_uses_assumed_connection (self); + NMPlatformIP6Route *route = &priv->default_route.v6; + + if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) { + nm_ip6_config_merge_setting (composite, + nm_connection_get_setting_ip6_config (connection), + nm_device_get_ip6_route_metric (self)); + } + + /* Add the default route. + * + * We keep track of the default route of a device in a private field. + * NMDevice needs to know the default route at this point, because the gateway + * might require a direct route (see below). + * + * But also, we don't want to add the default route to priv->ip4_config, + * because the default route from the setting might not be the same that + * NMDefaultRouteManager eventually configures (because the it might + * tweak the effective metric). + */ + if ( !assumed + && nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection)) { + const struct in6_addr *gateway = NULL; + + priv->default_route.v6_is_assumed = FALSE; + if ( (!commit && priv->ext_ip6_config_had_any_addresses) + || ( commit && nm_ip6_config_get_num_addresses (composite))) { + /* For managed interfaces, we can only configure a gateway, if either the external config indicates + * that we already have addresses, or if we are about to commit any addresses. + * Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any + * addresses for the route. */ + gateway = nm_ip6_config_get_gateway (composite); + if (gateway) { + memset (route, 0, sizeof (*route)); + route->source = NM_IP_CONFIG_SOURCE_USER; + route->gateway = *gateway; + route->metric = nm_device_get_ip6_route_metric (self); + route->mss = nm_ip6_config_get_mss (composite); + priv->default_route.v6_has = TRUE; + + if ( gateway + && !nm_ip6_config_get_subnet_for_host (composite, gateway) + && !nm_ip6_config_get_direct_route_for_host (composite, gateway)) { + /* add a direct route to the gateway */ + NMPlatformIP6Route r = *route; + + r.network = *gateway; + r.plen = 128; + r.gateway = in6addr_any; + nm_ip6_config_add_route (composite, &r); + } + } + } + } else { + /* For interfaces that are assumed and that have no default-route by configuration, we assume + * the default connection and pick up whatever is configured. */ + priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) route); + } } nm_ip6_config_addresses_sort (composite, priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + /* Allow setting MTU etc */ + if (commit) { + if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) + NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite); + } + success = nm_device_set_ip6_config (self, composite, commit, out_reason); g_object_unref (composite); return success; } static void -dhcp6_lease_change (NMDevice *device) +dhcp6_lease_change (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; if (priv->dhcp6_ip6_config == NULL) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to get DHCPv6 config for rebind", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + _LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind"); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); return; } g_assert (priv->dhcp6_client); /* sanity check */ - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); g_assert (connection); /* Apply the updated config */ - if (ip6_config_merge_and_apply (device, TRUE, &reason) == FALSE) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) { + _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event."); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } else { /* Notify dispatcher scripts of new DHCPv6 config */ - nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, connection, device, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, connection, self, NULL, NULL, NULL); } } static void -dhcp6_fail (NMDevice *device, gboolean timeout) +dhcp6_fail (NMDevice *self, gboolean timeout) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + dhcp6_cleanup (self, TRUE, FALSE); + + if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (timeout || (priv->ip6_state == IP_CONF)) + nm_device_activate_schedule_ip6_config_timeout (self); + else if (priv->ip6_state == IP_DONE) + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + else + g_warn_if_reached (); + } else { + /* not a hard failure; just live with the RA info */ + if (priv->ip6_state == IP_CONF) + nm_device_activate_schedule_ip6_config_result (self); + } +} - nm_dhcp6_config_reset (priv->dhcp6_config); +static void +dhcp6_timeout (NMDevice *self, NMDhcpClient *client) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (timeout || (priv->ip6_state == IP_CONF)) - nm_device_activate_schedule_ip6_config_timeout (device); - else if (priv->ip6_state == IP_FAIL) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) + dhcp6_fail (self, TRUE); + else { + /* not a hard failure; just live with the RA info */ + dhcp6_cleanup (self, TRUE, FALSE); + if (priv->ip6_state == IP_CONF) + nm_device_activate_schedule_ip6_config_result (self); + } } static void -dhcp6_state_changed (NMDHCPClient *client, - NMDHCPState state, +dhcp6_update_config (NMDevice *self, NMDhcp6Config *config, GHashTable *options) +{ + GHashTableIter iter; + const char *key, *value; + + /* Update the DHCP6 config object with new DHCP options */ + nm_dhcp6_config_reset (config); + + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) + nm_dhcp6_config_add_option (config, key, value); + + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); +} + +static void +dhcp6_state_changed (NMDhcpClient *client, + NMDhcpState state, + NMIP6Config *ip6_config, + GHashTable *options, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); + g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config)); - nm_log_dbg (LOGD_DHCP6, "(%s): new DHCPv6 client state %d", - nm_device_get_iface (device), state); + _LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state); switch (state) { - case DHC_BOUND6: - case DHC_RENEW6: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND6: /* new, different lease */ + case NM_DHCP_STATE_BOUND: g_clear_object (&priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); - - /* Update the DHCP6 config object with new DHCP options */ - nm_dhcp6_config_reset (priv->dhcp6_config); - if (priv->dhcp6_ip6_config) { - nm_dhcp_client_foreach_option (priv->dhcp6_client, - dhcp6_add_option_cb, - priv->dhcp6_config); + if (ip6_config) { + priv->dhcp6_ip6_config = g_object_ref (ip6_config); + dhcp6_update_config (self, priv->dhcp6_config, options); } - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG); if (priv->ip6_state == IP_CONF) { if (priv->dhcp6_ip6_config == NULL) { /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */ - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); break; } - nm_device_activate_schedule_ip6_config_result (device); + nm_device_activate_schedule_ip6_config_result (self); } else if (priv->ip6_state == IP_DONE) - dhcp6_lease_change (device); + dhcp6_lease_change (self); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ - dhcp6_fail (device, TRUE); + case NM_DHCP_STATE_TIMEOUT: + dhcp6_timeout (self, client); break; - case DHC_END: /* dhclient exited normally */ + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip6_state != IP_CONF) + dhcp6_fail (self, FALSE); + break; + case NM_DHCP_STATE_DONE: /* In IPv6 info-only mode, the client doesn't handle leases so it * may exit right after getting a response from the server. That's * normal. In that case we just ignore the exit. @@ -3190,83 +3677,45 @@ dhcp6_state_changed (NMDHCPClient *client, if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) break; /* Otherwise, fall through */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ - /* dhclient quit and can't get/renew a lease; so kill the connection */ - dhcp6_fail (device, FALSE); + case NM_DHCP_STATE_FAIL: + dhcp6_fail (self, FALSE); break; default: break; } } -static void -dhcp6_timeout (NMDHCPClient *client, gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - g_return_if_fail (nm_device_get_act_request (device) != NULL); - g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); - - nm_dhcp_client_stop (client, FALSE); - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) - dhcp6_fail (device, TRUE); - else { - /* not a hard failure; just live with the RA info */ - nm_dhcp6_config_reset (priv->dhcp6_config); - if (priv->dhcp6_ip6_config) - g_object_unref (priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = NULL; - - if (priv->ip6_state == IP_CONF) - nm_device_activate_schedule_ip6_config_result (device); - } -} - -static NMActStageReturn -dhcp6_start (NMDevice *self, - NMConnection *connection, - guint32 dhcp_opt, - NMDeviceStateReason *reason) +static gboolean +dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) { - NMSettingIP6Config *s_ip6; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMSettingIPConfig *s_ip6; GByteArray *tmp = NULL; + const guint8 *hw_addr; + size_t hw_addr_len = 0; - if (!connection) { - connection = nm_device_get_connection (self); - g_assert (connection); - } - - /* Begin a DHCP transaction on the interface */ - - /* Clear old exported DHCP options */ - if (priv->dhcp6_config) - g_object_unref (priv->dhcp6_config); - priv->dhcp6_config = nm_dhcp6_config_new (); - - g_warn_if_fail (priv->dhcp6_ip6_config == NULL); - if (priv->dhcp6_ip6_config) { - g_object_unref (priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = NULL; - } + g_assert (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); - if (priv->hw_addr_len) { - tmp = g_byte_array_sized_new (priv->hw_addr_len); - g_byte_array_append (tmp, priv->hw_addr, priv->hw_addr_len); + hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len); + if (hw_addr_len) { + tmp = g_byte_array_sized_new (hw_addr_len); + g_byte_array_append (tmp, hw_addr, hw_addr_len); } priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (), nm_device_get_ip_iface (self), + nm_device_get_ip_ifindex (self), tmp, nm_connection_get_uuid (connection), - nm_device_get_priority (self), - nm_connection_get_setting_ip6_config (connection), + nm_device_get_ip6_route_metric (self), + nm_setting_ip_config_get_dhcp_send_hostname (s_ip6), + nm_setting_ip_config_get_dhcp_hostname (s_ip6), priv->dhcp_timeout, priv->dhcp_anycast_address, - (dhcp_opt == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE); + (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, + nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))); if (tmp) g_byte_array_free (tmp, TRUE); @@ -3275,65 +3724,85 @@ dhcp6_start (NMDevice *self, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp6_state_changed), self); - priv->dhcp6_timeout_sigid = g_signal_connect (priv->dhcp6_client, - NM_DHCP_CLIENT_SIGNAL_TIMEOUT, - G_CALLBACK (dhcp6_timeout), - self); + } - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!nm_setting_ip6_config_get_may_fail (s_ip6) || - !strcmp (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) - nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); + return !!priv->dhcp6_client; +} - /* DHCP devices will be notified by the DHCP manager when stuff happens */ - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else { +static gboolean +dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + NMSettingIPConfig *s_ip6; + + g_clear_object (&priv->dhcp6_config); + priv->dhcp6_config = nm_dhcp6_config_new (); + + g_warn_if_fail (priv->dhcp6_ip6_config == NULL); + g_clear_object (&priv->dhcp6_ip6_config); + + connection = nm_device_get_connection (self); + g_assert (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (!nm_setting_ip_config_get_may_fail (s_ip6) || + !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) + nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); + + if (wait_for_ll) { + NMActStageReturn ret; + + /* ensure link local is ready... */ + ret = linklocal6_start (self); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { + /* success; wait for the LL address to show up */ + return TRUE; + } + + /* success; already have the LL address; kick off DHCP */ + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + } + + if (!dhcp6_start_with_link_ready (self, connection)) { *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; - ret = NM_ACT_STAGE_RETURN_FAILURE; + return FALSE; } - return ret; + return TRUE; } gboolean nm_device_dhcp6_renew (NMDevice *self, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret; - NMDeviceStateReason reason; - NMConnection *connection; g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE); - nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 lease renewal requested", - nm_device_get_iface (self)); + _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested"); /* Terminate old DHCP instance and release the old lease */ dhcp6_cleanup (self, TRUE, release); - connection = nm_device_get_connection (self); - g_assert (connection); - /* Start DHCP again on the interface */ - ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason); - - return (ret != NM_ACT_STAGE_RETURN_FAILURE); + return dhcp6_start (self, FALSE, NULL); } /******************************************/ static gboolean -linklocal6_config_is_ready (const NMIP6Config *ip6_config) +have_ip6_address (const NMIP6Config *ip6_config, gboolean linklocal) { - int i; + guint i; if (!ip6_config) return FALSE; + linklocal = !!linklocal; + for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) { const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ip6_config, i); - if (IN6_IS_ADDR_LINKLOCAL (&addr->address) && + if ((IN6_IS_ADDR_LINKLOCAL (&addr->address) == linklocal) && !(addr->flags & IFA_F_TENTATIVE)) return TRUE; } @@ -3359,8 +3828,7 @@ linklocal6_timeout_cb (gpointer user_data) linklocal6_cleanup (self); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: waiting for link-local addresses failed due to timeout", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout"); nm_device_activate_schedule_ip6_config_timeout (self); return G_SOURCE_REMOVE; @@ -3374,7 +3842,7 @@ linklocal6_complete (NMDevice *self) const char *method; g_assert (priv->linklocal6_timeout_id); - g_assert (linklocal6_config_is_ready (priv->ip6_config)); + g_assert (have_ip6_address (priv->ip6_config, TRUE)); linklocal6_cleanup (self); @@ -3383,17 +3851,70 @@ linklocal6_complete (NMDevice *self) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: waiting for link-local addresses successful, continue with method %s", - nm_device_get_iface (self), method); + _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method); - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) - addrconf6_start_with_link_ready (self); - else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { + if (!addrconf6_start_with_link_ready (self)) { + /* Time out IPv6 instead of failing the entire activation */ + nm_device_activate_schedule_ip6_config_timeout (self); + } + } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { + if (!dhcp6_start_with_link_ready (self, connection)) { + /* Time out IPv6 instead of failing the entire activation */ + nm_device_activate_schedule_ip6_config_timeout (self); + } + } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) nm_device_activate_schedule_ip6_config_result (self); else g_return_if_fail (FALSE); } +static void +check_and_add_ipv6ll_addr (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ip_ifindex = nm_device_get_ip_ifindex (self); + NMUtilsIPv6IfaceId iid; + struct in6_addr lladdr; + guint i, n; + + if (priv->nm_ipv6ll == FALSE) + return; + + if (priv->ip6_config) { + n = nm_ip6_config_get_num_addresses (priv->ip6_config); + for (i = 0; i < n; i++) { + const NMPlatformIP6Address *addr; + + addr = nm_ip6_config_get_address (priv->ip6_config, i); + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + /* Already have an LL address, nothing to do */ + return; + } + } + } + + if (!nm_device_get_ip_iface_identifier (self, &iid)) { + _LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 may be broken"); + return; + } + + memset (&lladdr, 0, sizeof (lladdr)); + lladdr.s6_addr16[0] = htons (0xfe80); + nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid); + _LOGD (LOGD_IP6, "adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL)); + if (!nm_platform_ip6_address_add (ip_ifindex, + lladdr, + in6addr_any, + 64, + NM_PLATFORM_LIFETIME_PERMANENT, + NM_PLATFORM_LIFETIME_PERMANENT, + 0)) { + _LOGW (LOGD_IP6, "failed to add IPv6 link-local address %s", + nm_utils_inet6_ntop (&lladdr, NULL)); + } +} + static NMActStageReturn linklocal6_start (NMDevice *self) { @@ -3403,15 +3924,16 @@ linklocal6_start (NMDevice *self) linklocal6_cleanup (self); - if (linklocal6_config_is_ready (priv->ip6_config)) + if (have_ip6_address (priv->ip6_config, TRUE)) return NM_ACT_STAGE_RETURN_SUCCESS; connection = nm_device_get_connection (self); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", - nm_device_get_iface (self), method); + _LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", method); + + check_and_add_ipv6ll_addr (self); priv->linklocal6_timeout_id = g_timeout_add_seconds (5, linklocal6_timeout_cb, self); @@ -3468,12 +3990,10 @@ print_support_extended_ifa_flags (NMSettingIP6ConfigPrivacy use_tempaddr) } static void -rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device) +rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMConnection *connection; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int i; - NMDeviceStateReason reason; static int system_support = -1; guint ifa_flags = 0x00; @@ -3499,8 +4019,6 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device } g_return_if_fail (priv->act_request); - connection = nm_device_get_connection (device); - g_assert (connection); if (!priv->ac_ip6_config) priv->ac_ip6_config = nm_ip6_config_new (); @@ -3536,7 +4054,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.source = NM_PLATFORM_SOURCE_RDISC; + address.source = NM_IP_CONFIG_SOURCE_RDISC; address.flags = ifa_flags; nm_ip6_config_add_address (priv->ac_ip6_config, &address); @@ -3560,8 +4078,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device route.network = discovered_route->network; route.plen = discovered_route->plen; route.gateway = discovered_route->gateway; - route.source = NM_PLATFORM_SOURCE_RDISC; - route.metric = nm_device_get_priority (device); + route.source = NM_IP_CONFIG_SOURCE_RDISC; + route.metric = nm_device_get_ip6_route_metric (self); nm_ip6_config_add_route (priv->ac_ip6_config, &route); } @@ -3591,39 +4109,99 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device } if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { - dhcp6_cleanup (device, TRUE, TRUE); + dhcp6_cleanup (self, TRUE, TRUE); priv->dhcp6_mode = rdisc->dhcp_level; - - switch (priv->dhcp6_mode) { - case NM_RDISC_DHCP_LEVEL_NONE: - break; - default: - nm_log_info (LOGD_DEVICE | LOGD_DHCP6, - "Activation (%s) Stage 3 of 5 (IP Configure Start) starting DHCPv6" - " as requested by IPv6 router...", - priv->iface); - switch (dhcp6_start (device, connection, priv->dhcp6_mode, &reason)) { - case NM_ACT_STAGE_RETURN_SUCCESS: - g_warn_if_reached (); - break; - case NM_ACT_STAGE_RETURN_POSTPONE: - return; - default: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - return; + if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) { + NMDeviceStateReason reason; + + _LOGI (LOGD_DEVICE | LOGD_DHCP6, + "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6" + " as requested by IPv6 router..."); + if (!dhcp6_start (self, FALSE, &reason)) { + if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } + return; } } - if (changed & NM_RDISC_CONFIG_HOP_LIMIT) { + /* hop_limit == 0 is a special value "unspecified", so do not touch + * in this case */ + if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) { char val[16]; g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit); - nm_device_ipv6_sysctl_set (device, "hop_limit", val); + nm_device_ipv6_sysctl_set (self, "hop_limit", val); } - nm_device_activate_schedule_ip6_config_result (device); + if (changed & NM_RDISC_CONFIG_MTU) { + char val[16]; + + g_snprintf (val, sizeof (val), "%d", rdisc->mtu); + nm_device_ipv6_sysctl_set (self, "mtu", val); + } + + nm_device_activate_schedule_ip6_config_result (self); +} + +static void +rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + /* We don't want to stop listening for router advertisements completely, + * but instead let device activation continue activating. If an RA + * shows up later, we'll use it as long as the device is not disconnected. + */ + + _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement"); + if (priv->ip6_state == IP_CONF) { + /* If RA is our only source of addressing information and we don't + * ever receive one, then time out IPv6. But if there is other + * IPv6 configuration, like manual IPv6 addresses or external IPv6 + * config, consider that sufficient for IPv6 success. + */ + if (have_ip6_address (priv->ip6_config, FALSE)) + nm_device_activate_schedule_ip6_config_result (self); + else + nm_device_activate_schedule_ip6_config_timeout (self); + } +} + +static gboolean +addrconf6_start_with_link_ready (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMUtilsIPv6IfaceId iid; + + g_assert (priv->rdisc); + + if (!nm_device_get_ip_iface_identifier (self, &iid)) { + _LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 cannot continue"); + return FALSE; + } + nm_rdisc_set_iid (priv->rdisc, iid); + + /* Apply any manual configuration before starting RA */ + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration"); + + nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + + priv->rdisc_changed_id = g_signal_connect (priv->rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (rdisc_config_changed), + self); + priv->rdisc_timeout_id = g_signal_connect (priv->rdisc, + NM_RDISC_RA_TIMEOUT, + G_CALLBACK (rdisc_ra_timeout), + self); + nm_rdisc_start (priv->rdisc); + return TRUE; } static gboolean @@ -3645,46 +4223,26 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface); if (!priv->rdisc) { - nm_log_err (LOGD_IP6, "(%s): failed to start router discovery.", ip_iface); + _LOGE (LOGD_IP6, "failed to start router discovery (%s)", ip_iface); return FALSE; } priv->rdisc_use_tempaddr = use_tempaddr; print_support_extended_ifa_flags (use_tempaddr); - if (!nm_setting_ip6_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) + if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE); /* ensure link local is ready... */ ret = linklocal6_start (self); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) - addrconf6_start_with_link_ready (self); - else - g_return_val_if_fail (ret == NM_ACT_STAGE_RETURN_POSTPONE, TRUE); - - return TRUE; -} - -static void -addrconf6_start_with_link_ready (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - g_assert (priv->rdisc); - - /* FIXME: what if interface has no lladdr, like PPP? */ - if (priv->hw_addr_len) - nm_rdisc_set_lladdr (priv->rdisc, (const char *) priv->hw_addr, priv->hw_addr_len); - - nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); - nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); - - priv->rdisc_config_changed_sigid = g_signal_connect (priv->rdisc, NM_RDISC_CONFIG_CHANGED, - G_CALLBACK (rdisc_config_changed), self); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { + /* success; wait for the LL address to show up */ + return TRUE; + } - nm_rdisc_start (priv->rdisc); + /* success; already have the LL address; kick off router discovery */ + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + return addrconf6_start_with_link_ready (self); } static void @@ -3692,10 +4250,14 @@ addrconf6_cleanup (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->rdisc_config_changed_sigid) { - g_signal_handler_disconnect (priv->rdisc, - priv->rdisc_config_changed_sigid); - priv->rdisc_config_changed_sigid = 0; + if (priv->rdisc_changed_id) { + g_signal_handler_disconnect (priv->rdisc, priv->rdisc_changed_id); + priv->rdisc_changed_id = 0; + } + + if (priv->rdisc_timeout_id) { + g_signal_handler_disconnect (priv->rdisc, priv->rdisc_timeout_id); + priv->rdisc_timeout_id = 0; } nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); @@ -3744,8 +4306,53 @@ restore_ip6_properties (NMDevice *self) gpointer key, value; g_hash_table_iter_init (&iter, priv->ip6_saved_properties); - while (g_hash_table_iter_next (&iter, &key, &value)) + while (g_hash_table_iter_next (&iter, &key, &value)) { + /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */ + if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0) + continue; nm_device_ipv6_sysctl_set (self, key, value); + } +} + +static inline void +set_disable_ipv6 (NMDevice *self, const char *value) +{ + /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */ + if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", value); +} + +static inline void +set_nm_ipv6ll (NMDevice *self, gboolean enable) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ifindex = nm_device_get_ip_ifindex (self); + const char *iface = nm_device_get_ip_iface (self); + char *value; + + if (!nm_platform_check_support_user_ipv6ll ()) + return; + + priv->nm_ipv6ll = enable; + if (ifindex > 0) { + const char *detail = enable ? "enable" : "disable"; + + _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail); + if ( !nm_platform_link_set_user_ipv6ll_enabled (ifindex, enable) + && nm_platform_get_error () != NM_PLATFORM_ERROR_NOT_FOUND) + _LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail); + + if (enable) { + /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ + value = nm_platform_sysctl_get (nm_utils_ip6_property_path (iface, "disable_ipv6")); + if (g_strcmp0 (value, "0") == 0) { + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); + } + g_free (value); + } + + } } static NMSettingIP6ConfigPrivacy @@ -3838,15 +4445,11 @@ act_stage3_ip6_config_start (NMDevice *self, connection = nm_device_get_connection (self); g_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (priv->master) - g_assert_cmpstr (method, ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - - if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0 + if ( connection_ip4_method_requires_carrier (connection, NULL) && priv->is_master && !priv->carrier) { - nm_log_info (LOGD_IP6 | LOGD_DEVICE, - "(%s): IPv6 config waiting until carrier is on", ip_iface); + _LOGI (LOGD_IP6 | LOGD_DEVICE, + "IPv6 config waiting until carrier is on"); return NM_ACT_STAGE_RETURN_WAIT; } @@ -3859,23 +4462,41 @@ act_stage3_ip6_config_start (NMDevice *self, g_slist_free (slaves); if (ready_slaves == FALSE) { - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "(%s): IPv6 config waiting until slaves are ready", - ip_iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "IPv6 config waiting until slaves are ready"); return NM_ACT_STAGE_RETURN_WAIT; } } priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE; + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { - if (!priv->master) + if (!priv->master) { + gboolean old_nm_ipv6ll = priv->nm_ipv6ll; + + /* When activating an IPv6 'ignore' connection we need to revert back + * to kernel IPv6LL, but the kernel won't actually assign an address + * to the interface until disable_ipv6 is bounced. + */ + set_nm_ipv6ll (self, FALSE); + if (old_nm_ipv6ll == TRUE) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); restore_ip6_properties (self); + } return NM_ACT_STAGE_RETURN_STOP; } + /* Any method past this point requires an IPv6LL address. Use NM-controlled + * IPv6LL if this is not an assumed connection, since assumed connections + * will already have IPv6 set up. + */ + if (!nm_device_uses_assumed_connection (self)) + set_nm_ipv6ll (self, TRUE); + /* Re-enable IPv6 on the interface */ - nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); + set_disable_ipv6 (self, "0"); /* Enable/disable IPv6 Privacy Extensions. * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf), @@ -3883,10 +4504,10 @@ act_stage3_ip6_config_start (NMDevice *self, */ ip6_privacy = ip6_use_tempaddr (); if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) { - NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection); + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6); + ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)); } ip6_privacy = use_tempaddr_clamp (ip6_privacy); @@ -3905,17 +4526,19 @@ act_stage3_ip6_config_start (NMDevice *self, } } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED; - ret = dhcp6_start (self, connection, priv->dhcp6_mode, reason); + if (!dhcp6_start (self, TRUE, reason)) { + /* IPv6 might be disabled; allow IPv4 to proceed */ + ret = NM_ACT_STAGE_RETURN_STOP; + } else + ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) { /* New blank config */ *out_config = nm_ip6_config_new (); g_assert (*out_config); ret = NM_ACT_STAGE_RETURN_SUCCESS; - } else { - nm_log_warn (LOGD_IP6, "(%s): unhandled IPv6 config method '%s'; will fail", - nm_device_get_ip_iface (self), method); - } + } else + _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method); /* Other methods (shared) aren't implemented yet */ @@ -4015,6 +4638,42 @@ nm_device_activate_stage3_ip6_start (NMDevice *self) } /* + * nm_device_check_ip_failed + * + * Progress the device to appropriate state if both IPv4 and IPv6 failed + */ +static void +nm_device_check_ip_failed (NMDevice *self, gboolean may_fail) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceState state; + + if ( priv->ip4_state != IP_FAIL + || priv->ip6_state != IP_FAIL) + return; + + if (nm_device_uses_assumed_connection (self)) { + /* We have assumed configuration, but couldn't + * redo it. No problem, move to check state. */ + priv->ip4_state = priv->ip6_state = IP_DONE; + state = NM_DEVICE_STATE_IP_CHECK; + } else if ( may_fail + && get_ip_config_may_fail (self, AF_INET) + && get_ip_config_may_fail (self, AF_INET6)) { + /* Couldn't start either IPv6 and IPv4 autoconfiguration, + * but both are allowed to fail. */ + state = NM_DEVICE_STATE_SECONDARIES; + } else { + /* Autoconfiguration attempted without success. */ + state = NM_DEVICE_STATE_FAILED; + } + + nm_device_state_changed (self, + state, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); +} + +/* * nm_device_activate_stage3_ip_config_start * * Begin automatic/manual IP configuration @@ -4025,7 +4684,6 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActiveConnection *master; NMDevice *master_device; @@ -4034,15 +4692,12 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) priv->ip4_state = priv->ip6_state = IP_WAIT; - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) started..."); nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); /* Device should be up before we can do anything with it */ - if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) { - nm_log_warn (LOGD_DEVICE, "(%s): interface %s not up for IP configuration", - iface, nm_device_get_ip_iface (self)); - } + if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); /* If the device is a slave, then we don't do any IP configuration but we * use the IP config stage to indicate to the master we're ready for @@ -4057,10 +4712,9 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) if (master) { master_device = nm_active_connection_get_device (master); if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) { - nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on master '%s'", - nm_device_get_iface (self), - nm_connection_get_id (nm_device_get_connection (self)), - master_device ? nm_device_get_iface (master_device) : "(unknown)"); + _LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'", + nm_connection_get_id (nm_device_get_connection (self)), + master_device ? nm_device_get_iface (master_device) : "(unknown)"); } goto out; } @@ -4073,13 +4727,10 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) if (!nm_device_activate_stage3_ip6_start (self)) goto out; - if (priv->ip4_state == IP_FAIL && priv->ip6_state == IP_FAIL) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } + nm_device_check_ip_failed (self, TRUE); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) complete."); return FALSE; } @@ -4087,8 +4738,14 @@ out: static void fw_change_zone_cb (GError *error, gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice *self; + NMDevicePrivate *priv; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_DEVICE (user_data); + priv = NM_DEVICE_GET_PRIVATE (self); priv->fw_call = NULL; @@ -4097,9 +4754,7 @@ fw_change_zone_cb (GError *error, gpointer user_data) } activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); - - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) scheduled.", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled."); } /* @@ -4120,15 +4775,24 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); + g_return_if_fail (!priv->fw_call); + /* Add the interface to the specified firewall zone */ connection = nm_device_get_connection (self); g_assert (connection); s_con = nm_connection_get_setting_connection (connection); zone = nm_setting_connection_get_zone (s_con); - nm_log_dbg (LOGD_DEVICE, "Activation (%s) setting firewall zone '%s'", - nm_device_get_iface (self), zone ? zone : "default"); - priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_manager, + + if (nm_device_uses_assumed_connection (self)) { + _LOGD (LOGD_DEVICE, "Activation: skip setting firewall zone '%s' for assumed device", zone ? zone : "default"); + activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled."); + return; + } + + _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default"); + priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (self), zone, FALSE, @@ -4139,7 +4803,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) static NMActStageReturn act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - if (nm_device_ip_config_should_fail (self, FALSE)) { + if (!get_ip_config_may_fail (self, AF_INET)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -4158,17 +4822,14 @@ nm_device_activate_ip4_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) started...", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) started..."); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) @@ -4181,16 +4842,11 @@ nm_device_activate_ip4_config_timeout (gpointer user_data) priv->ip4_state = IP_FAIL; - /* If IPv4 failed and IPv6 failed, the activation fails */ - if (priv->ip6_state == IP_FAIL) - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_check_ip_failed (self, FALSE); out: - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) complete.", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) complete."); return FALSE; } @@ -4213,16 +4869,15 @@ nm_device_activate_schedule_ip4_config_timeout (NMDevice *self) activation_source_schedule (self, nm_device_activate_ip4_config_timeout, AF_INET); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) scheduled..."); } static NMActStageReturn act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - if (nm_device_ip_config_should_fail (self, TRUE)) { + if (!get_ip_config_may_fail (self, AF_INET6)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -4242,17 +4897,14 @@ nm_device_activate_ip6_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET6); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) started...", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) started..."); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) @@ -4265,16 +4917,11 @@ nm_device_activate_ip6_config_timeout (gpointer user_data) priv->ip6_state = IP_FAIL; - /* If IPv6 failed and IPv4 failed, the activation fails */ - if (priv->ip4_state == IP_FAIL) - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_check_ip_failed (self, FALSE); out: - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) complete.", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) complete."); return FALSE; } @@ -4297,9 +4944,8 @@ nm_device_activate_schedule_ip6_config_timeout (NMDevice *self) activation_source_schedule (self, nm_device_activate_ip6_config_timeout, AF_INET6); - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) scheduled..."); } static void @@ -4320,16 +4966,19 @@ share_init (void) "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323", NULL }; char **iter; + int errsv; if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_forward", "1")) { - nm_log_err (LOGD_SHARING, "Error starting IP forwarding: (%d) %s", - errno, strerror (errno)); + errsv = errno; + nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + errsv, strerror (errsv)); return FALSE; } if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_dynaddr", "1")) { - nm_log_err (LOGD_SHARING, "error starting IP forwarding: (%d) %s", - errno, strerror (errno)); + errsv = errno; + nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + errsv, strerror (errsv)); } for (iter = modules; *iter; iter++) { @@ -4339,7 +4988,7 @@ share_init (void) if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, share_child_setup, NULL, NULL, NULL, &status, &error)) { - nm_log_err (LOGD_SHARING, "error loading NAT module %s: (%d) %s", + nm_log_err (LOGD_SHARING, "share: error loading NAT module %s: (%d) %s", *iter, error ? error->code : 0, (error && error->message) ? error->message : "unknown"); if (error) @@ -4412,9 +5061,8 @@ start_sharing (NMDevice *self, NMIP4Config *config) nm_act_request_set_shared (req, TRUE); if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) { - nm_log_err (LOGD_SHARING, "(%s/%s): failed to start dnsmasq: %s", - nm_device_get_iface (self), ip_iface, - (error && error->message) ? error->message : "(unknown)"); + _LOGE (LOGD_SHARING, "share: (%s) failed to start dnsmasq: %s", + ip_iface, (error && error->message) ? error->message : "(unknown)"); g_error_free (error); nm_act_request_set_shared (req, FALSE); return FALSE; @@ -4429,13 +5077,12 @@ start_sharing (NMDevice *self, NMIP4Config *config) static void send_arps (NMDevice *self, const char *mode_arg) { - const char *argv[] = { "/sbin/arping", mode_arg, "-q", "-I", nm_device_get_ip_iface (self), "-c", "1", NULL, NULL }; + const char *argv[] = { NULL, mode_arg, "-q", "-I", nm_device_get_ip_iface (self), "-c", "1", NULL, NULL }; int ip_arg = G_N_ELEMENTS (argv) - 2; NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; int i, num; - NMIP4Address *addr; - guint32 ipaddr; + NMIPAddress *addr; GError *error = NULL; connection = nm_device_get_connection (self); @@ -4444,24 +5091,33 @@ send_arps (NMDevice *self, const char *mode_arg) s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) return; - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); + if (num == 0) + return; + + argv[0] = nm_utils_find_helper ("arping", NULL, NULL); + if (!argv[0]) { + _LOGW (LOGD_DEVICE | LOGD_IP4, "arping could not be found; no ARPs will be sent"); + return; + } for (i = 0; i < num; i++) { - addr = nm_setting_ip4_config_get_address (s_ip4, i); - ipaddr = nm_ip4_address_get_address (addr); - argv[ip_arg] = (char *) nm_utils_inet4_ntop (ipaddr, NULL); - - nm_log_dbg (LOGD_DEVICE | LOGD_IP4, - "Running arping %s -I %s %s", - mode_arg, nm_device_get_iface (self), argv[ip_arg]); - g_spawn_async (NULL, (char **) argv, NULL, - G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, - nm_unblock_posix_signals, - NULL, NULL, &error); - if (error) { - nm_log_warn (LOGD_DEVICE | LOGD_IP4, - "Could not send ARP for local address %s: %s", - argv[ip_arg], error->message); + gs_free char *tmp_str = NULL; + gboolean success; + + addr = nm_setting_ip_config_get_address (s_ip4, i); + argv[ip_arg] = nm_ip_address_get_address (addr); + + _LOGD (LOGD_DEVICE | LOGD_IP4, + "arping: run %s", (tmp_str = g_strjoinv (" ", (char **) argv))); + success = g_spawn_async (NULL, (char **) argv, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + nm_unblock_posix_signals, + NULL, NULL, &error); + if (!success) { + _LOGW (LOGD_DEVICE | LOGD_IP4, + "arping: could not send ARP for local address %s: %s", + argv[ip_arg], error->message); g_clear_error (&error); } } @@ -4497,7 +5153,7 @@ arp_announce (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; int num; arp_cleanup (self); @@ -4511,7 +5167,7 @@ arp_announce (NMDevice *self) s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) return; - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); if (num == 0) return; @@ -4525,33 +5181,33 @@ nm_device_activate_ip4_config_commit (gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActRequest *req; - const char *iface, *method; + const char *method; NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + int ip_ifindex; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) started...", - iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) started..."); req = nm_device_get_act_request (self); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); - /* Device should be up before we can do anything with it */ - if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) { - nm_log_warn (LOGD_DEVICE, "(%s): interface %s not up for IP configuration", - iface, nm_device_get_ip_iface (self)); + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex (self); + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { + nm_platform_link_set_up (ip_ifindex); + if (!nm_platform_link_is_up (ip_ifindex)) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); } /* NULL to use the existing priv->dev_ip4_config */ if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) { - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 5 of 5 (IPv4 Commit) failed", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 5 of 5 (IPv4 Commit) failed"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); goto out; } @@ -4561,7 +5217,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { if (!start_sharing (self, priv->ip4_config)) { - nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IPv4 Commit) start sharing failed.", iface); + _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed."); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); goto out; } @@ -4593,8 +5249,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) complete.", - iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) complete."); return FALSE; } @@ -4605,17 +5260,16 @@ nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *conf NMDevicePrivate *priv; g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_IP4_CONFIG (config)); priv = NM_DEVICE_GET_PRIVATE (self); g_clear_object (&priv->dev_ip4_config); - priv->dev_ip4_config = g_object_ref (config); + if (config) + priv->dev_ip4_config = g_object_ref (config); activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 5 of 5 (IPv4 Configure Commit) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 5 of 5 (IPv4 Configure Commit) scheduled..."); } gboolean @@ -4639,27 +5293,27 @@ nm_device_activate_ip6_config_commit (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO; NMActRequest *req; - const char *iface; NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + int ip_ifindex; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET6); - iface = nm_device_get_iface (self); - nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) started...", iface); + _LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) started..."); req = nm_device_get_act_request (self); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); - /* Device should be up before we can do anything with it */ - g_warn_if_fail (nm_platform_link_is_up (nm_device_get_ip_ifindex (self))); - - /* Allow setting MTU etc */ - if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) - NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self); + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex (self); + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { + nm_platform_link_set_up (ip_ifindex); + if (!nm_platform_link_is_up (ip_ifindex)) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); + } if (ip6_config_merge_and_apply (self, TRUE, &reason)) { /* If IPv6 wasn't the first IP to complete, and DHCP was used, @@ -4686,13 +5340,12 @@ nm_device_activate_ip6_config_commit (gpointer user_data) if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); } else { - nm_log_warn (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 5 of 5 (IPv6 Commit) failed", - iface); + _LOGW (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 5 of 5 (IPv6 Commit) failed"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } - nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) complete.", iface); + _LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) complete."); return FALSE; } @@ -4705,11 +5358,16 @@ nm_device_activate_schedule_ip6_config_result (NMDevice *self) g_return_if_fail (NM_IS_DEVICE (self)); + /* If IP had previously failed, move it back to IP_CONF since we + * clearly now have configuration. + */ + if (priv->ip6_state == IP_FAIL) + priv->ip6_state = IP_CONF; + activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6); - nm_log (LOGD_DEVICE | LOGD_IP6, level, - "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...", - nm_device_get_iface (self)); + _LOG (level, LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 5 of 5 (IPv6 Commit) scheduled..."); } gboolean @@ -4775,7 +5433,7 @@ _update_ip4_address (NMDevice *self) fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_err (LOGD_IP4, "couldn't open control socket."); + _LOGE (LOGD_IP4, "couldn't open control socket."); return; } @@ -4790,17 +5448,17 @@ _update_ip4_address (NMDevice *self) } gboolean -nm_device_get_is_nm_owned (NMDevice *device) +nm_device_get_is_nm_owned (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->is_nm_owned; + return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned; } void -nm_device_set_nm_owned (NMDevice *device) +nm_device_set_nm_owned (NMDevice *self) { - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - NM_DEVICE_GET_PRIVATE (device)->is_nm_owned = TRUE; + NM_DEVICE_GET_PRIVATE (self)->is_nm_owned = TRUE; } /* @@ -4814,6 +5472,7 @@ static gboolean delete_on_deactivate_link_delete (gpointer user_data) { DeleteOnDeactivateData *data = user_data; + NMDevice *self = data->device; if (data->device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device); @@ -4822,8 +5481,8 @@ delete_on_deactivate_link_delete (gpointer user_data) priv->delete_on_deactivate_data = NULL; } - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", + data->ifindex, data->idle_add_id); nm_platform_link_delete (data->ifindex); g_free (data); return FALSE; @@ -4841,8 +5500,8 @@ delete_on_deactivate_unschedule (NMDevice *self) g_source_remove (data->idle_add_id); g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device); - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", + data->ifindex, data->idle_add_id); g_free (data); } } @@ -4857,6 +5516,8 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) return; if (!priv->is_nm_owned) return; + if (priv->queued_act_request) + return; if (!nm_device_is_software (self)) return; if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED) @@ -4872,17 +5533,17 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data); priv->delete_on_deactivate_data = data; - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d for [%s] (id=%u)", - ifindex, nm_device_get_iface (self), data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)", + ifindex, data->idle_add_id); } static void -disconnect_cb (NMDevice *device, +disconnect_cb (NMDevice *self, DBusGMethodInvocation *context, GError *error, gpointer user_data) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GError *local = NULL; if (error) { @@ -4898,9 +5559,9 @@ disconnect_cb (NMDevice *device, dbus_g_method_return_error (context, local); g_error_free (local); } else { - priv->autoconnect = FALSE; + nm_device_set_autoconnect (self, FALSE); - nm_device_state_changed (device, + nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_USER_REQUESTED); dbus_g_method_return (context); @@ -4908,12 +5569,12 @@ disconnect_cb (NMDevice *device, } static void -impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) +impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context) { NMConnection *connection; GError *error = NULL; - if (NM_DEVICE_GET_PRIVATE (device)->act_request == NULL) { + if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) { error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, "This device is not active"); @@ -4922,11 +5583,11 @@ impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) return; } - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); g_assert (connection); /* Ask the manager to authenticate this request for us */ - g_signal_emit (device, signals[AUTH_REQUEST], 0, + g_signal_emit (self, signals[AUTH_REQUEST], 0, context, connection, NM_AUTH_PERMISSION_NETWORK_CONTROL, @@ -4936,6 +5597,46 @@ impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) } static void +delete_cb (NMDevice *self, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) +{ + if (error) { + dbus_g_method_return_error (context, error); + return; + } + + /* Authorized */ + nm_platform_link_delete (nm_device_get_ifindex (self)); + dbus_g_method_return (context); +} + +static void +impl_device_delete (NMDevice *self, DBusGMethodInvocation *context) +{ + GError *error = NULL; + + if (!nm_device_is_software (self)) { + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device"); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Ask the manager to authenticate this request for us */ + g_signal_emit (self, signals[AUTH_REQUEST], 0, + context, + NULL, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + delete_cb, + NULL); +} + +static void _device_activate (NMDevice *self, NMActRequest *req) { NMDevicePrivate *priv; @@ -4949,9 +5650,8 @@ _device_activate (NMDevice *self, NMActRequest *req) connection = nm_act_request_get_connection (req); g_assert (connection); - nm_log_info (LOGD_DEVICE, "Activation (%s) starting connection '%s'", - nm_device_get_iface (self), - nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE, "Activation: starting connection '%s'", + nm_connection_get_id (connection)); delete_on_deactivate_unschedule (self); @@ -4986,8 +5686,7 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req) priv->queued_act_request = g_object_ref (req); /* Deactivate existing activation request first */ - nm_log_info (LOGD_DEVICE, "(%s): disconnecting for new activation request.", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "disconnecting for new activation request."); nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NONE); @@ -5000,14 +5699,14 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req) * */ gboolean -nm_device_is_activating (NMDevice *device) +nm_device_is_activating (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - state = nm_device_get_state (device); + state = nm_device_get_state (self); if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES) return TRUE; @@ -5021,7 +5720,7 @@ nm_device_is_activating (NMDevice *device) /* IP Configuration stuff */ -NMDHCP4Config * +NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -5041,6 +5740,7 @@ nm_device_get_ip4_config (NMDevice *self) static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *new_config, + guint32 default_route_metric, gboolean commit, NMDeviceStateReason *reason) { @@ -5062,7 +5762,12 @@ nm_device_set_ip4_config (NMDevice *self, /* Always commit to nm-platform to update lifetimes */ if (commit && new_config) { - success = nm_ip4_config_commit (new_config, ip_ifindex); + gboolean assumed = nm_device_uses_assumed_connection (self); + + /* for assumed devices we set the device_route_metric to the default which will + * stop nm_platform_ip4_address_sync() to replace the device routes. */ + success = nm_ip4_config_commit (new_config, ip_ifindex, + assumed ? NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE : default_route_metric); if (!success) reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED; } @@ -5073,8 +5778,8 @@ nm_device_set_ip4_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip4_config_replace (old_config, new_config, &has_changes); if (has_changes) { - nm_log_dbg (LOGD_IP4, "(%s): update IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP4, "update IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (old_config)); } } else { has_changes = TRUE; @@ -5085,18 +5790,20 @@ nm_device_set_ip4_config (NMDevice *self, nm_ip4_config_export (new_config); } - nm_log_dbg (LOGD_IP4, "(%s): set IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (new_config)); + _LOGD (LOGD_IP4, "set IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (new_config)); } } else if (old_config) { has_changes = TRUE; priv->ip4_config = NULL; - nm_log_dbg (LOGD_IP4, "(%s): clear IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP4, "clear IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (old_config)); /* Device config is invalid if combined config is invalid */ g_clear_object (&priv->dev_ip4_config); } + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + if (has_changes) { _update_ip4_address (self); @@ -5107,7 +5814,7 @@ nm_device_set_ip4_config (NMDevice *self, if (old_config != priv->ip4_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip4; @@ -5128,9 +5835,9 @@ nm_device_set_ip4_config (NMDevice *self, } void -nm_device_set_vpn4_config (NMDevice *device, NMIP4Config *config) +nm_device_set_vpn4_config (NMDevice *self, NMIP4Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->vpn4_config == config) return; @@ -5140,10 +5847,25 @@ nm_device_set_vpn4_config (NMDevice *device, NMIP4Config *config) priv->vpn4_config = g_object_ref (config); /* NULL to use existing configs */ - if (!ip4_config_merge_and_apply (device, NULL, TRUE, NULL)) { - nm_log_warn (LOGD_IP4, "(%s): failed to set VPN routes for device", - nm_device_get_ip_iface (device)); - } + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed to set VPN routes for device"); +} + +void +nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->wwan_ip4_config == config) + return; + + g_clear_object (&priv->wwan_ip4_config); + if (config) + priv->wwan_ip4_config = g_object_ref (config); + + /* NULL to use existing configs */ + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration"); } static gboolean @@ -5181,8 +5903,8 @@ nm_device_set_ip6_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip6_config_replace (old_config, new_config, &has_changes); if (has_changes) { - nm_log_dbg (LOGD_IP6, "(%s): update IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP6, "update IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (old_config)); } } else { has_changes = TRUE; @@ -5193,16 +5915,18 @@ nm_device_set_ip6_config (NMDevice *self, nm_ip6_config_export (new_config); } - nm_log_dbg (LOGD_IP4, "(%s): set IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (new_config)); + _LOGD (LOGD_IP4, "set IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (new_config)); } } else if (old_config) { has_changes = TRUE; priv->ip6_config = NULL; - nm_log_dbg (LOGD_IP6, "(%s): clear IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP6, "clear IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (old_config)); } + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + if (has_changes) { if (old_config != priv->ip6_config) g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG); @@ -5211,7 +5935,7 @@ nm_device_set_ip6_config (NMDevice *self, if (old_config != priv->ip6_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip6; @@ -5232,9 +5956,9 @@ nm_device_set_ip6_config (NMDevice *self, } void -nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config) +nm_device_set_vpn6_config (NMDevice *self, NMIP6Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->vpn6_config == config) return; @@ -5244,13 +5968,28 @@ nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config) priv->vpn6_config = g_object_ref (config); /* NULL to use existing configs */ - if (!ip6_config_merge_and_apply (device, TRUE, NULL)) { - nm_log_warn (LOGD_IP6, "(%s): failed to set VPN routes for device", - nm_device_get_ip_iface (device)); - } + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to set VPN routes for device"); +} + +void +nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->wwan_ip6_config == config) + return; + + g_clear_object (&priv->wwan_ip6_config); + if (config) + priv->wwan_ip6_config = g_object_ref (config); + + /* NULL to use existing configs */ + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration"); } -NMDHCP6Config * +NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -5336,16 +6075,7 @@ ip_check_gw_ping_cleanup (NMDevice *self) } if (priv->gw_ping.pid) { - guint count = 20; - int status; - - kill (priv->gw_ping.pid, SIGKILL); - do { - if (waitpid (priv->gw_ping.pid, &status, WNOHANG) != 0) - break; - g_usleep (G_USEC_PER_SEC / 20); - } while (count--); - + nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL); priv->gw_ping.pid = 0; } } @@ -5355,7 +6085,6 @@ ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; guint log_domain = priv->gw_ping.log_domain; if (!priv->gw_ping.watch) @@ -5363,17 +6092,15 @@ ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data) priv->gw_ping.watch = 0; priv->gw_ping.pid = 0; - iface = nm_device_get_iface (self); - if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0) - nm_log_dbg (log_domain, "(%s): gateway ping succeeded", iface); + _LOGD (log_domain, "ping: gateway ping succeeded"); else { - nm_log_warn (log_domain, "(%s): gateway ping failed with error code %d", - iface, WEXITSTATUS (status)); + _LOGW (log_domain, "ping: gateway ping failed with error code %d", + WEXITSTATUS (status)); } } else - nm_log_warn (log_domain, "(%s): ping stopped unexpectedly with status %d", iface, status); + _LOGW (log_domain, "ping: stopped unexpectedly with status %d", status); /* We've got connectivity, proceed to pre_up */ ip_check_gw_ping_cleanup (self); @@ -5388,8 +6115,7 @@ ip_check_ping_timeout_cb (gpointer user_data) priv->gw_ping.timeout = 0; - nm_log_warn (priv->gw_ping.log_domain, "(%s): gateway ping timed out", - nm_device_get_iface (self)); + _LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out"); ip_check_gw_ping_cleanup (self); ip_check_pre_up (self); @@ -5406,7 +6132,8 @@ spawn_ping (NMDevice *self, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *args[] = { binary, "-I", nm_device_get_ip_iface (self), "-c", "1", "-w", NULL, address, NULL }; GError *error = NULL; - char *str_timeout, *cmd; + char *str_timeout; + gs_free char *tmp_str = NULL; gboolean success; g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE); @@ -5414,13 +6141,8 @@ spawn_ping (NMDevice *self, args[6] = str_timeout = g_strdup_printf ("%u", timeout); - if (nm_logging_enabled (LOGL_DEBUG, log_domain)) { - cmd = g_strjoinv (" ", (gchar **) args); - nm_log_dbg (log_domain, "(%s): running '%s'", - nm_device_get_iface (self), - cmd); - g_free (cmd); - } + _LOGD (log_domain, "ping: running '%s'", + (tmp_str = g_strjoinv (" ", (gchar **) args))); success = g_spawn_async ("/", (gchar **) args, @@ -5435,7 +6157,7 @@ spawn_ping (NMDevice *self, priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self); priv->gw_ping.timeout = g_timeout_add_seconds (timeout + 1, ip_check_ping_timeout_cb, self); } else { - nm_log_warn (log_domain, "could not spawn %s: %s", binary, error->message); + _LOGW (log_domain, "ping: could not spawn %s: %s", binary, error->message); g_clear_error (&error); } @@ -5471,7 +6193,7 @@ nm_device_start_ip_check (NMDevice *self) timeout = nm_setting_connection_get_gateway_ping_timeout (s_con); if (timeout) { - if (priv->ip4_state == IP_DONE) { + if (priv->ip4_config && priv->ip4_state == IP_DONE) { guint gw = 0; ping_binary = "/usr/bin/ping"; @@ -5524,9 +6246,9 @@ nm_device_is_up (NMDevice *self) } static gboolean -is_up (NMDevice *device) +is_up (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); return ifindex > 0 ? nm_platform_link_is_up (ifindex) : TRUE; } @@ -5539,7 +6261,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - nm_log_dbg (LOGD_HW, "(%s): bringing up device.", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "bringing up device."); if (NM_DEVICE_GET_CLASS (self)->bring_up) { if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware)) @@ -5561,9 +6283,9 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) if (!device_is_up) { if (block) - nm_log_warn (LOGD_HW, "(%s): device not up after timeout!", nm_device_get_iface (self)); + _LOGW (LOGD_HW, "device not up after timeout!"); else - nm_log_dbg (LOGD_HW, "(%s): device not up immediately", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "device not up immediately"); return FALSE; } @@ -5589,18 +6311,18 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) } static void -check_carrier (NMDevice *device) +check_carrier (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); - if (!device_has_capability (device, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) - nm_device_set_carrier (device, nm_platform_link_is_connected (ifindex)); + if (!device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) + nm_device_set_carrier (self, nm_platform_link_is_connected (ifindex)); } static gboolean -bring_up (NMDevice *device, gboolean *no_firmware) +bring_up (NMDevice *self, gboolean *no_firmware) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); gboolean result; if (ifindex <= 0) { @@ -5614,8 +6336,8 @@ bring_up (NMDevice *device, gboolean *no_firmware) *no_firmware = nm_platform_get_error () == NM_PLATFORM_ERROR_NO_FIRMWARE; /* Store carrier immediately. */ - if (result && device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT)) - check_carrier (device); + if (result && device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) + check_carrier (self); return result; } @@ -5627,7 +6349,7 @@ nm_device_take_down (NMDevice *self, gboolean block) g_return_if_fail (NM_IS_DEVICE (self)); - nm_log_dbg (LOGD_HW, "(%s): taking down device.", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "taking down device."); if (NM_DEVICE_GET_CLASS (self)->take_down) { if (!NM_DEVICE_GET_CLASS (self)->take_down (self)) @@ -5649,22 +6371,22 @@ nm_device_take_down (NMDevice *self, gboolean block) if (device_is_up) { if (block) - nm_log_warn (LOGD_HW, "(%s): device not down after timeout!", nm_device_get_iface (self)); + _LOGW (LOGD_HW, "device not down after timeout!"); else - nm_log_dbg (LOGD_HW, "(%s): device not down immediately", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "device not down immediately"); } } static gboolean -take_down (NMDevice *device) +take_down (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); if (ifindex > 0) return nm_platform_link_set_down (ifindex); /* devices without ifindex are always up. */ - nm_log_dbg (LOGD_HW, "(%s): cannot take down device without ifindex", nm_device_get_iface (device)); + _LOGD (LOGD_HW, "cannot take down device without ifindex"); return FALSE; } @@ -5689,11 +6411,11 @@ nm_device_get_firmware_missing (NMDevice *self) } static NMIP4Config * -find_ip4_lease_config (NMDevice *device, +find_ip4_lease_config (NMDevice *self, NMConnection *connection, NMIP4Config *ext_ip4_config) { - const char *ip_iface = nm_device_get_ip_iface (device); + const char *ip_iface = nm_device_get_ip_iface (self); GSList *leases, *liter; NMIP4Config *found = NULL; @@ -5703,7 +6425,8 @@ find_ip4_lease_config (NMDevice *device, leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (), ip_iface, nm_connection_get_uuid (connection), - FALSE); + FALSE, + nm_device_get_ip4_route_metric (self)); for (liter = leases; liter && !found; liter = liter->next) { NMIP4Config *lease_config = liter->data; const NMPlatformIP4Address *address = nm_ip4_config_get_address (lease_config, 0); @@ -5722,13 +6445,13 @@ find_ip4_lease_config (NMDevice *device, } static void -capture_lease_config (NMDevice *device, +capture_lease_config (NMDevice *self, NMIP4Config *ext_ip4_config, NMIP4Config **out_ip4_config, NMIP6Config *ext_ip6_config, NMIP6Config **out_ip6_config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const GSList *connections, *citer; guint i; gboolean dhcp_used = FALSE; @@ -5767,13 +6490,13 @@ capture_lease_config (NMDevice *device, NMConnection *candidate = citer->data; const char *method; - if (!nm_device_check_connection_compatible (device, candidate)) + if (!nm_device_check_connection_compatible (self, candidate)) continue; /* IPv4 leases */ method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG); if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { - *out_ip4_config = find_ip4_lease_config (device, candidate, ext_ip4_config); + *out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config); if (*out_ip4_config) return; } @@ -5805,7 +6528,8 @@ update_ip_config (NMDevice *self, gboolean initial) /* IPv4 */ g_clear_object (&priv->ext_ip4_config); priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf); - + priv->ext_ip4_config_had_any_addresses = ( priv->ext_ip4_config + && nm_ip4_config_get_num_addresses (priv->ext_ip4_config) > 0); if (priv->ext_ip4_config) { if (initial) { g_clear_object (&priv->dev_ip4_config); @@ -5815,6 +6539,8 @@ update_ip_config (NMDevice *self, gboolean initial) nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config); if (priv->vpn4_config) nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config); + if (priv->wwan_ip4_config) + nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config); ip4_config_merge_and_apply (self, NULL, FALSE, NULL); } @@ -5822,16 +6548,20 @@ update_ip_config (NMDevice *self, gboolean initial) /* IPv6 */ g_clear_object (&priv->ext_ip6_config); priv->ext_ip6_config = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + priv->ext_ip6_config_had_any_addresses = ( priv->ext_ip6_config + && nm_ip6_config_get_num_addresses (priv->ext_ip6_config) > 0); if (priv->ext_ip6_config) { /* Check this before modifying ext_ip6_config */ linklocal6_just_completed = priv->linklocal6_timeout_id && - linklocal6_config_is_ready (priv->ext_ip6_config); + have_ip6_address (priv->ext_ip6_config, TRUE); if (priv->ac_ip6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config); if (priv->dhcp6_ip6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config); + if (priv->wwan_ip6_config) + nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config); if (priv->vpn6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->vpn6_config); @@ -5847,9 +6577,9 @@ update_ip_config (NMDevice *self, gboolean initial) } void -nm_device_capture_initial_config (NMDevice *dev) +nm_device_capture_initial_config (NMDevice *self) { - update_ip_config (dev, TRUE); + update_ip_config (self, TRUE); } static gboolean @@ -5864,22 +6594,33 @@ queued_ip_config_change (gpointer user_data) priv->queued_ip_config_id = 0; update_ip_config (self, FALSE); + + /* If no IPv6 link-local address exists but other addresses do then we + * must add the LL address to remain conformant with RFC 3513 chapter 2.1 + * ("Addressing Model"): "All interfaces are required to have at least + * one link-local unicast address". + */ + if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config)) + check_and_add_ipv6ll_addr (self); + return FALSE; } static void -device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, NMPlatformSignalChangeType change_type, NMPlatformReason reason, gpointer user_data) +device_ip_changed (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDevice *self) { - NMDevice *self = user_data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (nm_device_get_ip_ifindex (self) == ifindex) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!priv->queued_ip_config_id) priv->queued_ip_config_id = g_idle_add (queued_ip_config_change, self); - nm_log_dbg (LOGD_DEVICE, "(%s): queued IP config change", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "queued IP config change"); } } @@ -5889,8 +6630,7 @@ nm_device_queued_ip_config_change_clear (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->queued_ip_config_id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued IP config change", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "clearing queued IP config change"); g_source_remove (priv->queued_ip_config_id); priv->queued_ip_config_id = 0; } @@ -5898,19 +6638,19 @@ nm_device_queued_ip_config_change_clear (NMDevice *self) /** * nm_device_get_managed(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is managed */ gboolean -nm_device_get_managed (NMDevice *device) +nm_device_get_managed (NMDevice *self) { NMDevicePrivate *priv; gboolean managed; - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); /* Return the composite of all managed flags. However, if the device * is a default-unmanaged device, and would be managed except for the @@ -5926,30 +6666,30 @@ nm_device_get_managed (NMDevice *device) /** * nm_device_get_unmanaged_flag(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is unmanaged for @flag. */ gboolean -nm_device_get_unmanaged_flag (NMDevice *device, NMUnmanagedFlags flag) +nm_device_get_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag) { - return NM_DEVICE_GET_PRIVATE (device)->unmanaged_flags & flag; + return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags, flag); } /** * nm_device_get_default_unmanaged(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is by default unmanaged */ static gboolean -nm_device_get_default_unmanaged (NMDevice *device) +nm_device_get_default_unmanaged (NMDevice *self) { - return nm_device_get_unmanaged_flag (device, NM_UNMANAGED_DEFAULT); + return nm_device_get_unmanaged_flag (self, NM_UNMANAGED_DEFAULT); } void -nm_device_set_unmanaged (NMDevice *device, +nm_device_set_unmanaged (NMDevice *self, NMUnmanagedFlags flag, gboolean unmanaged, NMDeviceStateReason reason) @@ -5957,42 +6697,40 @@ nm_device_set_unmanaged (NMDevice *device, NMDevicePrivate *priv; gboolean was_managed, now_managed; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); g_return_if_fail (flag <= NM_UNMANAGED_LAST); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); - was_managed = nm_device_get_managed (device); + was_managed = nm_device_get_managed (self); if (unmanaged) priv->unmanaged_flags |= flag; else priv->unmanaged_flags &= ~flag; - now_managed = nm_device_get_managed (device); + now_managed = nm_device_get_managed (self); if (was_managed != now_managed) { - nm_log_dbg (LOGD_DEVICE, "(%s): now %s", - nm_device_get_iface (device), - unmanaged ? "unmanaged" : "managed"); + _LOGD (LOGD_DEVICE, "now %s", unmanaged ? "unmanaged" : "managed"); - g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED); + g_object_notify (G_OBJECT (self), NM_DEVICE_MANAGED); if (unmanaged) - nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); + nm_device_state_changed (self, NM_DEVICE_STATE_UNMANAGED, reason); else - nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, reason); + nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, reason); } } void -nm_device_set_unmanaged_quitting (NMDevice *device) +nm_device_set_unmanaged_quitting (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); /* It's OK to block here because we're quitting */ - if (nm_device_is_activating (device) || priv->state == NM_DEVICE_STATE_ACTIVATED) - _set_state_full (device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE); + if (nm_device_is_activating (self) || priv->state == NM_DEVICE_STATE_ACTIVATED) + _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE); - nm_device_set_unmanaged (device, + nm_device_set_unmanaged (self, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED); @@ -6000,26 +6738,26 @@ nm_device_set_unmanaged_quitting (NMDevice *device) /** * nm_device_set_initial_unmanaged_flag(): - * @device: the #NMDevice + * @self: the #NMDevice * @flag: an #NMUnmanagedFlag * @unmanaged: %TRUE or %FALSE to set or clear @flag * - * Like nm_device_set_unmanaged() but must be set before the device is exported - * and does not trigger state changes. Should only be used when initializing - * a device. + * Like nm_device_set_unmanaged(), but must be set before the device is + * initialized by nm_device_finish_init(), and does not trigger state changes. + * Should only be used when initializing a device. */ void -nm_device_set_initial_unmanaged_flag (NMDevice *device, +nm_device_set_initial_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag, gboolean unmanaged) { NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); g_return_if_fail (flag <= NM_UNMANAGED_LAST); - priv = NM_DEVICE_GET_PRIVATE (device); - g_return_if_fail (priv->path == NULL); + priv = NM_DEVICE_GET_PRIVATE (self); + g_return_if_fail (priv->initialized == FALSE); if (unmanaged) priv->unmanaged_flags |= flag; @@ -6028,60 +6766,54 @@ nm_device_set_initial_unmanaged_flag (NMDevice *device, } void -nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout) +nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout) { - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - NM_DEVICE_GET_PRIVATE (device)->dhcp_timeout = timeout; + NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout; } void -nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr) +nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) { NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); - - priv = NM_DEVICE_GET_PRIVATE (device); + g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN)); - if (priv->dhcp_anycast_address) { - g_byte_array_free (priv->dhcp_anycast_address, TRUE); - priv->dhcp_anycast_address = NULL; - } + priv = NM_DEVICE_GET_PRIVATE (self); - if (addr) { - priv->dhcp_anycast_address = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (priv->dhcp_anycast_address, addr, ETH_ALEN); - } + g_free (priv->dhcp_anycast_address); + priv->dhcp_anycast_address = g_strdup (addr); } /** * nm_device_connection_is_available(): - * @device: the #NMDevice + * @self: the #NMDevice * @connection: the #NMConnection to check for availability * @allow_device_override: set to %TRUE to let the device do specific checks * - * Check if @connection is available to be activated on @device. Normally this - * only checks if the connection is in @device's AvailableConnections property. + * Check if @connection is available to be activated on @self. Normally this + * only checks if the connection is in @self's AvailableConnections property. * If @allow_device_override is %TRUE then the device is asked to do specific * checks that may bypass the AvailableConnections property. * - * Returns: %TRUE if @connection can be activated on @device + * Returns: %TRUE if @connection can be activated on @self */ gboolean -nm_device_connection_is_available (NMDevice *device, +nm_device_connection_is_available (NMDevice *self, NMConnection *connection, gboolean allow_device_override) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean available = FALSE; - if (nm_device_get_default_unmanaged (device) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { + if (nm_device_get_default_unmanaged (self) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { /* default-unmanaged devices in UNMANAGED state have no available connections * so we must manually check whether the connection is available here. */ - if ( nm_device_check_connection_compatible (device, connection) - && NM_DEVICE_GET_CLASS (device)->check_connection_available (device, connection, NULL)) + if ( nm_device_check_connection_compatible (self, connection) + && NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) return TRUE; } @@ -6092,32 +6824,33 @@ nm_device_connection_is_available (NMDevice *device, * activating but the network isn't available let the device recheck * availability. */ - if ( nm_device_check_connection_compatible (device, connection) - && NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden) - available = NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden (device, connection); + if ( nm_device_check_connection_compatible (self, connection) + && NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden) + available = NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden (self, connection); } return available; } static void -_signal_available_connections_changed (NMDevice *device) +_signal_available_connections_changed (NMDevice *self) { - g_object_notify (G_OBJECT (device), NM_DEVICE_AVAILABLE_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_DEVICE_AVAILABLE_CONNECTIONS); } static void -_clear_available_connections (NMDevice *device, gboolean do_signal) +_clear_available_connections (NMDevice *self, gboolean do_signal) { - g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (device)->available_connections); + g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (self)->available_connections); if (do_signal == TRUE) - _signal_available_connections_changed (device); + _signal_available_connections_changed (self); } static gboolean _try_add_available_connection (NMDevice *self, NMConnection *connection) { - if (nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED) + if ( nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED + && !nm_device_get_default_unmanaged (self)) return FALSE; if (nm_device_check_connection_compatible (self, connection)) { @@ -6132,98 +6865,49 @@ _try_add_available_connection (NMDevice *self, NMConnection *connection) } static gboolean -_del_available_connection (NMDevice *device, NMConnection *connection) +_del_available_connection (NMDevice *self, NMConnection *connection) { - return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (device)->available_connections, connection); + return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (self)->available_connections, connection); } static gboolean -connection_requires_carrier (NMConnection *connection) -{ - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - const char *method; - gboolean ip4_carrier_wanted = FALSE, ip6_carrier_wanted = FALSE; - gboolean ip4_used = FALSE, ip6_used = FALSE; - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0 - && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0) { - ip4_carrier_wanted = TRUE; - - /* If IPv4 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv6 method. - */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4)) - return TRUE; - } - ip4_used = (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0); - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0 - && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0) { - ip6_carrier_wanted = TRUE; - - /* If IPv6 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv4 method. - */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6)) - return TRUE; - } - ip6_used = (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0); - - /* If an IP version wants a carrier and and the other IP version isn't - * used, the connection requires carrier since it will just fail without one. - */ - if (ip4_carrier_wanted && !ip6_used) - return TRUE; - if (ip6_carrier_wanted && !ip4_used) - return TRUE; - - /* If both want a carrier, the whole connection wants a carrier */ - return ip4_carrier_wanted && ip6_carrier_wanted; -} - -static gboolean -check_connection_available (NMDevice *device, +check_connection_available (NMDevice *self, NMConnection *connection, const char *specific_object) { /* Connections which require a network connection are not available when * the device has no carrier, even with ignore-carrer=TRUE. */ - if (NM_DEVICE_GET_PRIVATE (device)->carrier == FALSE) + if (NM_DEVICE_GET_PRIVATE (self)->carrier == FALSE) return connection_requires_carrier (connection) ? FALSE : TRUE; return TRUE; } void -nm_device_recheck_available_connections (NMDevice *device) +nm_device_recheck_available_connections (NMDevice *self) { NMDevicePrivate *priv; const GSList *connections, *iter; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE(device); + priv = NM_DEVICE_GET_PRIVATE(self); if (priv->con_provider) { - _clear_available_connections (device, FALSE); + _clear_available_connections (self, FALSE); connections = nm_connection_provider_get_connections (priv->con_provider); for (iter = connections; iter; iter = g_slist_next (iter)) - _try_add_available_connection (device, NM_CONNECTION (iter->data)); + _try_add_available_connection (self, NM_CONNECTION (iter->data)); - _signal_available_connections_changed (device); + _signal_available_connections_changed (self); } } /** * nm_device_get_available_connections: - * @device: the #NMDevice + * @self: the #NMDevice * @specific_object: a specific object path if any * * Returns a list of connections available to activate on the device, taking @@ -6233,9 +6917,9 @@ nm_device_recheck_available_connections (NMDevice *device) * Returns: caller-owned #GPtrArray of #NMConnections */ GPtrArray * -nm_device_get_available_connections (NMDevice *device, const char *specific_object) +nm_device_get_available_connections (NMDevice *self, const char *specific_object) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GHashTableIter iter; guint num_available; NMConnection *connection = NULL; @@ -6250,7 +6934,7 @@ nm_device_get_available_connections (NMDevice *device, const char *specific_obje * compatible with it. */ if ( !specific_object - || NM_DEVICE_GET_CLASS (device)->check_connection_available (device, connection, specific_object)) + || NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, specific_object)) g_ptr_array_add (array, connection); } } @@ -6286,14 +6970,14 @@ cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpoin } gboolean -nm_device_supports_vlans (NMDevice *device) +nm_device_supports_vlans (NMDevice *self) { - return nm_platform_link_supports_vlans (nm_device_get_ifindex (device)); + return nm_platform_link_supports_vlans (nm_device_get_ifindex (self)); } /** * nm_device_add_pending_action(): - * @device: the #NMDevice to add the pending action to + * @self: the #NMDevice to add the pending action to * @action: a static string that identifies the action * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending. * Otherwise, ignore duplicate scheduling of the same action silently. @@ -6305,9 +6989,9 @@ nm_device_supports_vlans (NMDevice *device) * a second time. */ gboolean -nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending) +nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *iter; guint count = 0; @@ -6317,16 +7001,12 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass for (iter = priv->pending_actions; iter; iter = iter->next) { if (!strcmp (action, iter->data)) { if (assert_not_yet_pending) { - nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending", - nm_device_get_iface (device), - count + g_slist_length (iter), - action); + _LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending", + count + g_slist_length (iter), action); g_return_val_if_reached (FALSE); } else { - nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending (expected)", - nm_device_get_iface (device), - count + g_slist_length (iter), - action); + _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)", + count + g_slist_length (iter), action); } return FALSE; } @@ -6336,20 +7016,17 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action)); count++; - nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s'", - nm_device_get_iface (device), - count, - action); + _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); if (count == 1) - g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION); return TRUE; } /** * nm_device_remove_pending_action(): - * @device: the #NMDevice to remove the pending action from + * @self: the #NMDevice to remove the pending action from * @action: a static string that identifies the action * @assert_is_pending: if %TRUE, assert that the @action is pending. * If %FALSE, don't do anything if the current action is not pending and @@ -6360,9 +7037,9 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass * Returns: whether the @action was pending and is now removed. */ gboolean -nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending) +nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *iter; guint count = 0; @@ -6370,38 +7047,31 @@ nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean for (iter = priv->pending_actions; iter; iter = iter->next) { if (!strcmp (action, iter->data)) { - nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s'", - nm_device_get_iface (device), - count + g_slist_length (iter->next), /* length excluding 'iter' */ - action); + _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'", + count + g_slist_length (iter->next), /* length excluding 'iter' */ + action); g_free (iter->data); priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); if (priv->pending_actions == NULL) - g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION); return TRUE; } count++; } if (assert_is_pending) { - nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending", - nm_device_get_iface (device), - count, - action); + _LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action); g_return_val_if_reached (FALSE); - } else { - nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending (expected)", - nm_device_get_iface (device), - count, - action); - } + } else + _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action); + return FALSE; } gboolean -nm_device_has_pending_action (NMDevice *device) +nm_device_has_pending_action (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return !!priv->pending_actions; } @@ -6409,25 +7079,41 @@ nm_device_has_pending_action (NMDevice *device) /***********************************************************/ static void +_cleanup_ip_pre (NMDevice *self, gboolean deconfigure) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + priv->ip4_state = priv->ip6_state = IP_NONE; + nm_device_queued_ip_config_change_clear (self); + + dhcp4_cleanup (self, deconfigure, FALSE); + arp_cleanup (self); + dhcp6_cleanup (self, deconfigure, FALSE); + linklocal6_cleanup (self); + addrconf6_cleanup (self); + dnsmasq_cleanup (self); + aipd_cleanup (self); +} + +static void _cleanup_generic_pre (NMDevice *self, gboolean deconfigure) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; /* Clean up when device was deactivated during call to firewall */ - if (priv->fw_manager) { - NMConnection *connection; - - if (priv->fw_call) { - nm_firewall_manager_cancel_call (priv->fw_manager, priv->fw_call); - priv->fw_call = NULL; - } + if (priv->fw_call) { + nm_firewall_manager_cancel_call (nm_firewall_manager_get (), priv->fw_call); + priv->fw_call = NULL; + } - connection = nm_device_get_connection (self); - if (deconfigure && connection) { - nm_firewall_manager_remove_from_zone (priv->fw_manager, - nm_device_get_ip_iface (self), - NULL); - } + connection = nm_device_get_connection (self); + if ( deconfigure + && connection + && !nm_device_uses_assumed_connection (self)) { + nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (), + nm_device_get_ip_iface (self), + NULL); } ip_check_gw_ping_cleanup (self); @@ -6438,17 +7124,8 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure) /* Clear any queued transitions */ nm_device_queued_state_clear (self); - nm_device_queued_ip_config_change_clear (self); - priv->ip4_state = priv->ip6_state = IP_NONE; - - dhcp4_cleanup (self, deconfigure, FALSE); - arp_cleanup (self); - dhcp6_cleanup (self, deconfigure, FALSE); - linklocal6_cleanup (self); - addrconf6_cleanup (self); - dnsmasq_cleanup (self); - aipd_cleanup (self); + _cleanup_ip_pre (self, deconfigure); } static void @@ -6457,20 +7134,33 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE; + priv->default_route.v4_has = FALSE; + priv->default_route.v4_is_assumed = TRUE; + priv->default_route.v6_has = FALSE; + priv->default_route.v6_is_assumed = TRUE; + + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ - nm_device_set_ip4_config (self, NULL, TRUE, &ignored); + nm_device_set_ip4_config (self, NULL, 0, TRUE, &ignored); nm_device_set_ip6_config (self, NULL, TRUE, &ignored); g_clear_object (&priv->dev_ip4_config); g_clear_object (&priv->ext_ip4_config); + g_clear_object (&priv->wwan_ip4_config); g_clear_object (&priv->vpn4_config); g_clear_object (&priv->ip4_config); g_clear_object (&priv->ac_ip6_config); g_clear_object (&priv->ext_ip6_config); g_clear_object (&priv->vpn6_config); + g_clear_object (&priv->wwan_ip6_config); g_clear_object (&priv->ip6_config); + priv->ext_ip4_config_had_any_addresses = FALSE; + priv->ext_ip6_config_had_any_addresses = FALSE; + clear_act_request (self); /* Clear legacy IPv4 address property */ @@ -6507,13 +7197,10 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) g_return_if_fail (NM_IS_DEVICE (self)); - if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) { - nm_log_info (LOGD_DEVICE, "(%s): preparing device", - nm_device_get_iface (self)); - } else { - nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason '%s') [%d]", - nm_device_get_iface (self), reason_to_string (reason), reason); - } + if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) + _LOGI (LOGD_DEVICE, "preparing device"); + else + _LOGI (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string (reason), reason); /* Save whether or not we tried IPv6 for later */ priv = NM_DEVICE_GET_PRIVATE (self); @@ -6521,7 +7208,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) _cleanup_generic_pre (self, TRUE); /* Turn off kernel IPv6 */ - nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); + set_disable_ipv6 (self, "1"); nm_device_ipv6_sysctl_set (self, "accept_ra", "0"); nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); @@ -6547,6 +7234,170 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) _cleanup_generic_post (self, TRUE); } +static char * +bin2hexstr (const char *bytes, gsize len) +{ + GString *str; + int i; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + + str = g_string_sized_new (len * 2 + 1); + for (i = 0; i < len; i++) { + if (str->len) + g_string_append_c (str, ':'); + g_string_append_printf (str, "%02x", (guint8) bytes[i]); + } + return g_string_free (str, FALSE); +} + +static char * +find_dhcp4_address (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + guint i, n; + + if (!priv->ip4_config) + return NULL; + + n = nm_ip4_config_get_num_addresses (priv->ip4_config); + for (i = 0; i < n; i++) { + const NMPlatformIP4Address *a = nm_ip4_config_get_address (priv->ip4_config, i); + + if (a->source == NM_IP_CONFIG_SOURCE_DHCP) + return g_strdup (nm_utils_inet4_ntop (a->address, NULL)); + } + return NULL; +} + +void +nm_device_spawn_iface_helper (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean configured = FALSE; + NMConnection *connection; + GError *error = NULL; + const char *method; + GPtrArray *argv; + gs_free char *dhcp4_address = NULL; + + if (priv->state != NM_DEVICE_STATE_ACTIVATED) + return; + if (!nm_device_can_assume_connections (self)) + return; + + connection = nm_device_get_connection (self); + g_assert (connection); + + argv = g_ptr_array_sized_new (10); + g_ptr_array_set_free_func (argv, g_free); + + g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/nm-iface-helper")); + g_ptr_array_add (argv, g_strdup ("--ifname")); + g_ptr_array_add (argv, g_strdup (nm_device_get_ip_iface (self))); + g_ptr_array_add (argv, g_strdup ("--uuid")); + g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection))); + + dhcp4_address = find_dhcp4_address (self); + + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + if ( priv->ip4_config + && priv->ip4_state == IP_DONE + && g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0 + && priv->dhcp4_client + && dhcp4_address) { + NMSettingIPConfig *s_ip4; + GBytes *client_id; + char *hex_client_id; + const char *hostname; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + + g_ptr_array_add (argv, g_strdup ("--priority4")); + g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip4_route_metric (self))); + + g_ptr_array_add (argv, g_strdup ("--dhcp4")); + g_ptr_array_add (argv, g_strdup (dhcp4_address)); + if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE) + g_ptr_array_add (argv, g_strdup ("--dhcp4-required")); + + client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client); + if (client_id) { + g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid")); + hex_client_id = bin2hexstr (g_bytes_get_data (client_id, NULL), + g_bytes_get_size (client_id)); + g_ptr_array_add (argv, hex_client_id); + } + + hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client); + if (client_id) { + g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); + g_ptr_array_add (argv, g_strdup (hostname)); + } + + configured = TRUE; + } + + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if ( priv->ip6_config + && priv->ip6_state == IP_DONE + && g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + && priv->rdisc + && priv->ac_ip6_config) { + NMSettingIPConfig *s_ip6; + char *hex_iid; + NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + + g_ptr_array_add (argv, g_strdup ("--priority6")); + g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip6_route_metric (self))); + + g_ptr_array_add (argv, g_strdup ("--slaac")); + + if (nm_setting_ip_config_get_may_fail (s_ip6) == FALSE) + g_ptr_array_add (argv, g_strdup ("--slaac-required")); + + g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr")); + g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr)); + + if (nm_device_get_ip_iface_identifier (self, &iid)) { + g_ptr_array_add (argv, g_strdup ("--iid")); + hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId)); + g_ptr_array_add (argv, hex_iid); + } + + configured = TRUE; + } + + if (configured) { + GPid pid; + + g_ptr_array_add (argv, NULL); + + if (nm_logging_enabled (LOGL_DEBUG, LOGD_DEVICE)) { + char *tmp; + + tmp = g_strjoinv (" ", (char **) argv->pdata); + _LOGD (LOGD_DEVICE, "running '%s'", tmp); + g_free (tmp); + } + + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) { + _LOGI (LOGD_DEVICE, "spawned helper PID %u", (guint) pid); + } else { + _LOGW (LOGD_DEVICE, "failed to spawn helper: %s", error->message); + g_error_free (error); + } + } + + g_ptr_array_unref (argv); +} + /***********************************************************/ static gboolean @@ -6558,22 +7409,33 @@ ip_config_valid (NMDeviceState state) } static void -notify_ip_properties (NMDevice *device) +notify_ip_properties (NMDevice *self) +{ + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); +} + +static void +ip6_managed_setup (NMDevice *self) { - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP4_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP4_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP6_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG); + set_nm_ipv6ll (self, TRUE); + set_disable_ipv6 (self, "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); } static void -_set_state_full (NMDevice *device, +_set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState old_state; NMActRequest *req; gboolean no_firmware = FALSE; @@ -6583,7 +7445,7 @@ _set_state_full (NMDevice *device, g_warn_if_fail (priv->in_state_changed == FALSE); priv->in_state_changed = TRUE; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); /* Do nothing if state isn't changing, but as a special case allow * re-setting UNAVAILABLE if the device is missing firmware so that we @@ -6599,78 +7461,96 @@ _set_state_full (NMDevice *device, priv->state = state; priv->state_reason = reason; - nm_log_info (LOGD_DEVICE, "(%s): device state change: %s -> %s (reason '%s') [%d %d %d]", - nm_device_get_iface (device), - state_to_string (old_state), - state_to_string (state), - reason_to_string (reason), - old_state, - state, - reason); + _LOGI (LOGD_DEVICE, "device state change: %s -> %s (reason '%s') [%d %d %d]", + state_to_string (old_state), + state_to_string (state), + reason_to_string (reason), + old_state, + state, + reason); /* Clear any queued transitions */ - nm_device_queued_state_clear (device); + nm_device_queued_state_clear (self); - dispatcher_cleanup (device); + dispatcher_cleanup (self); /* Cache the activation request for the dispatcher */ req = priv->act_request ? g_object_ref (priv->act_request) : NULL; if (state <= NM_DEVICE_STATE_UNAVAILABLE) { - _clear_available_connections (device, TRUE); + _clear_available_connections (self, TRUE); g_clear_object (&priv->queued_act_request); } /* Update the available connections list when a device first becomes available */ - if ( state >= NM_DEVICE_STATE_DISCONNECTED - && old_state < NM_DEVICE_STATE_DISCONNECTED) - nm_device_recheck_available_connections (device); + if ( (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) + || nm_device_get_default_unmanaged (self)) + nm_device_recheck_available_connections (self); /* Handle the new state here; but anything that could trigger * another state change should be done below. */ switch (state) { case NM_DEVICE_STATE_UNMANAGED: - nm_device_set_firmware_missing (device, FALSE); + nm_device_set_firmware_missing (self, FALSE); if (old_state > NM_DEVICE_STATE_UNMANAGED) { /* Clean up if the device is now unmanaged but was activated */ - if (nm_device_get_act_request (device)) - nm_device_cleanup (device, reason); - nm_device_take_down (device, TRUE); - restore_ip6_properties (device); + if (nm_device_get_act_request (self)) + nm_device_cleanup (self, reason); + nm_device_take_down (self, TRUE); + set_nm_ipv6ll (self, FALSE); + restore_ip6_properties (self); } break; case NM_DEVICE_STATE_UNAVAILABLE: if (old_state == NM_DEVICE_STATE_UNMANAGED) { - save_ip6_properties (device); - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { - nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); - nm_device_ipv6_sysctl_set (device, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (device, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (device, "accept_ra_rtr_pref", "0"); - nm_device_ipv6_sysctl_set (device, "use_tempaddr", "0"); - } + save_ip6_properties (self); + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) + ip6_managed_setup (self); } - if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { - if (!nm_device_bring_up (device, TRUE, &no_firmware) && no_firmware) - nm_log_warn (LOGD_HW, "(%s): firmware may be missing.", nm_device_get_iface (device)); - nm_device_set_firmware_missing (device, no_firmware ? TRUE : FALSE); + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { + if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) + _LOGW (LOGD_HW, "firmware may be missing."); + nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); + } + + /* Ensure the device gets deactivated in response to stuff like + * carrier changes or rfkill. But don't deactivate devices that are + * about to assume a connection since that defeats the purpose of + * assuming the device's existing connection. + * + * Note that we "deactivate" the device even when coming from + * UNMANAGED, to ensure that it's in a clean state. + */ + nm_device_cleanup (self, reason); } - /* Ensure the device gets deactivated in response to stuff like - * carrier changes or rfkill. But don't deactivate devices that are - * about to assume a connection since that defeats the purpose of - * assuming the device's existing connection. - * - * Note that we "deactivate" the device even when coming from - * UNMANAGED, to ensure that it's in a clean state. - */ - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) - nm_device_cleanup (device, reason); break; case NM_DEVICE_STATE_DISCONNECTED: - if (old_state > NM_DEVICE_STATE_UNAVAILABLE) - nm_device_cleanup (device, reason); + if (old_state > NM_DEVICE_STATE_DISCONNECTED) { + /* Ensure devices that previously assumed a connection now have + * userspace IPv6LL enabled. + */ + set_nm_ipv6ll (self, TRUE); + + nm_device_cleanup (self, reason); + } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + /* Ensure IPv6 is set up as it may not have been done when + * entering the UNAVAILABLE state depending on the reason. + */ + ip6_managed_setup (self); + } + } + break; + case NM_DEVICE_STATE_NEED_AUTH: + if (old_state > NM_DEVICE_STATE_NEED_AUTH) { + /* Clean up any half-done IP operations if the device's layer2 + * finds out it needs authentication during IP config. + */ + _cleanup_ip_pre (self, TRUE); + } break; default: break; @@ -6679,11 +7559,11 @@ _set_state_full (NMDevice *device, /* Reset autoconnect flag when the device is activating or connected. */ if ( state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) - priv->autoconnect = TRUE; + nm_device_set_autoconnect (self, TRUE); - g_object_notify (G_OBJECT (device), NM_DEVICE_STATE); - g_object_notify (G_OBJECT (device), NM_DEVICE_STATE_REASON); - g_signal_emit_by_name (device, "state-changed", state, old_state, reason); + g_object_notify (G_OBJECT (self), NM_DEVICE_STATE); + g_object_notify (G_OBJECT (self), NM_DEVICE_STATE_REASON); + g_signal_emit_by_name (self, "state-changed", state, old_state, reason); /* Post-process the event after internal notification */ @@ -6695,35 +7575,33 @@ _set_state_full (NMDevice *device, * we can't change states again from the state handler for a variety of * reasons. */ - if (nm_device_is_available (device)) { - nm_log_dbg (LOGD_DEVICE, "(%s): device is available, will transition to DISCONNECTED", - nm_device_get_iface (device)); - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + if (nm_device_is_available (self)) { + _LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED"); + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); } else { - if (old_state == NM_DEVICE_STATE_UNMANAGED) { - nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED", - nm_device_get_iface (device)); - } else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE - && nm_device_get_default_unmanaged (device)) - nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); + if (old_state == NM_DEVICE_STATE_UNMANAGED) + _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED"); + else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE + && nm_device_get_default_unmanaged (self)) + nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); } break; case NM_DEVICE_STATE_DEACTIVATING: if (quitting) { nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN, nm_act_request_get_connection (req), - device); + self); } else { priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; priv->dispatcher.post_state_reason = reason; if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN, nm_act_request_get_connection (req), - device, + self, dispatcher_complete_proceed_state, - device, + self, &priv->dispatcher.call_id)) { /* Just proceed on errors */ - dispatcher_complete_proceed_state (0, device); + dispatcher_complete_proceed_state (0, self); } } break; @@ -6733,26 +7611,32 @@ _set_state_full (NMDevice *device, queued_req = priv->queued_act_request; priv->queued_act_request = NULL; - _device_activate (device, queued_req); + _device_activate (self, queued_req); g_object_unref (queued_req); } else if ( old_state > NM_DEVICE_STATE_DISCONNECTED - && nm_device_get_default_unmanaged (device)) - nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); + && nm_device_get_default_unmanaged (self)) + nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); break; case NM_DEVICE_STATE_ACTIVATED: - nm_log_info (LOGD_DEVICE, "Activation (%s) successful, device activated.", - nm_device_get_iface (device)); - nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), device, NULL, NULL, NULL); + _LOGI (LOGD_DEVICE, "Activation: successful, device activated."); + nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL); break; case NM_DEVICE_STATE_FAILED: - connection = nm_device_get_connection (device); - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s) failed for connection '%s'", - nm_device_get_iface (device), - connection ? nm_connection_get_id (connection) : "<unknown>"); + if (nm_device_uses_assumed_connection (self)) { + /* Avoid tearing down assumed connection, assume it's connected */ + nm_device_queue_state (self, + NM_DEVICE_STATE_ACTIVATED, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + break; + } + + connection = nm_device_get_connection (self); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: failed for connection '%s'", + connection ? nm_connection_get_id (connection) : "<unknown>"); /* Notify any slaves of the unexpected failure */ - nm_device_master_release_slaves (device); + nm_device_master_release_slaves (self); /* If the connection doesn't yet have a timestamp, set it to zero so that * we can distinguish between connections we've tried to activate and have @@ -6769,41 +7653,40 @@ _set_state_full (NMDevice *device, * immediately because we can't change states again from the state * handler for a variety of reasons. */ - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); break; case NM_DEVICE_STATE_IP_CHECK: - nm_device_start_ip_check (device); + nm_device_start_ip_check (self); /* IP-related properties are only valid when the device has IP configuration; * now that it does, ensure their change notifications are emitted. */ - notify_ip_properties (device); + notify_ip_properties (self); break; case NM_DEVICE_STATE_SECONDARIES: - ip_check_gw_ping_cleanup (device); - nm_log_dbg (LOGD_DEVICE, "(%s): device entered SECONDARIES state", - nm_device_get_iface (device)); + ip_check_gw_ping_cleanup (self); + _LOGD (LOGD_DEVICE, "device entered SECONDARIES state"); break; default: break; } if (state > NM_DEVICE_STATE_DISCONNECTED) - delete_on_deactivate_unschedule (device); + delete_on_deactivate_unschedule (self); if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING) && (state != NM_DEVICE_STATE_DEACTIVATING)) { if (quitting) - nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device); + nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self); else - nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self, NULL, NULL, NULL); } /* IP-related properties are only valid when the device has IP configuration. * If it no longer does, ensure their change notifications are emitted. */ if (ip_config_valid (old_state) && !ip_config_valid (state)) - notify_ip_properties (device); + notify_ip_properties (self); /* Dispose of the cached activation request */ if (req) @@ -6813,11 +7696,11 @@ _set_state_full (NMDevice *device, } void -nm_device_state_changed (NMDevice *device, +nm_device_state_changed (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason) { - _set_state_full (device, state, reason, FALSE); + _set_state_full (self, state, reason, FALSE); } static gboolean @@ -6829,10 +7712,9 @@ queued_set_state (gpointer user_data) NMDeviceStateReason new_reason; if (priv->queued_state.id) { - nm_log_dbg (LOGD_DEVICE, "(%s): running queued state change to %s (id %d)", - nm_device_get_iface (self), - state_to_string (priv->queued_state.state), - priv->queued_state.id); + _LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)", + state_to_string (priv->queued_state.state), + priv->queued_state.id); /* Clear queued state struct before triggering state change, since * the state change may queue another state. @@ -6871,10 +7753,9 @@ nm_device_queue_state (NMDevice *self, /* We should only ever have one delayed state transition at a time */ if (priv->queued_state.id) { - nm_log_warn (LOGD_DEVICE, "(%s): overwriting previously queued state change to %s (%s)", - nm_device_get_iface (self), - state_to_string (priv->queued_state.state), - reason_to_string (priv->queued_state.reason)); + _LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)", + state_to_string (priv->queued_state.state), + reason_to_string (priv->queued_state.reason)); nm_device_queued_state_clear (self); } @@ -6882,9 +7763,9 @@ nm_device_queue_state (NMDevice *self, priv->queued_state.reason = reason; priv->queued_state.id = g_idle_add (queued_set_state, self); - nm_log_dbg (LOGD_DEVICE, "(%s): queued state change to %s due to %s (id %d)", - nm_device_get_iface (self), state_to_string (state), reason_to_string (reason), - priv->queued_state.id); + _LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)", + state_to_string (state), reason_to_string (reason), + priv->queued_state.id); } NMDeviceState @@ -6905,8 +7786,8 @@ nm_device_queued_state_clear (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->queued_state.id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued state transition (id %d)", - nm_device_get_iface (self), priv->queued_state.id); + _LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)", + priv->queued_state.id); g_source_remove (priv->queued_state.id); nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); } @@ -6914,152 +7795,112 @@ nm_device_queued_state_clear (NMDevice *self) } NMDeviceState -nm_device_get_state (NMDevice *device) +nm_device_get_state (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); + g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (device)->state; + return NM_DEVICE_GET_PRIVATE (self)->state; } /***********************************************************/ /* NMConfigDevice interface related stuff */ -static guint -nm_device_get_hw_address_length (NMDevice *dev, gboolean *out_permanent) -{ - return NM_DEVICE_GET_CLASS (dev)->get_hw_address_length (dev, out_permanent); -} - -const guint8 * -nm_device_get_hw_address (NMDevice *dev, guint *out_len) +const char * +nm_device_get_hw_address (NMDevice *self) { NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (dev), NULL); - priv = NM_DEVICE_GET_PRIVATE (dev); - - if (out_len) - *out_len = priv->hw_addr_len; + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->hw_addr_len == 0) - return NULL; - else - return priv->hw_addr; + return priv->hw_addr_len ? priv->hw_addr : NULL; } -gboolean -nm_device_update_hw_address (NMDevice *dev) +static void +nm_device_update_hw_address (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - gboolean changed = FALSE, permanent = FALSE; - - priv->hw_addr_len = nm_device_get_hw_address_length (dev, &permanent); - - /* If the address can't be changed, don't bother trying */ - if (permanent) - return FALSE; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ifindex = nm_device_get_ifindex (self); + const guint8 *hwaddr; + gsize hwaddrlen = 0; - if (priv->hw_addr_len) { - int ifindex = nm_device_get_ip_ifindex (dev); - gsize addrlen; - const guint8 *binaddr; + if (ifindex <= 0) + return; - g_return_val_if_fail (ifindex > 0, FALSE); + hwaddr = nm_platform_link_get_address (ifindex, &hwaddrlen); - binaddr = nm_platform_link_get_address (ifindex, &addrlen); + if (hwaddrlen) { + if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) { + g_free (priv->hw_addr); + priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - if (addrlen != priv->hw_addr_len) { - nm_log_err (LOGD_HW | LOGD_DEVICE, - "(%s): hardware address is wrong length (got %zd, expected %d)", - nm_device_get_iface (dev), addrlen, priv->hw_addr_len); - } else { - changed = !!memcmp (priv->hw_addr, binaddr, addrlen); - if (changed) { - char *addrstr = nm_utils_hwaddr_ntoa_len (binaddr, priv->hw_addr_len); - - memcpy (priv->hw_addr, binaddr, addrlen); - nm_log_dbg (LOGD_HW | LOGD_DEVICE, - "(%s): hardware address is %s", - nm_device_get_iface (dev), addrstr); - g_free (addrstr); - g_object_notify (G_OBJECT (dev), NM_DEVICE_HW_ADDRESS); - } + _LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); } } else { - int i; - - /* hw_addr_len is now 0; see if hw_addr was already empty */ - for (i = 0; i < sizeof (priv->hw_addr) && !changed; i++) { - if (priv->hw_addr[i]) - changed = TRUE; - } - if (changed) { - memset (priv->hw_addr, 0, sizeof (priv->hw_addr)); - nm_log_dbg (LOGD_HW | LOGD_DEVICE, - "(%s): previous hardware address is no longer valid", - nm_device_get_iface (dev)); - g_object_notify (G_OBJECT (dev), NM_DEVICE_HW_ADDRESS); + /* Invalid or no hardware address */ + if (priv->hw_addr_len != 0) { + g_clear_pointer (&priv->hw_addr, g_free); + _LOGD (LOGD_HW | LOGD_DEVICE, + "previous hardware address is no longer valid"); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); } } - - return changed; + priv->hw_addr_len = hwaddrlen; } gboolean -nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, +nm_device_set_hw_addr (NMDevice *self, const char *addr, const char *detail, guint64 hw_log_domain) { - const char *iface; - char *mac_str = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean success = FALSE; - guint len; - const guint8 *cur_addr = nm_device_get_hw_address (device, &len); + const char *cur_addr = nm_device_get_hw_address (self); + guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; g_return_val_if_fail (addr != NULL, FALSE); - iface = nm_device_get_iface (device); - /* Do nothing if current MAC is same */ - if (cur_addr && !memcmp (cur_addr, addr, len)) { - nm_log_dbg (LOGD_DEVICE | hw_log_domain, "(%s): no MAC address change needed", iface); + if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { + _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed"); return TRUE; } - - mac_str = nm_utils_hwaddr_ntoa_len (addr, len); + if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) { + _LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr); + return FALSE; + } /* Can't change MAC address while device is up */ - nm_device_take_down (device, FALSE); + nm_device_take_down (self, FALSE); - success = nm_platform_link_set_address (nm_device_get_ip_ifindex (device), addr, len); + success = nm_platform_link_set_address (nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len); if (success) { /* MAC address succesfully changed; update the current MAC to match */ - nm_device_update_hw_address (device); - cur_addr = nm_device_get_hw_address (device, NULL); - if (memcmp (cur_addr, addr, len) == 0) { - nm_log_info (LOGD_DEVICE | hw_log_domain, "(%s): %s MAC address to %s", - iface, detail, mac_str); + nm_device_update_hw_address (self); + cur_addr = nm_device_get_hw_address (self); + if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { + _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s", + detail, addr); } else { - nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): new MAC address %s " - "not successfully set", - iface, mac_str); + _LOGW (LOGD_DEVICE | hw_log_domain, + "new MAC address %s not successfully set", addr); success = FALSE; } } else { - nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): failed to %s MAC address to %s", - iface, detail, mac_str); + _LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s", + detail, addr); } - nm_device_bring_up (device, TRUE, NULL); - g_free (mac_str); + nm_device_bring_up (self, TRUE, NULL); return success; } /** * nm_device_spec_match_list: - * @device: an #NMDevice + * @self: an #NMDevice * @specs: (element-type utf8): a list of device specs * - * Checks if @device matches any of the specifications in @specs. The + * Checks if @self matches any of the specifications in @specs. The * currently-supported spec types are: * * "mac:00:11:22:33:44:55" - matches a device with the given @@ -7073,52 +7914,37 @@ nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, * * "*" - matches any device * - * Returns: #TRUE if @device matches one of the specs in @specs + * Returns: #TRUE if @self matches one of the specs in @specs */ gboolean -nm_device_spec_match_list (NMDevice *device, const GSList *specs) +nm_device_spec_match_list (NMDevice *self, const GSList *specs) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); if (!specs) return FALSE; - return NM_DEVICE_GET_CLASS (device)->spec_match_list (device, specs); + return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs); } static gboolean -spec_match_list (NMDevice *device, const GSList *specs) +spec_match_list (NMDevice *self, const GSList *specs) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - char *hwaddr_str; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean matched = FALSE; if (nm_match_spec_string (specs, "*")) return TRUE; - if (priv->hw_addr_len) { - hwaddr_str = nm_utils_hwaddr_ntoa_len (priv->hw_addr, priv->hw_addr_len); - matched = nm_match_spec_hwaddr (specs, hwaddr_str); - g_free (hwaddr_str); - } + if (priv->hw_addr_len) + matched = nm_match_spec_hwaddr (specs, priv->hw_addr); if (!matched) - matched = nm_match_spec_interface_name (specs, nm_device_get_iface (device)); + matched = nm_match_spec_interface_name (specs, nm_device_get_iface (self)); return matched; } -static guint -get_hw_address_length (NMDevice *dev, gboolean *out_permanent) -{ - size_t len; - - if (nm_platform_link_get_address (nm_device_get_ip_ifindex (dev), &len)) - return len; - else - return 0; -} - /***********************************************************/ #define DEFAULT_AUTOCONNECT TRUE @@ -7138,13 +7964,9 @@ nm_device_init (NMDevice *self) priv->unmanaged_flags = NM_UNMANAGED_INTERNAL; priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); -} -static void -nm_device_config_device_interface_init (NMConfigDeviceInterface *iface) -{ - iface->spec_match_list = (gboolean (*) (NMConfigDevice *, const GSList *)) nm_device_spec_match_list; - iface->get_hw_address = (const guint8 * (*) (NMConfigDevice *, guint *)) nm_device_get_hw_address; + priv->default_route.v4_is_assumed = TRUE; + priv->default_route.v6_is_assumed = TRUE; } /* @@ -7152,7 +7974,7 @@ nm_device_config_device_interface_init (NMConfigDeviceInterface *iface) * Returns driver and firmware versions to 'driver_version and' 'firmware_version' */ static gboolean -device_get_driver_info (const char *iface, char **driver_version, char **firmware_version) +device_get_driver_info (NMDevice *self, const char *iface, char **driver_version, char **firmware_version) { struct ethtool_drvinfo drvinfo; struct ifreq req; @@ -7160,7 +7982,7 @@ device_get_driver_info (const char *iface, char **driver_version, char **firmwar fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); + _LOGW (LOGD_HW, "couldn't open control socket."); return FALSE; } @@ -7173,8 +7995,8 @@ device_get_driver_info (const char *iface, char **driver_version, char **firmwar errno = 0; if (ioctl (fd, SIOCETHTOOL, &req) < 0) { - nm_log_dbg (LOGD_HW, "SIOCETHTOOL ioctl() failed: cmd=ETHTOOL_GDRVINFO, iface=%s, errno=%d", - iface, errno); + _LOGD (LOGD_HW, "SIOCETHTOOL ioctl() failed: cmd=ETHTOOL_GDRVINFO, iface=%s, errno=%d", + iface, errno); close (fd); return FALSE; } @@ -7193,7 +8015,7 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; - NMDevice *dev; + NMDevice *self; NMDevicePrivate *priv; NMPlatform *platform; static guint32 id = 0; @@ -7204,11 +8026,13 @@ constructor (GType type, if (!object) return NULL; - dev = NM_DEVICE (object); - priv = NM_DEVICE_GET_PRIVATE (dev); + 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) { - nm_log_err (LOGD_DEVICE, "No device interface provided, ignoring"); + _LOGE (LOGD_DEVICE, "No device interface provided, ignoring"); goto error; } @@ -7217,52 +8041,60 @@ constructor (GType type, priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++); } - if (NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities) - priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); + if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) + priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); - priv->fw_manager = nm_firewall_manager_get (); + if (priv->ifindex <= 0 && !device_has_capability (self, NM_DEVICE_CAP_IS_NON_KERNEL)) + _LOGW (LOGD_HW, "failed to look up interface index"); - device_get_driver_info (priv->iface, &priv->driver_version, &priv->firmware_version); + device_get_driver_info (self, priv->iface, &priv->driver_version, &priv->firmware_version); /* Watch for external IP config changes */ platform = nm_platform_get (); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), dev); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self); + + if (nm_platform_check_support_user_ipv6ll ()) { + int ip_ifindex = nm_device_get_ip_ifindex (self); + + if (ip_ifindex > 0) + priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (ip_ifindex); + } return object; error: - g_object_unref (dev); + g_object_unref (self); return NULL; } static void constructed (GObject *object) { - NMDevice *dev = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int master; - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); - if (NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address (dev); + if (NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address) + NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address (self); - if (NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev); + if (NM_DEVICE_GET_CLASS (self)->update_initial_hw_address) + NM_DEVICE_GET_CLASS (self)->update_initial_hw_address (self); /* Have to call update_initial_hw_address() before calling get_ignore_carrier() */ - if (device_has_capability (dev, NM_DEVICE_CAP_CARRIER_DETECT)) { - priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), NM_CONFIG_DEVICE (dev)); - - check_carrier (dev); - nm_log_info (LOGD_HW, - "(%s): carrier is %s%s", - nm_device_get_iface (NM_DEVICE (dev)), - priv->carrier ? "ON" : "OFF", - priv->ignore_carrier ? " (but ignored)" : ""); + if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { + priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), self); + + check_carrier (self); + _LOGI (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; @@ -7271,27 +8103,42 @@ constructed (GObject *object) if (priv->ifindex > 0) { priv->is_software = nm_platform_link_is_software (priv->ifindex); priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex); + priv->mtu = nm_platform_link_get_mtu (priv->ifindex); } + /* Indicate software device in capabilities. */ + if (priv->is_software) + priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; - if (priv->ifindex > 0) - priv->mtu = nm_platform_link_get_mtu (priv->ifindex); + /* Enslave ourselves */ + master = nm_platform_link_get_master (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, NM_CP_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), - dev); + self); g_signal_connect (priv->con_provider, NM_CP_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), - dev); + self); g_signal_connect (priv->con_provider, NM_CP_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), - dev); + self); + + /* Update default-unmanaged device available connections immediately, + * since they don't transition from UNMANAGED (and thus the state handler + * doesn't run and update them) until something external happens. + */ + if (nm_device_get_default_unmanaged (self)) { + nm_device_set_autoconnect (self, FALSE); + nm_device_recheck_available_connections (self); + } G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); } @@ -7303,6 +8150,8 @@ dispose (GObject *object) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatform *platform; + _LOGD (LOGD_DEVICE, "dispose(): %s", G_OBJECT_TYPE_NAME (self)); + dispatcher_cleanup (self); _cleanup_generic_pre (self, FALSE); @@ -7310,6 +8159,9 @@ dispose (GObject *object) g_warn_if_fail (priv->slaves == NULL); g_assert (priv->master_ready_id == 0); + /* Let the kernel manage IPv6LL again */ + set_nm_ipv6ll (self, FALSE); + _cleanup_generic_post (self, FALSE); g_clear_pointer (&priv->ip6_saved_properties, g_hash_table_unref); @@ -7342,8 +8194,6 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self); g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self); - g_clear_object (&priv->fw_manager); - G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); } @@ -7353,6 +8203,9 @@ finalize (GObject *object) NMDevice *self = NM_DEVICE (object); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self)); + + g_free (priv->hw_addr); g_slist_free_full (priv->pending_actions, g_free); g_clear_pointer (&priv->physical_port_id, g_free); g_free (priv->udi); @@ -7363,8 +8216,7 @@ finalize (GObject *object) g_free (priv->driver_version); g_free (priv->firmware_version); g_free (priv->type_desc); - if (priv->dhcp_anycast_address) - g_byte_array_free (priv->dhcp_anycast_address, TRUE); + g_free (priv->dhcp_anycast_address); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); } @@ -7373,9 +8225,11 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatformLink *platform_device; - const char *hw_addr; + const char *hw_addr, *p; + guint count; switch (prop_id) { case PROP_PLATFORM_DEVICE: @@ -7386,6 +8240,7 @@ set_property (GObject *object, guint prop_id, g_free (priv->iface); priv->iface = g_strdup (platform_device->name); priv->ifindex = platform_device->ifindex; + priv->up = platform_device->up; g_free (priv->driver); priv->driver = g_strdup (platform_device->driver); } @@ -7399,18 +8254,10 @@ set_property (GObject *object, guint prop_id, case PROP_IFACE: if (g_value_get_string (value)) { g_free (priv->iface); - priv->ifindex = 0; priv->iface = g_value_dup_string (value); - - /* Only look up the ifindex if it appears to be an actual kernel - * interface name. eg Bluetooth devices won't have one until we know - * the IP interface. - */ - if (priv->iface && !strchr (priv->iface, ':')) { - priv->ifindex = nm_platform_link_get_ifindex (priv->iface); - if (priv->ifindex <= 0) - nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", priv->iface); - } + priv->ifindex = nm_platform_link_get_ifindex (priv->iface); + if (priv->ifindex > 0) + priv->up = nm_platform_link_is_up (priv->ifindex); } break; case PROP_DRIVER: @@ -7434,7 +8281,7 @@ set_property (GObject *object, guint prop_id, priv->ip4_address = g_value_get_uint (value); break; case PROP_AUTOCONNECT: - priv->autoconnect = g_value_get_boolean (value); + nm_device_set_autoconnect (self, g_value_get_boolean (value)); break; case PROP_FIRMWARE_MISSING: priv->firmware_missing = g_value_get_boolean (value); @@ -7454,19 +8301,30 @@ set_property (GObject *object, guint prop_id, priv->is_master = g_value_get_boolean (value); break; case PROP_HW_ADDRESS: - priv->hw_addr_len = nm_device_get_hw_address_length (NM_DEVICE (object), NULL); - - hw_addr = g_value_get_string (value); - if (!hw_addr) - break; - if (priv->hw_addr_len == 0) { - g_warn_if_fail (*hw_addr == '\0'); + /* construct only */ + p = hw_addr = g_value_get_string (value); + + /* Hardware address length is the number of ':' plus 1 */ + count = 1; + while (p && *p) { + if (*p++ == ':') + count++; + } + if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) { + if (hw_addr && *hw_addr) { + _LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d", + hw_addr, count); + } break; } - if (!nm_utils_hwaddr_aton_len (hw_addr, priv->hw_addr, priv->hw_addr_len)) { - g_warning ("Could not parse hw-address '%s'", hw_addr); - memset (priv->hw_addr, 0, sizeof (priv->hw_addr)); + priv->hw_addr_len = count; + g_free (priv->hw_addr); + if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len)) + priv->hw_addr = g_strdup (hw_addr); + else { + _LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr); + priv->hw_addr = NULL; } break; default: @@ -7596,10 +8454,7 @@ get_property (GObject *object, guint prop_id, g_value_set_object (value, priv->master); break; case PROP_HW_ADDRESS: - if (priv->hw_addr_len) - g_value_take_string (value, nm_utils_hwaddr_ntoa_len (priv->hw_addr, priv->hw_addr_len)); - else - g_value_set_string (value, NULL); + g_value_set_string (value, priv->hw_addr); break; case PROP_HAS_PENDING_ACTION: g_value_set_boolean (value, nm_device_has_pending_action (self)); @@ -7644,257 +8499,226 @@ nm_device_class_init (NMDeviceClass *klass) klass->bring_up = bring_up; klass->take_down = take_down; klass->carrier_changed = carrier_changed; - klass->get_hw_address_length = get_hw_address_length; + 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, - "Platform Device", - "NMPlatform device object", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + 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, - "UDI", - "Unique Device Identifier", + g_param_spec_string (NM_DEVICE_UDI, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IFACE, - g_param_spec_string (NM_DEVICE_IFACE, - "Interface", - "Interface", + g_param_spec_string (NM_DEVICE_IFACE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_IFACE, - g_param_spec_string (NM_DEVICE_IP_IFACE, - "IP Interface", - "IP Interface", + g_param_spec_string (NM_DEVICE_IP_IFACE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_DEVICE_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_DEVICE_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER_VERSION, - g_param_spec_string (NM_DEVICE_DRIVER_VERSION, - "Driver Version", - "Driver Version", + g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FIRMWARE_VERSION, - g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, - "Firmware Version", - "Firmware Version", + g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_CAPABILITIES, - "Capabilities", - "Capabilities", + g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "", 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_DEVICE_MTU, - "MTU", - "MTU", + g_param_spec_uint (NM_DEVICE_MTU, "", "", 0, G_MAXUINT32, 1500, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP4_ADDRESS, - g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, - "IP4 address", - "IP4 address", + g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "", 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP4_CONFIG, - g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, - "IP4 Config", - "IP4 Config", + g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DHCP4_CONFIG, - g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", + g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP6_CONFIG, - g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, - "IP6 Config", - "IP6 Config", + g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DHCP6_CONFIG, - g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", + g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_DEVICE_STATE, - "State", - "State", + g_param_spec_uint (NM_DEVICE_STATE, "", "", 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE_REASON, - g_param_spec_boxed (NM_DEVICE_STATE_REASON, - "StateReason", - "StateReason", + g_param_spec_boxed (NM_DEVICE_STATE_REASON, "", "", DBUS_TYPE_STATE_REASON_STRUCT, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTION, - g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, - "ActiveConnection", - "ActiveConnection", + g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_TYPE, - g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, - "DeviceType", - "DeviceType", + g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "", 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MANAGED, - g_param_spec_boolean (NM_DEVICE_MANAGED, - "Managed", - "Managed", + g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AUTOCONNECT, - g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, - "Autoconnect", - "Autoconnect", + g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", DEFAULT_AUTOCONNECT, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FIRMWARE_MISSING, - g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, - "FirmwareMissing", - "Firmware missing", + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TYPE_DESC, - g_param_spec_string (NM_DEVICE_TYPE_DESC, - "Type Description", - "Device type description", + g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RFKILL_TYPE, - g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, - "Rfkill Type", - "Type of rfkill switch (if any) supported by this device", + g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "", RFKILL_TYPE_WLAN, RFKILL_TYPE_MAX, RFKILL_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IFINDEX, - g_param_spec_int (NM_DEVICE_IFINDEX, - "Ifindex", - "Ifindex", + g_param_spec_int (NM_DEVICE_IFINDEX, "", "", 0, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AVAILABLE_CONNECTIONS, - g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, - "AvailableConnections", - "AvailableConnections", + g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PHYSICAL_PORT_ID, - g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, - "PhysicalPortId", - "PhysicalPortId", + g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IS_MASTER, - g_param_spec_boolean (NM_DEVICE_IS_MASTER, - "IsMaster", - "IsMaster", + g_param_spec_boolean (NM_DEVICE_IS_MASTER, "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MASTER, - g_param_spec_object (NM_DEVICE_MASTER, - "Master", - "Master", + g_param_spec_object (NM_DEVICE_MASTER, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_HW_ADDRESS, - "Hardware Address", - "Hardware address", + g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HAS_PENDING_ACTION, - g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, - "Has pending action", - "Has pending action", + g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[STATE_CHANGED] = diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index f74486e6..b3855c74 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -19,24 +19,18 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_H -#define NM_DEVICE_H +#ifndef __NETWORKMANAGER_DEVICE_H__ +#define __NETWORKMANAGER_DEVICE_H__ #include <glib-object.h> #include <dbus/dbus-glib.h> #include <netinet/in.h> -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-types.h" -#include "nm-activation-request.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" -#include "nm-dhcp4-config.h" -#include "nm-dhcp6-config.h" #include "nm-connection.h" #include "nm-rfkill-manager.h" -#include "nm-connection-provider.h" -#include "nm-platform.h" +#include "NetworkManagerUtils.h" /* Properties */ #define NM_DEVICE_UDI "udi" @@ -62,12 +56,13 @@ #define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_MTU "mtu" -#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ -#define NM_DEVICE_IS_MASTER "is-master" /* Internal only */ -#define NM_DEVICE_MASTER "master" /* Internal only */ -#define NM_DEVICE_HW_ADDRESS "hw-address" /* Internal only */ +#define NM_DEVICE_HW_ADDRESS "hw-address" + +#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ +#define NM_DEVICE_IS_MASTER "is-master" /* Internal only */ +#define NM_DEVICE_MASTER "master" /* Internal only */ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ @@ -90,12 +85,6 @@ G_BEGIN_DECLS typedef enum NMActStageReturn NMActStageReturn; -typedef enum { - NM_DEVICE_ERROR_CONNECTION_ACTIVATING = 0, /*< nick=ConnectionActivating >*/ - NM_DEVICE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ -} NMDeviceError; - struct _NMDevice { GObject parent; }; @@ -120,10 +109,10 @@ typedef struct { /* Carrier state (IFF_LOWER_UP) */ void (*carrier_changed) (NMDevice *, gboolean carrier); - void (* update_hw_address) (NMDevice *self); void (* update_permanent_hw_address) (NMDevice *self); void (* update_initial_hw_address) (NMDevice *self); - guint (* get_hw_address_length) (NMDevice *self, gboolean *out_permanent); + + gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid); guint32 (* get_generic_capabilities) (NMDevice *self); @@ -183,7 +172,7 @@ typedef struct { /* Called right before IP config is set; use for setting MTU etc */ void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config); - void (* ip6_config_pre_commit) (NMDevice *self); + void (* ip6_config_pre_commit) (NMDevice *self, NMIP6Config *config); void (* deactivate) (NMDevice *self); @@ -192,6 +181,11 @@ typedef struct { /* Update the connection with currently configured L2 settings */ void (* update_connection) (NMDevice *device, NMConnection *connection); + gboolean (*master_update_slave_connection) (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error); + gboolean (* enslave_slave) (NMDevice *self, NMDevice *slave, NMConnection *connection, @@ -207,6 +201,8 @@ typedef struct { gboolean (* component_added) (NMDevice *self, GObject *component); gboolean (* owns_iface) (NMDevice *self, const char *iface); + + NMConnection * (* new_default_connection) (NMDevice *self); } NMDeviceClass; @@ -220,6 +216,8 @@ GType nm_device_get_type (void); const char * nm_device_get_path (NMDevice *dev); void nm_device_dbus_export (NMDevice *device); +void nm_device_finish_init (NMDevice *device); + const char * nm_device_get_udi (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev); int nm_device_get_ifindex (NMDevice *dev); @@ -232,11 +230,13 @@ const char * nm_device_get_type_desc (NMDevice *dev); NMDeviceType nm_device_get_device_type (NMDevice *dev); int nm_device_get_priority (NMDevice *dev); +guint32 nm_device_get_ip4_route_metric (NMDevice *dev); +guint32 nm_device_get_ip6_route_metric (NMDevice *dev); -const guint8 * nm_device_get_hw_address (NMDevice *dev, guint *out_len); +const char * nm_device_get_hw_address (NMDevice *dev); -NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *dev); -NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *dev); +NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); +NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); void nm_device_set_vpn4_config (NMDevice *dev, NMIP4Config *config); @@ -255,14 +255,21 @@ NMDevice * nm_device_get_master (NMDevice *dev); NMActRequest * nm_device_get_act_request (NMDevice *dev); NMConnection * nm_device_get_connection (NMDevice *dev); +void nm_device_removed (NMDevice *dev); + gboolean nm_device_is_available (NMDevice *dev); gboolean nm_device_has_carrier (NMDevice *dev); -NMConnection * nm_device_generate_connection (NMDevice *device); +NMConnection * nm_device_generate_connection (NMDevice *self, NMDevice *master); -NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, - GSList *connections, - char **specific_object); +gboolean nm_device_master_update_slave_connection (NMDevice *master, + NMDevice *slave, + NMConnection *connection, + GError **error); + +gboolean nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object); gboolean nm_device_complete_connection (NMDevice *device, NMConnection *connection, @@ -272,6 +279,8 @@ gboolean nm_device_complete_connection (NMDevice *device, gboolean nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection); +gboolean nm_device_uses_assumed_connection (NMDevice *device); + gboolean nm_device_can_assume_active_connection (NMDevice *device); gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); @@ -294,12 +303,16 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device); * @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie, * because NM is sleeping or not managed for some other reason) * @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs) + * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged + * @NM_UNMANAGED_EXTERNAL_DOWN: %TRUE when unmanaged because !IFF_UP and not created by NM */ typedef enum { - NM_UNMANAGED_NONE = 0x00, - NM_UNMANAGED_DEFAULT = 0x01, - NM_UNMANAGED_INTERNAL = 0x02, - NM_UNMANAGED_USER = 0x04, + NM_UNMANAGED_NONE = 0x00, + NM_UNMANAGED_DEFAULT = 0x01, + NM_UNMANAGED_INTERNAL = 0x02, + NM_UNMANAGED_USER = 0x04, + NM_UNMANAGED_PARENT = 0x08, + NM_UNMANAGED_EXTERNAL_DOWN = 0x10, /* Boundary value */ __NM_UNMANAGED_LAST, @@ -355,6 +368,13 @@ gboolean nm_device_notify_component_added (NMDevice *device, GObject *component) gboolean nm_device_owns_iface (NMDevice *device, const char *iface); +NMConnection *nm_device_new_default_connection (NMDevice *self); + +const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed); +const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed); + +void nm_device_spawn_iface_helper (NMDevice *self); + G_END_DECLS /* For testing only */ diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am new file mode 100644 index 00000000..6fea9b3f --- /dev/null +++ b/src/devices/team/Makefile.am @@ -0,0 +1,68 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/platform \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ + -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) + +if WITH_TEAMDCTL +AM_CPPFLAGS += ${LIBTEAMDCTL_CFLAGS} +endif + +GLIB_GENERATED = nm-team-enum-types.h nm-team-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_team_enum_types_sources = $(srcdir)/nm-device-team.h + +glue_sources = \ + nm-device-team-glue.h + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) + +pkglib_LTLIBRARIES = libnm-device-plugin-team.la + +SYMBOL_VIS_FILE=$(srcdir)/exports.ver + +libnm_device_plugin_team_la_SOURCES = \ + nm-device-team.c \ + nm-device-team.h \ + nm-team-factory.c \ + nm-team-factory.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_team_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_team_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +if WITH_TEAMDCTL +libnm_device_plugin_team_la_LIBADD += $(LIBTEAMDCTL_LIBS) +endif + +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = $(SYMBOL_VIS_FILE) + +if ENABLE_TESTS + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + +endif + diff --git a/src/devices/team/Makefile.in b/src/devices/team/Makefile.in new file mode 100644 index 00000000..4ee30e66 --- /dev/null +++ b/src/devices/team/Makefile.in @@ -0,0 +1,845 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WITH_TEAMDCTL_TRUE@am__append_1 = ${LIBTEAMDCTL_CFLAGS} +@WITH_TEAMDCTL_TRUE@am__append_2 = $(LIBTEAMDCTL_LIBS) +subdir = src/devices/team +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@WITH_TEAMDCTL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libnm_device_plugin_team_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__objects_1 = nm-team-enum-types.lo +am__objects_2 = +am__objects_3 = $(am__objects_1) $(am__objects_2) +am_libnm_device_plugin_team_la_OBJECTS = nm-device-team.lo \ + nm-team-factory.lo $(am__objects_3) +libnm_device_plugin_team_la_OBJECTS = \ + $(am_libnm_device_plugin_team_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libnm_device_plugin_team_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libnm_device_plugin_team_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libnm_device_plugin_team_la_SOURCES) +DIST_SOURCES = $(libnm_device_plugin_team_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src \ + -I${top_srcdir}/src/devices -I${top_srcdir}/src/platform \ + -I${top_srcdir}/include -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ + -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(DBUS_CFLAGS) \ + $(am__append_1) +GLIB_GENERATED = nm-team-enum-types.h nm-team-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_team_enum_types_sources = $(srcdir)/nm-device-team.h +glue_sources = \ + nm-device-team-glue.h + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) +pkglib_LTLIBRARIES = libnm-device-plugin-team.la +SYMBOL_VIS_FILE = $(srcdir)/exports.ver +libnm_device_plugin_team_la_SOURCES = \ + nm-device-team.c \ + nm-device-team.h \ + nm-team-factory.c \ + nm-team-factory.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_team_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_team_la_LIBADD = $(DBUS_LIBS) $(GUDEV_LIBS) \ + $(am__append_2) +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = $(SYMBOL_VIS_FILE) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/team/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/devices/team/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libnm-device-plugin-team.la: $(libnm_device_plugin_team_la_OBJECTS) $(libnm_device_plugin_team_la_DEPENDENCIES) $(EXTRA_libnm_device_plugin_team_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_device_plugin_team_la_LINK) -rpath $(pkglibdir) $(libnm_device_plugin_team_la_OBJECTS) $(libnm_device_plugin_team_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-team-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-team-factory.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@ENABLE_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/devices/team/exports.ver b/src/devices/team/exports.ver new file mode 100644 index 00000000..24cd848c --- /dev/null +++ b/src/devices/team/exports.ver @@ -0,0 +1,6 @@ +{ +global: + nm_device_factory_create; +local: + *; +}; diff --git a/src/devices/team/nm-device-team-glue.h b/src/devices/team/nm-device-team-glue.h new file mode 100644 index 00000000..405975c8 --- /dev/null +++ b/src/devices/team/nm-device-team-glue.h @@ -0,0 +1,73 @@ +/* Generated by dbus-binding-tool; do not edit! */ + + +#ifndef __dbus_glib_marshal_nm_device_team_MARSHAL_H__ +#define __dbus_glib_marshal_nm_device_team_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +G_END_DECLS + +#endif /* __dbus_glib_marshal_nm_device_team_MARSHAL_H__ */ + +#include <dbus/dbus-glib.h> +static const DBusGMethodInfo dbus_glib_nm_device_team_methods[] = { +}; + +const DBusGObjectInfo dbus_glib_nm_device_team_object_info = { 1, + dbus_glib_nm_device_team_methods, + 0, +"\0", +"org.freedesktop.NetworkManager.Device.Team\0PropertiesChanged\0\0", +"org.freedesktop.NetworkManager.Device.Team\0HwAddress\0hw_address\0read\0org.freedesktop.NetworkManager.Device.Team\0Carrier\0carrier\0read\0org.freedesktop.NetworkManager.Device.Team\0Slaves\0slaves\0read\0\0" +}; + diff --git a/src/devices/nm-device-team.c b/src/devices/team/nm-device-team.c index f3b25e3b..16f1fcc2 100644 --- a/src/devices/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -27,38 +27,34 @@ #include <glib.h> #include <glib/gi18n.h> #include <gio/gio.h> -#include <netinet/ether.h> -#if WITH_TEAMDCTL #include <teamdctl.h> -#endif #include <stdlib.h> #include "nm-device-team.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-platform.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" +#include "nm-team-enum-types.h" #include "nm-posix-signals.h" +#include "nm-core-internal.h" #include "nm-device-team-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceTeam); G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) #define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) -#define NM_TEAM_ERROR (nm_team_error_quark ()) - -static gboolean teamd_start (NMDevice *dev, NMSettingTeam *s_team); +static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); typedef struct { -#if WITH_TEAMDCTL struct teamdctl *tdc; -#endif GPid teamd_pid; guint teamd_process_watch; guint teamd_timeout; @@ -74,28 +70,17 @@ enum { /******************************************************************/ -static GQuark -nm_team_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-team-error"); - return quark; -} - -/******************************************************************/ - static guint32 -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities (NMDevice *device) { return NM_DEVICE_CAP_CARRIER_DETECT; } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - if (NM_DEVICE_GET_CLASS (dev)->is_up) - return NM_DEVICE_GET_CLASS (dev)->is_up (dev); + if (NM_DEVICE_GET_CLASS (device)->is_up) + return NM_DEVICE_GET_CLASS (device)->is_up (device); return FALSE; } @@ -124,7 +109,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; /* Team connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; @@ -140,17 +125,14 @@ complete_connection (NMDevice *device, const GSList *existing_connections, GError **error) { - NMSettingTeam *s_team, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; + NMSettingTeam *s_team; nm_utils_complete_generic (connection, NM_SETTING_TEAM_SETTING_NAME, existing_connections, - _("Team connection %d"), NULL, + _("Team connection"), + "team", TRUE); s_team = nm_connection_get_setting_team (connection); @@ -159,41 +141,13 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_team)); } - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_team_get_interface_name (s_team)) { - name = g_strdup_printf ("team%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing team connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_team (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_TEAM_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_team_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - return TRUE; } -#if WITH_TEAMDCTL static gboolean -ensure_teamd_connection (NMDevice *self) +ensure_teamd_connection (NMDevice *device) { + NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); int err; @@ -202,32 +156,28 @@ ensure_teamd_connection (NMDevice *self) priv->tdc = teamdctl_alloc (); g_assert (priv->tdc); - err = teamdctl_connect (priv->tdc, nm_device_get_iface (self), NULL, NULL); + err = teamdctl_connect (priv->tdc, nm_device_get_iface (device), NULL, NULL); if (err != 0) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd (err=%d)", - nm_device_get_iface (self), err); + _LOGE (LOGD_TEAM, "failed to connect to teamd (err=%d)", err); teamdctl_free (priv->tdc); priv->tdc = NULL; } return !!priv->tdc; } -#endif static void update_connection (NMDevice *device, NMConnection *connection) { + NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMSettingTeam *s_team = nm_connection_get_setting_team (connection); - const char *iface = nm_device_get_iface (device); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, (NMSetting *) s_team); - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, iface, NULL); } g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); -#if WITH_TEAMDCTL teamd_start (device, s_team); if (NM_DEVICE_TEAM_GET_PRIVATE (device)->teamd_pid > 0 && ensure_teamd_connection (device)) { const char *config = NULL; @@ -238,51 +188,59 @@ update_connection (NMDevice *device, NMConnection *connection) if (err == 0) g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL); else - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd config (err=%d)", iface, err); + _LOGE (LOGD_TEAM, "failed to read teamd config (err=%d)", err); } -#endif } /******************************************************************/ -gboolean -nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) { NMSettingTeamPort *s_port; - const char *iface = nm_device_get_iface (slave); char *port_config = NULL; - gboolean with_teamdctl = FALSE; int err = 0; -#if WITH_TEAMDCTL - const char *master_iface; - int master_ifindex; struct teamdctl *tdc; const char *team_port_config = NULL; -#endif - - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - -#if WITH_TEAMDCTL - master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave)); - g_assert (master_ifindex > 0); - master_iface = nm_platform_link_get_name (master_ifindex); - g_assert (master_iface); + const char *iface = nm_device_get_iface (self); + const char *iface_slave = nm_device_get_iface (slave); tdc = teamdctl_alloc (); - g_assert (tdc); - err = teamdctl_connect (tdc, master_iface, NULL, NULL); + if (!tdc) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master %s (out of memory?)", + iface_slave, iface); + g_return_val_if_reached (FALSE); + } + + err = teamdctl_connect (tdc, iface, NULL, NULL); if (err) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)", - iface, master_iface, err); teamdctl_free (tdc); + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master %s (err=%d)", + iface_slave, iface, err); return FALSE; } - err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config); + + err = teamdctl_port_config_get_raw_direct (tdc, iface_slave, (char **)&team_port_config); port_config = g_strdup (team_port_config); teamdctl_free (tdc); - with_teamdctl = TRUE; -#endif + if (err) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to get configuration from teamd master %s (err=%d)", + iface_slave, iface, err); + g_free (port_config); + return FALSE; + } s_port = nm_connection_get_setting_team_port (connection); if (!s_port) { @@ -293,56 +251,19 @@ nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free (port_config); - if (!with_teamdctl || err != 0) { - if (!with_teamdctl) - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration " - " (compiled without libteamdctl support)", iface); - else - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)", - iface, err); - return FALSE; - } - + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, + NULL); return TRUE; } /******************************************************************/ -static gboolean -ensure_killed (gpointer data) -{ - int pid = GPOINTER_TO_INT (data); - - if (kill (pid, 0) == 0) - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_TEAM, "waiting for teamd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_TEAM, "teamd pid %d cleaned up", pid); - - return FALSE; -} - static void -service_kill (int pid) +teamd_timeout_remove (NMDevice *device) { - if (kill (pid, SIGTERM) == 0) - g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (pid)); - else { - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_TEAM, "waiting for teamd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_TEAM, "teamd pid %d cleaned up", pid); - } -} - -static void -teamd_timeout_remove (NMDevice *dev) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); if (priv->teamd_timeout) { g_source_remove (priv->teamd_timeout); @@ -351,9 +272,9 @@ teamd_timeout_remove (NMDevice *dev) } static void -teamd_cleanup (NMDevice *dev, gboolean device_state_failed) +teamd_cleanup (NMDevice *device, gboolean device_state_failed) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); if (priv->teamd_dbus_watch) { g_bus_unwatch_name (priv->teamd_dbus_watch); @@ -366,37 +287,36 @@ teamd_cleanup (NMDevice *dev, gboolean device_state_failed) } if (priv->teamd_pid > 0) { - service_kill (priv->teamd_pid); + nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, "teamd", 2000, NULL, NULL); priv->teamd_pid = 0; } -#if WITH_TEAMDCTL if (priv->tdc) { teamdctl_disconnect (priv->tdc); teamdctl_free (priv->tdc); priv->tdc = NULL; } -#endif - teamd_timeout_remove (dev); + teamd_timeout_remove (device); if (device_state_failed) { - if (nm_device_is_activating (dev) || - (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + if (nm_device_is_activating (device) || + (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); } } static gboolean teamd_timeout_cb (gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDevice *device = NM_DEVICE (self); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); g_return_val_if_fail (priv->teamd_timeout, FALSE); - nm_log_info (LOGD_TEAM, "(%s): teamd timed out.", nm_device_get_iface (dev)); - teamd_cleanup (dev, TRUE); + _LOGI (LOGD_TEAM, "teamd timed out."); + teamd_cleanup (device, TRUE); return FALSE; } @@ -407,20 +327,24 @@ teamd_dbus_appeared (GDBusConnection *connection, const gchar *name_owner, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + gboolean success; g_return_if_fail (priv->teamd_dbus_watch); - nm_log_info (LOGD_TEAM, "(%s): teamd appeared on D-Bus", nm_device_get_iface (dev)); - teamd_timeout_remove (dev); -#if WITH_TEAMDCTL - if (!ensure_teamd_connection (dev)) { - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); + teamd_timeout_remove (device); + + success = ensure_teamd_connection (device); + if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) { + if (success) + nm_device_activate_schedule_stage2_device_config (device); + else if (!nm_device_uses_assumed_connection (device)) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); return; } -#endif - nm_device_activate_schedule_stage2_device_config (dev); } static void @@ -428,8 +352,9 @@ teamd_dbus_vanished (GDBusConnection *connection, const gchar *name, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (priv->teamd_dbus_watch); @@ -441,26 +366,27 @@ teamd_dbus_vanished (GDBusConnection *connection, * Note that g_bus_watch_name is guaranteed to alternate vanished/appeared signals, * so we won't hit this condition again (because the next signal is either 'appeared' * or 'timeout'). */ - nm_log_dbg (LOGD_TEAM, "(%s): teamd vanished from D-Bus (ignored)", nm_device_get_iface (dev)); + _LOGD (LOGD_TEAM, "teamd vanished from D-Bus (ignored)"); return; } - nm_log_info (LOGD_TEAM, "(%s): teamd vanished from D-Bus", nm_device_get_iface (dev)); - teamd_cleanup (dev, TRUE); + _LOGI (LOGD_TEAM, "teamd vanished from D-Bus"); + teamd_cleanup (device, TRUE); } static void teamd_process_watch_cb (GPid pid, gint status, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (priv->teamd_process_watch); - nm_log_info (LOGD_TEAM, "(%s): teamd died", nm_device_get_iface (dev)); + _LOGI (LOGD_TEAM, "teamd died with status %d", status); priv->teamd_process_watch = 0; priv->teamd_pid = 0; - teamd_cleanup (dev, TRUE); + teamd_cleanup (device, TRUE); } static void @@ -481,18 +407,14 @@ teamd_child_setup (gpointer user_data G_GNUC_UNUSED) } static gboolean -teamd_start (NMDevice *dev, NMSettingTeam *s_team) +teamd_start (NMDevice *device, NMSettingTeam *s_team) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - const char *iface = nm_device_get_ip_iface (dev); - char *tmp_str; + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + const char *iface = nm_device_get_ip_iface (device); + char *tmp_str = NULL; const char *config; - const char **teamd_binary = NULL; - static const char *teamd_paths[] = { - "/usr/bin/teamd", - "/usr/local/bin/teamd", - NULL - }; + const char *teamd_binary; GPtrArray *argv; GError *error = NULL; gboolean ret; @@ -501,51 +423,42 @@ teamd_start (NMDevice *dev, NMSettingTeam *s_team) if (priv->teamd_dbus_watch || priv->teamd_process_watch || priv->teamd_pid > 0 || -#if WITH_TEAMDCTL priv->tdc || -#endif priv->teamd_timeout) { /* Just return if teamd_start() was already called */ return TRUE; } - teamd_binary = teamd_paths; - while (*teamd_binary != NULL) { - if (g_file_test (*teamd_binary, G_FILE_TEST_EXISTS)) - break; - teamd_binary++; - } - - if (!*teamd_binary) { - nm_log_warn (LOGD_TEAM, - "Activation (%s) failed to start teamd: teamd binary not found", - iface); + teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); + if (!teamd_binary) { + _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); return FALSE; } /* Kill teamd for same named device first if it is there */ argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) *teamd_binary); + g_ptr_array_add (argv, (gpointer) teamd_binary); g_ptr_array_add (argv, (gpointer) "-k"); g_ptr_array_add (argv, (gpointer) "-t"); g_ptr_array_add (argv, (gpointer) iface); g_ptr_array_add (argv, NULL); - tmp_str = g_strjoinv (" ", (gchar **) argv->pdata); - nm_log_dbg (LOGD_TEAM, "running: %s", tmp_str); - g_free (tmp_str); + _LOGD (LOGD_TEAM, "running: %s", + (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + g_clear_pointer (&tmp_str, g_free); ret = g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &error); g_ptr_array_free (argv, TRUE); /* Start teamd now */ argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) *teamd_binary); + g_ptr_array_add (argv, (gpointer) teamd_binary); g_ptr_array_add (argv, (gpointer) "-o"); g_ptr_array_add (argv, (gpointer) "-n"); g_ptr_array_add (argv, (gpointer) "-U"); g_ptr_array_add (argv, (gpointer) "-D"); + g_ptr_array_add (argv, (gpointer) "-N"); g_ptr_array_add (argv, (gpointer) "-t"); g_ptr_array_add (argv, (gpointer) iface); @@ -559,12 +472,12 @@ teamd_start (NMDevice *dev, NMSettingTeam *s_team) g_ptr_array_add (argv, (gpointer) "-gg"); g_ptr_array_add (argv, NULL); - tmp_str = g_strjoinv (" ", (gchar **) argv->pdata); - nm_log_dbg (LOGD_TEAM, "running: %s", tmp_str); - g_free (tmp_str); + _LOGD (LOGD_TEAM, "running: %s", + (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + g_clear_pointer (&tmp_str, g_free); /* Start a timeout for teamd to appear at D-Bus */ - priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, dev); + priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device); /* Register D-Bus name watcher */ tmp_str = g_strdup_printf ("org.libteam.teamd.%s", iface); @@ -573,7 +486,7 @@ teamd_start (NMDevice *dev, NMSettingTeam *s_team) G_BUS_NAME_WATCHER_FLAGS_NONE, teamd_dbus_appeared, teamd_dbus_vanished, - dev, + device, NULL); g_free (tmp_str); @@ -581,41 +494,36 @@ teamd_start (NMDevice *dev, NMSettingTeam *s_team) &teamd_child_setup, NULL, &priv->teamd_pid, &error); g_ptr_array_free (argv, TRUE); if (!ret) { - nm_log_warn (LOGD_TEAM, - "Activation (%s) failed to start teamd: %s", - iface, error->message); + _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); g_clear_error (&error); - teamd_cleanup (dev, FALSE); + teamd_cleanup (device, FALSE); return FALSE; } /* Monitor the child process so we know when it dies */ priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid, teamd_process_watch_cb, - dev); + device); - nm_log_info (LOGD_TEAM, - "Activation (%s) started teamd...", iface); + _LOGI (LOGD_TEAM, "Activation: (team) started teamd..."); return TRUE; } static void -teamd_stop (NMDevice *dev) +teamd_stop (NMDevice *device) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - if (priv->teamd_pid > 0) { - nm_log_info (LOGD_TEAM, "Deactivation (%s) stopping teamd...", - nm_device_get_ip_iface (dev)); - } else { - nm_log_dbg (LOGD_TEAM, "Deactivation (%s) stopping teamd (not started)...", - nm_device_get_ip_iface (dev)); - } - teamd_cleanup (dev, FALSE); + if (priv->teamd_pid > 0) + _LOGI (LOGD_TEAM, "Deactivation: stopping teamd..."); + else + _LOGD (LOGD_TEAM, "Deactivation: stopping teamd (not started)..."); + teamd_cleanup (device, FALSE); } static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; NMConnection *connection; @@ -623,13 +531,13 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason); if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_team = nm_connection_get_setting_team (connection); g_assert (s_team); - if (teamd_start (dev, s_team)) + if (teamd_start (device, s_team)) ret = NM_ACT_STAGE_RETURN_POSTPONE; else ret = NM_ACT_STAGE_RETURN_FAILURE; @@ -638,9 +546,9 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) } static void -deactivate (NMDevice *dev) +deactivate (NMDevice *device) { - teamd_stop (dev); + teamd_stop (device); } static gboolean @@ -649,11 +557,9 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { -#if WITH_TEAMDCTL + NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); -#endif gboolean success = TRUE, no_firmware = FALSE; - const char *iface = nm_device_get_ip_iface (device); const char *slave_iface = nm_device_get_ip_iface (slave); NMSettingTeamPort *s_team_port; @@ -667,10 +573,9 @@ enslave_slave (NMDevice *device, const char *config = nm_setting_team_port_get_config (s_team_port); if (config) { -#if WITH_TEAMDCTL if (!priv->tdc) { - nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed, not connected to teamd", - iface, slave_iface); + _LOGW (LOGD_TEAM, "enslaved team port %s config not changed, not connected to teamd", + slave_iface); } else { int err; char *sanitized_config; @@ -679,15 +584,11 @@ enslave_slave (NMDevice *device, err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); g_free (sanitized_config); if (err != 0) { - nm_log_err (LOGD_TEAM, "(%s): failed to update config for port %s (err=%d)", - iface, slave_iface, err); + _LOGE (LOGD_TEAM, "failed to update config for port %s (err=%d)", + slave_iface, err); return FALSE; } } -#else - nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed due to lack of Teamd control support", - iface, slave_iface); -#endif } } success = nm_platform_link_enslave (nm_device_get_ip_ifindex (device), @@ -697,9 +598,9 @@ enslave_slave (NMDevice *device, if (!success) return FALSE; - nm_log_info (LOGD_TEAM, "(%s): enslaved team port %s", iface, slave_iface); + _LOGI (LOGD_TEAM, "enslaved team port %s", slave_iface); } else - nm_log_info (LOGD_TEAM, "(%s): team port %s was enslaved", iface, slave_iface); + _LOGI (LOGD_TEAM, "team port %s was enslaved", slave_iface); g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); @@ -711,26 +612,19 @@ release_slave (NMDevice *device, NMDevice *slave, gboolean configure) { + NMDeviceTeam *self = NM_DEVICE_TEAM (device); gboolean success = TRUE, no_firmware = FALSE; if (configure) { success = nm_platform_link_release (nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)); - if (success) { - nm_log_info (LOGD_TEAM, "(%s): released team port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } else { - nm_log_warn (LOGD_TEAM, "(%s): failed to release team port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } - } else { - nm_log_info (LOGD_TEAM, "(%s): team port %s was released", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } + if (success) + _LOGI (LOGD_TEAM, "released team port %s", nm_device_get_ip_iface (slave)); + else + _LOGW (LOGD_TEAM, "failed to release team port %s", nm_device_get_ip_iface (slave)); + } else + _LOGI (LOGD_TEAM, "team port %s was released", nm_device_get_ip_iface (slave)); if (success) g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); @@ -740,10 +634,9 @@ release_slave (NMDevice *device, * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released port. */ - if (!nm_device_bring_up (slave, TRUE, &no_firmware)) { - nm_log_warn (LOGD_TEAM, "(%s): released team port could not be brought up.", - nm_device_get_iface (slave)); - } + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) + _LOGW (LOGD_TEAM, "released team port %s could not be brought up", + nm_device_get_ip_iface (slave)); } return success; @@ -766,18 +659,21 @@ nm_device_team_new (NMPlatformLink *platform_device) } NMDevice * -nm_device_team_new_for_connection (NMConnection *connection) +nm_device_team_new_for_connection (NMConnection *connection, GError **error) { const char *iface; g_return_val_if_fail (connection != NULL, NULL); - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); g_return_val_if_fail (iface != NULL, NULL); if ( !nm_platform_team_add (iface) && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_TEAM, "(%s): failed to create team master interface for '%s': %s", + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "failed to create team master interface '%s' for connection '%s': %s", iface, nm_connection_get_id (connection), nm_platform_get_error_msg ()); return NULL; @@ -793,16 +689,6 @@ nm_device_team_new_for_connection (NMConnection *connection) } static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_TEAM, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - -static void nm_device_team_init (NMDeviceTeam * self) { } @@ -860,7 +746,6 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->connection_type = NM_SETTING_TEAM_SETTING_NAME; /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; @@ -871,6 +756,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->check_connection_available = check_connection_available; parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->deactivate = deactivate; @@ -880,15 +766,12 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_team_object_info); - - dbus_g_error_domain_register (NM_TEAM_ERROR, NULL, NM_TYPE_TEAM_ERROR); } diff --git a/src/devices/nm-device-team.h b/src/devices/team/nm-device-team.h index fe1275c6..26ba5737 100644 --- a/src/devices/nm-device-team.h +++ b/src/devices/team/nm-device-team.h @@ -18,8 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef NM_DEVICE_TEAM_H -#define NM_DEVICE_TEAM_H +#ifndef __NETWORKMANAGER_DEVICE_TEAM_H__ +#define __NETWORKMANAGER_DEVICE_TEAM_H__ #include <glib-object.h> @@ -34,12 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM)) #define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) -typedef enum { - NM_TEAM_ERROR_CONNECTION_NOT_TEAM = 0, /*< nick=ConnectionNotTeam >*/ - NM_TEAM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMTeamError; - #define NM_DEVICE_TEAM_SLAVES "slaves" typedef struct { @@ -55,9 +49,7 @@ typedef struct { GType nm_device_team_get_type (void); NMDevice *nm_device_team_new (NMPlatformLink *platform_device); -NMDevice *nm_device_team_new_for_connection (NMConnection *connection); - -gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection); +NMDevice *nm_device_team_new_for_connection (NMConnection *connection, GError **error); G_END_DECLS diff --git a/src/devices/team/nm-team-enum-types.c b/src/devices/team/nm-team-enum-types.c new file mode 100644 index 00000000..5ac3494d --- /dev/null +++ b/src/devices/team/nm-team-enum-types.c @@ -0,0 +1,12 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#include "nm-team-enum-types.h" + +#include "nm-device-team.h" + + + + diff --git a/src/devices/team/nm-team-enum-types.h b/src/devices/team/nm-team-enum-types.h new file mode 100644 index 00000000..136cadc2 --- /dev/null +++ b/src/devices/team/nm-team-enum-types.h @@ -0,0 +1,17 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#ifndef __NM_TEAM_ENUM_TYPES_H__ +#define __NM_TEAM_ENUM_TYPES_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS +G_END_DECLS + +#endif /* __NM_TEAM_ENUM_TYPES_H__ */ + + + diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c new file mode 100644 index 00000000..cb887cac --- /dev/null +++ b/src/devices/team/nm-team-factory.c @@ -0,0 +1,93 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> +#include <gmodule.h> + +#include "nm-device-factory.h" +#include "nm-team-factory.h" +#include "nm-device-team.h" +#include "nm-logging.h" +#include "nm-platform.h" +#include "nm-core-internal.h" + +static GType nm_team_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMTeamFactory, nm_team_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +/************************************************************************/ + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL); +} + +/************************************************************************/ + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_TEAM) + return nm_device_team_new (plink); + return NULL; +} + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) + return nm_device_team_new_for_connection (connection, error); + return NULL; +} + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_TEAM; +} + +/************************************************************************/ + +static void +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->get_device_type = get_device_type; +} + +static void +nm_team_factory_class_init (NMTeamFactoryClass *klass) +{ +} diff --git a/src/devices/team/nm-team-factory.h b/src/devices/team/nm-team-factory.h new file mode 100644 index 00000000..2f02ac57 --- /dev/null +++ b/src/devices/team/nm-team-factory.h @@ -0,0 +1,37 @@ +/* -*- 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 (C) 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_TEAM_FACTORY_H__ +#define __NETWORKMANAGER_TEAM_FACTORY_H__ + +#include <glib-object.h> + +#define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type ()) +#define NM_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) + +typedef struct { + GObject parent; +} NMTeamFactory; + +typedef struct { + GObjectClass parent; +} NMTeamFactoryClass; + +#endif /* __NETWORKMANAGER_TEAM_FACTORY_H__ */ diff --git a/src/devices/wifi/Makefile.am b/src/devices/wifi/Makefile.am index 5f3ce286..230c00ac 100644 --- a/src/devices/wifi/Makefile.am +++ b/src/devices/wifi/Makefile.am @@ -7,21 +7,17 @@ SUBDIRS=. tests AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-wifi-enum-types.h nm-wifi-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM diff --git a/src/devices/wifi/Makefile.in b/src/devices/wifi/Makefile.in index cbf6826b..175dd900 100644 --- a/src/devices/wifi/Makefile.in +++ b/src/devices/wifi/Makefile.in @@ -261,6 +261,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -384,6 +386,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -403,6 +406,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -429,7 +433,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -512,21 +516,17 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-wifi-enum-types.h nm-wifi-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM diff --git a/src/devices/wifi/exports.ver b/src/devices/wifi/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wifi/exports.ver +++ b/src/devices/wifi/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 85214a70..0f5aa164 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -25,18 +25,16 @@ */ #include "config.h" + #include <glib.h> #include <glib/gi18n.h> #include <dbus/dbus.h> #include <netinet/in.h> #include <string.h> -#include <net/ethernet.h> -#include <netinet/ether.h> #include <sys/stat.h> #include <sys/wait.h> #include <signal.h> #include <unistd.h> -#include <linux/if.h> #include <sys/ioctl.h> #include <errno.h> @@ -53,14 +51,18 @@ #include "nm-manager.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-platform.h" #include "nm-wifi-enum-types.h" /* This is a bug; but we can't really change API now... */ -#include "NetworkManagerVPN.h" +#include "nm-vpn-dbus-interface.h" #include "nm-device-olpc-mesh-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceOlpcMesh); + G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) #define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) @@ -80,19 +82,6 @@ struct _NMDeviceOlpcMeshPrivate { /*******************************************************************/ -static GQuark -nm_olpc_mesh_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-mesh-error"); - return quark; -} - -#define NM_OLPC_MESH_ERROR (nm_olpc_mesh_error_quark ()) - -/*******************************************************************/ - static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { @@ -149,19 +138,17 @@ complete_connection (NMDevice *device, } if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) { - const guint8 anycast[ETH_ALEN] = { 0xC0, 0x27, 0xC0, 0x27, 0xC0, 0x27 }; + const char *anycast = "c0:27:c0:27:c0:27"; - tmp = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (tmp, anycast, sizeof (anycast)); - g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, anycast, NULL); } nm_utils_complete_generic (connection, NM_SETTING_OLPC_MESH_SETTING_NAME, existing_connections, - _("Mesh %d"), + NULL, + _("Mesh"), NULL, FALSE); /* No IPv6 by default */ @@ -171,28 +158,27 @@ complete_connection (NMDevice *device, /****************************************************************************/ static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (device); NMActStageReturn ret; gboolean scanning; - ret = NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->act_stage1_prepare (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; /* disconnect companion device, if it is connected */ if (nm_device_get_act_request (NM_DEVICE (priv->companion))) { - nm_log_info (LOGD_OLPC, "(%s): disconnecting companion device %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->companion)); + _LOGI (LOGD_OLPC, "disconnecting companion device %s", + nm_device_get_iface (priv->companion)); /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ nm_device_state_changed (NM_DEVICE (priv->companion), NM_DEVICE_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); - nm_log_info (LOGD_OLPC, "(%s): companion %s disconnected", - nm_device_get_iface (dev), - nm_device_get_iface (priv->companion)); + NM_DEVICE_STATE_REASON_USER_REQUESTED); + _LOGI (LOGD_OLPC, "companion %s disconnected", + nm_device_get_iface (priv->companion)); } @@ -218,16 +204,16 @@ _mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); NMConnection *connection; NMSettingOlpcMesh *s_mesh; guint32 channel; - const GByteArray *anycast_addr_array; - guint8 *anycast_addr = NULL; + GBytes *ssid; + const char *anycast_addr; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_mesh = nm_connection_get_setting_olpc_mesh (connection); @@ -236,25 +222,25 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) channel = nm_setting_olpc_mesh_get_channel (s_mesh); if (channel != 0) _mesh_set_channel (self, channel); - nm_platform_mesh_set_ssid (nm_device_get_ifindex (dev), - nm_setting_olpc_mesh_get_ssid (s_mesh)); - anycast_addr_array = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); - if (anycast_addr_array) - anycast_addr = anycast_addr_array->data; + ssid = nm_setting_olpc_mesh_get_ssid (s_mesh); + nm_platform_mesh_set_ssid (nm_device_get_ifindex (device), + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + + anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); + nm_device_set_dhcp_anycast_address (device, anycast_addr); - nm_device_set_dhcp_anycast_address (dev, anycast_addr); return NM_ACT_STAGE_RETURN_SUCCESS; } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because companion not found", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because companion not found"); return FALSE; } @@ -310,12 +296,11 @@ companion_state_changed_cb (NMDeviceWifi *companion, || state > NM_DEVICE_STATE_ACTIVATED) return; - nm_log_dbg (LOGD_OLPC, "(%s): disconnecting mesh due to companion connectivity", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_OLPC, "disconnecting mesh due to companion connectivity"); /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); + NM_DEVICE_STATE_REASON_USER_REQUESTED); } static gboolean @@ -343,24 +328,21 @@ static gboolean check_companion (NMDeviceOlpcMesh *self, NMDevice *other) { NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - const guint8 *my_addr, *their_addr; - guint their_addr_len; + const char *my_addr, *their_addr; if (!NM_IS_DEVICE_WIFI (other)) return FALSE; - my_addr = nm_device_get_hw_address (NM_DEVICE (self), NULL); - their_addr = nm_device_get_hw_address (other, &their_addr_len); - if ( (their_addr_len != ETH_ALEN) - || (memcmp (my_addr, their_addr, ETH_ALEN) != 0)) + my_addr = nm_device_get_hw_address (NM_DEVICE (self)); + their_addr = nm_device_get_hw_address (other); + if (!nm_utils_hwaddr_matches (my_addr, -1, their_addr, -1)) return FALSE; g_assert (priv->companion == NULL); priv->companion = g_object_ref (other); - nm_log_info (LOGD_OLPC, "(%s): found companion WiFi device %s", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_iface (other)); + _LOGI (LOGD_OLPC, "found companion WiFi device %s", + nm_device_get_iface (other)); g_signal_connect (G_OBJECT (other), "state-changed", G_CALLBACK (companion_state_changed_cb), self); @@ -471,13 +453,8 @@ constructor (GType type, self = NM_DEVICE_OLPC_MESH (object); - nm_log_dbg (LOGD_HW | LOGD_OLPC, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &caps)) { - nm_log_warn (LOGD_HW | LOGD_OLPC, "(%s): failed to initialize WiFi driver", - nm_device_get_iface (NM_DEVICE (self))); + _LOGW (LOGD_HW | LOGD_OLPC, "failed to initialize WiFi driver"); g_object_unref (object); return NULL; } @@ -562,24 +539,20 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_COMPANION, - g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, - "Companion device", - "Companion device object path", + g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVE_CHANNEL, - g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, - "Active channel", - "Active channel", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_olpc_mesh_object_info); - - dbus_g_error_domain_register (NM_OLPC_MESH_ERROR, NULL, NM_TYPE_OLPC_MESH_ERROR); } diff --git a/src/devices/wifi/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h index c25dd8e5..67d83fb0 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.h +++ b/src/devices/wifi/nm-device-olpc-mesh.h @@ -25,11 +25,10 @@ * (C) Copyright 2009 One Laptop per Child */ -#ifndef NM_DEVICE_OLPC_MESH_H -#define NM_DEVICE_OLPC_MESH_H +#ifndef __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ +#define __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ #include <glib-object.h> -#include <dbus/dbus.h> #include "nm-device.h" @@ -42,13 +41,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OLPC_MESH)) #define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) -typedef enum -{ - NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH = 0, /*< nick=ConnectionNotMesh >*/ - NM_OLPC_MESH_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMOlpcMeshError; - #define NM_DEVICE_OLPC_MESH_COMPANION "companion" #define NM_DEVICE_OLPC_MESH_BITRATE "bitrate" #define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel" diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 95173cf4..dd7754b3 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -19,12 +19,13 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include <glib.h> #include <glib/gi18n.h> #include <dbus/dbus.h> #include <netinet/in.h> #include <string.h> -#include <net/ethernet.h> #include <sys/stat.h> #include <sys/wait.h> #include <signal.h> @@ -32,7 +33,6 @@ #include <linux/sockios.h> #include <linux/ethtool.h> #include <sys/ioctl.h> -#include <netinet/ether.h> #include <errno.h> #include "nm-glib-compat.h" @@ -52,9 +52,10 @@ #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" #include "nm-setting-ip4-config.h" +#include "nm-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-platform.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-settings-connection.h" #include "nm-enum-types.h" #include "nm-dbus-glib-types.h" @@ -76,6 +77,8 @@ static void impl_device_request_scan (NMDeviceWifi *device, #include "nm-device-wifi-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceWifi); /* All of these are in seconds */ #define SCAN_INTERVAL_MIN 3 @@ -115,8 +118,8 @@ static guint signals[LAST_SIGNAL] = { 0 }; struct _NMDeviceWifiPrivate { gboolean disposed; - guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ - guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ + char * perm_hw_addr; /* Permanent MAC address */ + char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */ gint8 invalid_strength_counter; @@ -192,19 +195,6 @@ static void remove_supplicant_interface_error_handler (NMDeviceWifi *self); /*****************************************************************/ -#define NM_WIFI_ERROR (nm_wifi_error_quark ()) - -static GQuark -nm_wifi_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-wifi-error"); - return quark; -} - -/*****************************************************************/ - static GObject* constructor (GType type, guint n_construct_params, @@ -223,22 +213,15 @@ constructor (GType type, self = NM_DEVICE_WIFI (object); priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_dbg (LOGD_HW | LOGD_WIFI, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &priv->capabilities)) { - nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s): failed to initialize WiFi driver", - nm_device_get_iface (NM_DEVICE (self))); + _LOGW (LOGD_HW | LOGD_WIFI, "failed to initialize WiFi driver"); g_object_unref (object); return NULL; } - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) { - nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver supports Access Point (AP) mode", - nm_device_get_iface (NM_DEVICE (self))); - } + if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + _LOGI (LOGD_HW | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ priv->sup_mgr = nm_supplicant_manager_get (); @@ -260,13 +243,12 @@ supplicant_interface_acquire (NMDeviceWifi *self) nm_device_get_iface (NM_DEVICE (self)), TRUE); if (priv->sup_iface == NULL) { - nm_log_err (LOGD_WIFI, "Couldn't initialize supplicant interface for %s.", - nm_device_get_iface (NM_DEVICE (self))); + _LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface"); return FALSE; } if (nm_supplicant_interface_get_state (priv->sup_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY) - nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", TRUE); + nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", FALSE); g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_STATE, @@ -309,9 +291,8 @@ supplicant_interface_release (NMDeviceWifi *self) /* Reset the scan interval to be pretty frequent when disconnected */ priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP; - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): reset scanning interval to %d seconds", - nm_device_get_iface (NM_DEVICE (self)), - priv->scan_interval); + _LOGD (LOGD_WIFI_SCAN, "reset scanning interval to %d seconds", + priv->scan_interval); if (priv->scanlist_cull_id) { g_source_remove (priv->scanlist_cull_id); @@ -370,9 +351,8 @@ find_active_ap (NMDeviceWifi *self, gboolean match_hidden) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - struct ether_addr bssid; + guint8 bssid[ETH_ALEN]; GByteArray *ssid; GSList *iter; int i = 0; @@ -382,22 +362,18 @@ find_active_ap (NMDeviceWifi *self, NM80211Mode devmode; guint32 devfreq; - nm_platform_wifi_get_bssid (ifindex, &bssid); - nm_log_dbg (LOGD_WIFI, "(%s): active BSSID: %02x:%02x:%02x:%02x:%02x:%02x", - iface, - bssid.ether_addr_octet[0], bssid.ether_addr_octet[1], - bssid.ether_addr_octet[2], bssid.ether_addr_octet[3], - bssid.ether_addr_octet[4], bssid.ether_addr_octet[5]); + nm_platform_wifi_get_bssid (ifindex, bssid); + _LOGD (LOGD_WIFI, "active BSSID: %02x:%02x:%02x:%02x:%02x:%02x", + bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - if (!nm_ethernet_address_is_valid (&bssid)) + if (!nm_ethernet_address_is_valid (bssid, ETH_ALEN)) return NULL; ssid = nm_platform_wifi_get_ssid (ifindex); - nm_log_dbg (LOGD_WIFI, "(%s): active SSID: %s%s%s", - iface, - ssid ? "'" : "", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - ssid ? "'" : ""); + _LOGD (LOGD_WIFI, "active SSID: %s%s%s", + ssid ? "'" : "", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + ssid ? "'" : ""); devmode = nm_platform_wifi_get_mode (ifindex); devfreq = nm_platform_wifi_get_frequency (ifindex); @@ -407,50 +383,54 @@ find_active_ap (NMDeviceWifi *self, * and therefore it won't get matched the first time around. */ while (i++ < (match_hidden ? 2 : 1)) { - nm_log_dbg (LOGD_WIFI, " Pass #%d %s", i, i > 1 ? "(ignoring SSID)" : ""); + _LOGD (LOGD_WIFI, " Pass #%d %s", i, i > 1 ? "(ignoring SSID)" : ""); /* Find this SSID + BSSID in the device's AP list */ for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { NMAccessPoint *ap = NM_AP (iter->data); - const struct ether_addr *ap_bssid = nm_ap_get_address (ap); + const char *ap_bssid = nm_ap_get_address (ap); const GByteArray *ap_ssid = nm_ap_get_ssid (ap); NM80211Mode apmode; guint32 apfreq; - nm_log_dbg (LOGD_WIFI, " AP: %s%s%s %02x:%02x:%02x:%02x:%02x:%02x", - ap_ssid ? "'" : "", - ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", - ap_ssid ? "'" : "", - ap_bssid->ether_addr_octet[0], ap_bssid->ether_addr_octet[1], - ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], - ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); + _LOGD (LOGD_WIFI, " AP: %s%s%s %s", + ap_ssid ? "'" : "", + ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", + ap_ssid ? "'" : "", + str_if_set (ap_bssid, "(none)")); if (ap == ignore_ap) { - nm_log_dbg (LOGD_WIFI, " ignored"); + _LOGD (LOGD_WIFI, " ignored"); continue; } - if (memcmp (bssid.ether_addr_octet, ap_bssid->ether_addr_octet, ETH_ALEN)) { - nm_log_dbg (LOGD_WIFI, " BSSID mismatch"); + if (!nm_utils_hwaddr_matches (bssid, ETH_ALEN, ap_bssid, -1)) { + _LOGD (LOGD_WIFI, " BSSID mismatch"); continue; } - if ((i == 0) && !nm_utils_same_ssid (ssid, ap_ssid, TRUE)) { - nm_log_dbg (LOGD_WIFI, " SSID mismatch"); - continue; + if (i == 0) { + if ( (ssid && !ap_ssid) + || (ap_ssid && !ssid) + || (ssid && ap_ssid && !nm_utils_same_ssid (ssid->data, ssid->len, + ap_ssid->data, ap_ssid->len, + TRUE))) { + _LOGD (LOGD_WIFI, " SSID mismatch"); + continue; + } } apmode = nm_ap_get_mode (ap); if (devmode != apmode) { - nm_log_dbg (LOGD_WIFI, " mode mismatch (device %d, ap %d)", - devmode, apmode); + _LOGD (LOGD_WIFI, " mode mismatch (device %d, ap %d)", + devmode, apmode); continue; } apfreq = nm_ap_get_freq (ap); if (devfreq != apfreq) { - nm_log_dbg (LOGD_WIFI, " frequency mismatch (device %u, ap %u)", - devfreq, apfreq); + _LOGD (LOGD_WIFI, " frequency mismatch (device %u, ap %u)", + devfreq, apfreq); if (match_nofreq == NULL) match_nofreq = ap; @@ -463,7 +443,7 @@ find_active_ap (NMDeviceWifi *self, } // FIXME: handle security settings here too - nm_log_dbg (LOGD_WIFI, " matched"); + _LOGD (LOGD_WIFI, " matched"); active_ap = ap; goto done; } @@ -482,22 +462,19 @@ find_active_ap (NMDeviceWifi *self, * we can't match the AP based on frequency at all, just give up. */ if (match_nofreq && ((found_a_band != found_bg_band) || (devfreq == 0))) { - const struct ether_addr *ap_bssid = nm_ap_get_address (match_nofreq); const GByteArray *ap_ssid = nm_ap_get_ssid (match_nofreq); - nm_log_dbg (LOGD_WIFI, " matched %s%s%s %02x:%02x:%02x:%02x:%02x:%02x", - ap_ssid ? "'" : "", - ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", - ap_ssid ? "'" : "", - ap_bssid->ether_addr_octet[0], ap_bssid->ether_addr_octet[1], - ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], - ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); + _LOGD (LOGD_WIFI, " matched %s%s%s %s", + ap_ssid ? "'" : "", + ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", + ap_ssid ? "'" : "", + str_if_set (nm_ap_get_address (match_nofreq), "(none)")); active_ap = match_nofreq; goto done; } - nm_log_dbg (LOGD_WIFI, " No matching AP found."); + _LOGD (LOGD_WIFI, " No matching AP found."); done: if (ssid) @@ -612,15 +589,17 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) * current AP with it, if the current AP is adhoc. */ if (priv->current_ap && (nm_ap_get_mode (priv->current_ap) == NM_802_11_MODE_ADHOC)) { - struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; + guint8 bssid[ETH_ALEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; - nm_platform_wifi_get_bssid (ifindex, &bssid); + nm_platform_wifi_get_bssid (ifindex, bssid); /* 0x02 means "locally administered" and should be OR-ed into * the first byte of IBSS BSSIDs. */ - if ( (bssid.ether_addr_octet[0] & 0x02) - && nm_ethernet_address_is_valid (&bssid)) - nm_ap_set_address (priv->current_ap, &bssid); + if ((bssid[0] & 0x02) && nm_ethernet_address_is_valid (bssid, ETH_ALEN)) { + char *bssid_str = nm_utils_hwaddr_ntoa (bssid, ETH_ALEN); + nm_ap_set_address (priv->current_ap, bssid_str); + g_free (bssid_str); + } } new_ap = find_active_ap (self, ignore_ap, FALSE); @@ -636,32 +615,26 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) } if (new_ap != priv->current_ap) { - const struct ether_addr *new_bssid = NULL; + const char *new_bssid = NULL; const GByteArray *new_ssid = NULL; - const struct ether_addr *old_bssid = NULL; + const char *old_bssid = NULL; const GByteArray *old_ssid = NULL; - char *old_addr = NULL, *new_addr = NULL; if (new_ap) { new_bssid = nm_ap_get_address (new_ap); - new_addr = nm_utils_hwaddr_ntoa (new_bssid, ARPHRD_ETHER); new_ssid = nm_ap_get_ssid (new_ap); } if (priv->current_ap) { old_bssid = nm_ap_get_address (priv->current_ap); - old_addr = nm_utils_hwaddr_ntoa (old_bssid, ARPHRD_ETHER); old_ssid = nm_ap_get_ssid (priv->current_ap); } - nm_log_info (LOGD_WIFI, "(%s): roamed from BSSID %s (%s) to %s (%s)", - nm_device_get_iface (NM_DEVICE (self)), - old_addr ? old_addr : "(none)", - old_ssid ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)", - new_addr ? new_addr : "(none)", - new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)"); - g_free (old_addr); - g_free (new_addr); + _LOGI (LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", + old_bssid ? old_bssid : "(none)", + old_ssid ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)", + new_bssid ? new_bssid : "(none)", + new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)"); set_current_ap (self, new_ap, TRUE, FALSE); } @@ -734,15 +707,15 @@ remove_all_aps (NMDeviceWifi *self) } static void -deactivate (NMDevice *dev) +deactivate (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (dev); + int ifindex = nm_device_get_ifindex (device); NMConnection *connection; NM80211Mode old_mode = priv->mode; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); if (connection) { /* Clear wireless secrets tries when deactivating */ g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); @@ -768,7 +741,8 @@ deactivate (NMDevice *dev) nm_platform_wifi_indicate_addressing_running (ifindex, FALSE); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_WIFI); /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. @@ -828,8 +802,9 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingConnection *s_con; NMSettingWireless *s_wireless; - const GByteArray *mac; - const GSList *mac_blacklist, *mac_blacklist_iter; + const char *mac; + const char * const *mac_blacklist; + int i; const char *mode; if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection)) @@ -846,21 +821,18 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1)) return FALSE; /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { g_warn_if_reached (); - continue; + return FALSE; } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1)) return FALSE; } @@ -998,10 +970,12 @@ complete_connection (NMDevice *device, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - const GByteArray *setting_mac; - char *format, *str_ssid = NULL; + const char *setting_mac; + char *str_ssid = NULL; NMAccessPoint *ap = NULL; const GByteArray *ssid = NULL; + GByteArray *tmp_ssid = NULL; + GBytes *setting_ssid = NULL; GSList *iter; gboolean hidden = FALSE; @@ -1013,17 +987,17 @@ complete_connection (NMDevice *device, /* If not given a specific object, we need at minimum an SSID */ if (!s_wifi) { g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wireless' setting is required if no AP path was given."); return FALSE; } - ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!ssid || !ssid->len) { + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (!setting_ssid || g_bytes_get_size (setting_ssid) == 0) { g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wireless' setting with a valid SSID is required if no AP path was given."); return FALSE; } @@ -1041,17 +1015,7 @@ complete_connection (NMDevice *device, * if the network isn't broadcasting the SSID for example. */ if (!ap) { - GSList *settings = NULL; - gboolean valid; - - settings = g_slist_prepend (settings, s_wifi); - if (s_wsec) - settings = g_slist_prepend (settings, s_wsec); - if (s_8021x) - settings = g_slist_prepend (settings, s_8021x); - valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error); - g_slist_free (settings); - if (!valid) + if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) return FALSE; hidden = TRUE; @@ -1060,8 +1024,8 @@ complete_connection (NMDevice *device, ap = get_ap_by_path (self, specific_object); if (!ap) { g_set_error (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "The access point %s was not in the scan list.", specific_object); return FALSE; @@ -1074,37 +1038,48 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wifi)); } - if (ap) { + if (ap) ssid = nm_ap_get_ssid (ap); - - if (ssid == NULL) { - /* The AP must be hidden. Connecting to a WiFi AP requires the SSID - * as part of the initial handshake, so check the connection details - * for the SSID. The AP object will still be used for encryption - * settings and such. - */ - ssid = nm_setting_wireless_get_ssid (s_wifi); + if (ssid == NULL) { + /* The AP must be hidden. Connecting to a WiFi AP requires the SSID + * as part of the initial handshake, so check the connection details + * for the SSID. The AP object will still be used for encryption + * settings and such. + */ + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (setting_ssid) { + ssid = tmp_ssid = g_byte_array_new (); + g_byte_array_append (tmp_ssid, + g_bytes_get_data (setting_ssid, NULL), + g_bytes_get_size (setting_ssid)); } + } - if (ssid == NULL) { - /* If there's no SSID on the AP itself, and no SSID in the - * connection data, then we cannot connect at all. Return an error. - */ - g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, - "A 'wireless' setting with a valid SSID is required for hidden access points."); - return FALSE; - } + if (ssid == NULL) { + /* If there's no SSID on the AP itself, and no SSID in the + * connection data, then we cannot connect at all. Return an error. + */ + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + ap + ? "A 'wireless' setting with a valid SSID is required for hidden access points." + : "Cannot create 'wireless' setting due to missing SSID."); + return FALSE; + } + if (ap) { /* If the SSID is a well-known SSID, lock the connection to the AP's * specific BSSID so NM doesn't autoconnect to some random wifi net. */ if (!nm_ap_complete_connection (ap, connection, is_manf_default_ssid (ssid), - error)) + error)) { + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; + } } /* The kernel doesn't support Ad-Hoc WPA connections well at this time, @@ -1113,24 +1088,27 @@ complete_connection (NMDevice *device, */ if (is_adhoc_wpa (connection)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc disabled due to kernel bugs"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA Ad-Hoc disabled due to kernel bugs")); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; } - g_assert (ssid); - str_ssid = nm_utils_ssid_to_utf8 (ssid); - format = g_strdup_printf ("%s %%d", str_ssid); + str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); nm_utils_complete_generic (connection, NM_SETTING_WIRELESS_SETTING_NAME, existing_connections, - format, str_ssid, + str_ssid, + NULL, TRUE); g_free (str_ssid); - g_free (format); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -1138,26 +1116,26 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wireless_get_mac_address (s_wifi); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { - g_set_error (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRELESS_MAC_ADDRESS); + if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + guint8 perm_hw_addr[ETH_ALEN]; /* Lock the connection to this device by default if it uses a * permanent MAC address (ie not a 'locally administered' one) */ - if ( !(priv->perm_hw_addr[0] & 0x02) - && memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + nm_utils_hwaddr_aton (priv->perm_hw_addr, perm_hw_addr, ETH_ALEN); + if ( !(perm_hw_addr[0] & 0x02) + && !nm_utils_hwaddr_matches (perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) { + g_object_set (G_OBJECT (s_wifi), + NM_SETTING_WIRELESS_MAC_ADDRESS, priv->perm_hw_addr, + NULL); } } @@ -1165,31 +1143,26 @@ complete_connection (NMDevice *device, } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSupplicantInterface *sup_iface; guint32 state; if (!priv->enabled) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because not enabled", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because not enabled"); return FALSE; } - sup_iface = priv->sup_iface; - if (!sup_iface) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because supplicant not running", - nm_device_get_iface (dev)); + if (!priv->sup_iface) { + _LOGD (LOGD_WIFI, "not available because supplicant not running"); return FALSE; } - state = nm_supplicant_interface_get_state (sup_iface); + state = nm_supplicant_interface_get_state (priv->sup_iface); if ( state < NM_SUPPLICANT_INTERFACE_STATE_READY || state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because supplicant interface not ready", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because supplicant interface not ready"); return FALSE; } @@ -1197,17 +1170,17 @@ is_available (NMDevice *dev) } static gboolean -can_auto_connect (NMDevice *dev, +can_auto_connect (NMDevice *device, NMConnection *connection, char **specific_object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); GSList *ap_iter; const char *method = NULL; guint64 timestamp = 0; - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (dev, connection, specific_object)) + if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (device, connection, specific_object)) return FALSE; /* Don't autoconnect to networks that have been tried at least once @@ -1246,12 +1219,12 @@ ap_list_dump (NMDeviceWifi *self) g_return_if_fail (NM_IS_DEVICE_WIFI (self)); - nm_log_dbg (LOGD_WIFI_SCAN, "Current AP list:"); + _LOGD (LOGD_WIFI_SCAN, "Current AP list:"); for (elt = priv->ap_list; elt; elt = g_slist_next (elt), i++) { NMAccessPoint * ap = NM_AP (elt->data); nm_ap_dump (ap, "List AP: "); } - nm_log_dbg (LOGD_WIFI_SCAN, "Current AP list: done"); + _LOGD (LOGD_WIFI_SCAN, "Current AP list: done"); } static gboolean @@ -1301,8 +1274,8 @@ request_scan_cb (NMDevice *device, } if (!check_scanning_allowed (self)) { - local = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + local = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed at this time"); dbus_g_method_return_error (context, local); g_error_free (local); @@ -1328,23 +1301,23 @@ impl_device_request_scan (NMDeviceWifi *self, || !priv->sup_iface || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED || nm_device_is_activating (device)) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while unavailable or activating"); goto error; } if (nm_supplicant_interface_get_scanning (priv->sup_iface)) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while already scanning"); goto error; } last_scan = nm_supplicant_interface_get_last_scan_time (priv->sup_iface); if (last_scan && (nm_utils_get_monotonic_timestamp_s () - last_scan) < 10) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed immediately following previous scan"); goto error; } @@ -1413,7 +1386,6 @@ scanning_allowed (NMDeviceWifi *self) if (connection) { NMSettingWireless *s_wifi; const char *ip4_method = NULL; - const GByteArray *bssid; /* Don't scan when a shared connection is active; it makes drivers mad */ ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); @@ -1427,8 +1399,7 @@ scanning_allowed (NMDeviceWifi *self) */ s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - bssid = nm_setting_wireless_get_bssid (s_wifi); - if (bssid && bssid->len == ETH_ALEN) + if (nm_setting_wireless_get_bssid (s_wifi)) return FALSE; } @@ -1500,20 +1471,25 @@ build_hidden_probe_list (NMDeviceWifi *self) hidden_filter_func, NULL); if (connections && connections->data) { - ssids = g_ptr_array_sized_new (max_scan_ssids - 1); - g_ptr_array_add (ssids, nullssid); /* Add wildcard SSID */ + ssids = g_ptr_array_new_full (max_scan_ssids - 1, (GDestroyNotify) g_byte_array_unref); + g_ptr_array_add (ssids, g_byte_array_ref (nullssid)); /* Add wildcard SSID */ } for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *connection = iter->data; NMSettingWireless *s_wifi; - const GByteArray *ssid; + GBytes *ssid; + GByteArray *ssid_array; s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (connection); g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); g_assert (ssid); - g_ptr_array_add (ssids, (gpointer) ssid); + ssid_array = g_byte_array_new (); + g_byte_array_append (ssid_array, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + g_ptr_array_add (ssids, ssid_array); } g_slist_free (connections); @@ -1534,27 +1510,25 @@ request_wireless_scan (gpointer user_data) } if (check_scanning_allowed (self)) { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scanning requested", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_WIFI_SCAN, "scanning requested"); ssids = build_hidden_probe_list (self); if (nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN)) { if (ssids) { + const GByteArray *ssid; guint i; char *foo; for (i = 0; i < ssids->len; i++) { - foo = nm_utils_ssid_to_utf8 (g_ptr_array_index (ssids, i)); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): (%d) probe scanning SSID '%s'", - nm_device_get_iface (NM_DEVICE (self)), + ssid = g_ptr_array_index (ssids, i); + foo = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); + _LOGD (LOGD_WIFI_SCAN, "(%d) probe scanning SSID '%s'", i, foo ? foo : "<hidden>"); g_free (foo); } - } else { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): no SSIDs to probe scan", - nm_device_get_iface (NM_DEVICE (self))); - } + } else + _LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan"); } if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) { @@ -1564,14 +1538,10 @@ request_wireless_scan (gpointer user_data) nm_device_add_pending_action (NM_DEVICE (self), "scan", TRUE); } - if (ssids) { - /* Elements owned by the connections, so we don't free them here */ - g_ptr_array_free (ssids, TRUE); - } - } else { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan requested but not allowed at this time", - nm_device_get_iface (NM_DEVICE (self))); - } + if (ssids) + g_ptr_array_unref (ssids); + } else + _LOGD (LOGD_WIFI_SCAN, "scan requested but not allowed at this time"); priv->pending_scan_id = 0; schedule_scan (self, backoff); @@ -1622,11 +1592,8 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff) priv->scan_interval = 5; } - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scheduled scan in %d seconds (interval now %d seconds)", - nm_device_get_iface (NM_DEVICE (self)), - next_scan, - priv->scan_interval); - + _LOGD (LOGD_WIFI_SCAN, "scheduled scan in %d seconds (interval now %d seconds)", + next_scan, priv->scan_interval); } } @@ -1649,9 +1616,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan %s", - nm_device_get_iface (NM_DEVICE (self)), - success ? "successful" : "failed"); + _LOGD (LOGD_WIFI_SCAN, "scan %s", success ? "successful" : "failed"); schedule_scan (self, success); @@ -1674,7 +1639,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, static void try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) { - const struct ether_addr *bssid; + const char *bssid; const GSList *connections, *iter; g_return_if_fail (nm_ap_get_ssid (ap) == NULL); @@ -1692,16 +1657,17 @@ try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) s_wifi = nm_connection_get_setting_wireless (connection); if (s_wifi) { if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid)) { - nm_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + GBytes *ssid = nm_setting_wireless_get_ssid (s_wifi); + + nm_ap_set_ssid (ap, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); break; } } } } -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] - /* * merge_scanned_ap * @@ -1721,7 +1687,7 @@ merge_scanned_ap (NMDeviceWifi *self, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMAccessPoint *found_ap = NULL; const GByteArray *ssid; - const struct ether_addr *bssid; + const char *bssid; gboolean strict_match = TRUE; /* Let the manager try to fill in the SSID from seen-bssids lists */ @@ -1734,16 +1700,13 @@ merge_scanned_ap (NMDeviceWifi *self, ssid = nm_ap_get_ssid (merge_ap); if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { /* Yay, matched it, no longer treat as hidden */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): matched hidden AP " MAC_FMT " => '%s'", - nm_device_get_iface (NM_DEVICE (self)), - MAC_ARG (bssid->ether_addr_octet), - nm_utils_escape_ssid (ssid->data, ssid->len)); + _LOGD (LOGD_WIFI_SCAN, "matched hidden AP %s => '%s'", + str_if_set (bssid, "(none)"), nm_utils_escape_ssid (ssid->data, ssid->len)); nm_ap_set_broadcast (merge_ap, FALSE); } else { /* Didn't have an entry for this AP in the database */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): failed to match hidden AP " MAC_FMT, - nm_device_get_iface (NM_DEVICE (self)), - MAC_ARG (bssid->ether_addr_octet)); + _LOGD (LOGD_WIFI_SCAN, "failed to match hidden AP %s", + str_if_set (bssid, "(none)")); } } @@ -1760,10 +1723,9 @@ merge_scanned_ap (NMDeviceWifi *self, if (!found_ap) found_ap = nm_ap_match_in_list (merge_ap, priv->ap_list, strict_match); if (found_ap) { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): merging AP '%s' " MAC_FMT " (%p) with existing (%p)", - nm_device_get_iface (NM_DEVICE (self)), + _LOGD (LOGD_WIFI_SCAN, "merging AP '%s' %s (%p) with existing (%p)", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - MAC_ARG (bssid->ether_addr_octet), + str_if_set (bssid, "(none)"), merge_ap, found_ap); @@ -1783,11 +1745,9 @@ merge_scanned_ap (NMDeviceWifi *self, nm_ap_set_fake (found_ap, FALSE); } else { /* New entry in the list */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): adding new AP '%s' " MAC_FMT " (%p)", - nm_device_get_iface (NM_DEVICE (self)), - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - MAC_ARG (bssid->ether_addr_octet), - merge_ap); + _LOGD (LOGD_WIFI_SCAN, "adding new AP '%s' %s (%p)", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + str_if_set (bssid, "(none)"), merge_ap); g_object_ref (merge_ap); priv->ap_list = g_slist_prepend (priv->ap_list, merge_ap); @@ -1809,8 +1769,7 @@ cull_scan_list (NMDeviceWifi *self) priv->scanlist_cull_id = 0; - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): checking scan list for outdated APs", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_WIFI_SCAN, "checking scan list for outdated APs"); /* Walk the access point list and remove any access points older than * three times the inactive scan interval. @@ -1844,28 +1803,23 @@ cull_scan_list (NMDeviceWifi *self) /* Remove outdated APs */ for (elt = outdated_list; elt; elt = g_slist_next (elt)) { NMAccessPoint *outdated_ap = NM_AP (elt->data); - const struct ether_addr *bssid; const GByteArray *ssid; - bssid = nm_ap_get_address (outdated_ap); ssid = nm_ap_get_ssid (outdated_ap); - nm_log_dbg (LOGD_WIFI_SCAN, - " removing %02x:%02x:%02x:%02x:%02x:%02x (%s%s%s)", - bssid->ether_addr_octet[0], bssid->ether_addr_octet[1], - bssid->ether_addr_octet[2], bssid->ether_addr_octet[3], - bssid->ether_addr_octet[4], bssid->ether_addr_octet[5], - ssid ? "'" : "", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - ssid ? "'" : ""); + _LOGD (LOGD_WIFI_SCAN, + " removing %s (%s%s%s)", + str_if_set (nm_ap_get_address (outdated_ap), "(none)"), + ssid ? "'" : "", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + ssid ? "'" : ""); remove_access_point (self, outdated_ap); removed++; } g_slist_free (outdated_list); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): removed %d APs (of %d)", - nm_device_get_iface (NM_DEVICE (self)), - removed, total); + _LOGD (LOGD_WIFI_SCAN, "removed %d APs (of %d)", + removed, total); ap_list_dump (self); @@ -1913,10 +1867,8 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, /* Add the AP to the device's AP list */ merge_scanned_ap (self, ap); g_object_unref (ap); - } else { - nm_log_warn (LOGD_WIFI_SCAN, "(%s): invalid AP properties received", - nm_device_get_iface (NM_DEVICE (self))); - } + } else + _LOGW (LOGD_WIFI_SCAN, "invalid AP properties received"); /* Remove outdated access points */ schedule_scanlist_cull (self); @@ -1998,19 +1950,20 @@ wifi_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); - g_return_if_fail (req == nm_device_get_act_request (dev)); - g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail (req == nm_device_get_act_request (device)); + g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); g_return_if_fail (nm_act_request_get_connection (req) == connection); if (error) { - nm_log_warn (LOGD_WIFI, "%s", error->message); - nm_device_state_changed (dev, + _LOGW (LOGD_WIFI, "%s", error->message); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); } else - nm_device_activate_schedule_stage1_device_prepare (dev); + nm_device_activate_schedule_stage1_device_prepare (device); } /* @@ -2022,11 +1975,11 @@ wifi_secrets_cb (NMActRequest *req, static gboolean link_timeout_cb (gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_warn (LOGD_WIFI, "(%s): link timed out.", nm_device_get_iface (dev)); + _LOGW (LOGD_WIFI, "link timed out."); priv->link_timeout_id = 0; @@ -2034,7 +1987,7 @@ link_timeout_cb (gpointer user_data) * to reassociate within the timeout period, so the connection must * fail. */ - if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED) + if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) return FALSE; /* If the access point failed, and wasn't found by the supplicant when it @@ -2045,7 +1998,7 @@ link_timeout_cb (gpointer user_data) if (priv->ssid_found == FALSE && priv->current_ap) set_current_ap (self, NULL, TRUE, TRUE); - nm_device_state_changed (dev, + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); @@ -2080,10 +2033,11 @@ need_new_8021x_secrets (NMDeviceWifi *self, s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) { - nm_setting_get_secret_flags (NM_SETTING (s_8021x), - NM_SETTING_802_1X_PASSWORD, - &secret_flags, - NULL); + if (!nm_setting_get_secret_flags (NM_SETTING (s_8021x), + NM_SETTING_802_1X_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached (); if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) *setting_name = NM_SETTING_802_1X_SETTING_NAME; return *setting_name ? TRUE : FALSE; @@ -2091,10 +2045,11 @@ need_new_8021x_secrets (NMDeviceWifi *self, s_wsec = nm_connection_get_setting_wireless_security (connection); if (s_wsec) { - nm_setting_get_secret_flags (NM_SETTING (s_wsec), - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - &secret_flags, - NULL); + if (!nm_setting_get_secret_flags (NM_SETTING (s_wsec), + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached (); if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; return *setting_name ? TRUE : FALSE; @@ -2160,16 +2115,15 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): disconnected during association," - " asking for new key.", nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) disconnected during association, asking for new key"); cleanup_association_attempt (self, TRUE); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION - | NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wifi_secrets_cb, self); @@ -2195,11 +2149,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (new_state == old_state) return; - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "(%s): supplicant interface state: %s -> %s", - nm_device_get_iface (device), - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string (old_state), + nm_supplicant_interface_state_to_string (new_state)); devstate = nm_device_get_state (device); scanning = nm_supplicant_interface_get_scanning (iface); @@ -2222,9 +2175,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE); } - nm_log_dbg (LOGD_WIFI_SCAN, - "(%s): supplicant ready, requesting initial scan", - nm_device_get_iface (device)); + _LOGD (LOGD_WIFI_SCAN, "supplicant ready, requesting initial scan"); /* Request a scan to get latest results */ cancel_pending_scan (self); @@ -2243,7 +2194,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (devstate == NM_DEVICE_STATE_CONFIG) { NMConnection *connection; NMSettingWireless *s_wifi; - const GByteArray *ssid; + GBytes *ssid; connection = nm_device_get_connection (NM_DEVICE (self)); g_return_if_fail (connection); @@ -2254,13 +2205,12 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, ssid = nm_setting_wireless_get_ssid (s_wifi); g_return_if_fail (ssid); - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless) Stage 2 of 5 (Device Configure) " - "successful. %s '%s'.", - nm_device_get_iface (device), - priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" : - "Connected to wireless network", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)"); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s '%s'.", + priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" : + "Connected to wireless network", + ssid ? nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)) : "(none)"); nm_device_activate_schedule_stage3_ip_config_start (device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update (self, NULL); @@ -2326,9 +2276,9 @@ supplicant_iface_connection_error_cb (NMSupplicantInterface *iface, NMDevice *device = NM_DEVICE (self); if (nm_device_is_activating (device)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): supplicant association failed: %s - %s", - nm_device_get_iface (device), name, message); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) supplicant association failed: %s - %s", + name, message); cleanup_association_attempt (self, TRUE); nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); @@ -2356,9 +2306,7 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface, gboolean scanning; scanning = nm_supplicant_interface_get_scanning (iface); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): now %s", - nm_device_get_iface (NM_DEVICE (self)), - scanning ? "scanning" : "idle"); + _LOGD (LOGD_WIFI_SCAN, "now %s", scanning ? "scanning" : "idle"); g_object_notify (G_OBJECT (self), "scanning"); @@ -2397,16 +2345,16 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (new_secrets) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else - nm_log_warn (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + _LOGW (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); return ret; } @@ -2420,7 +2368,7 @@ handle_auth_or_fail (NMDeviceWifi *self, static gboolean supplicant_connection_timeout_cb (gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE (user_data); NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActRequest *req; @@ -2428,7 +2376,7 @@ supplicant_connection_timeout_cb (gpointer user_data) cleanup_association_attempt (self, TRUE); - if (!nm_device_is_activating (dev)) + if (!nm_device_is_activating (device)) return FALSE; /* Timed out waiting for a successful connection to the AP; if the AP's @@ -2437,7 +2385,7 @@ supplicant_connection_timeout_cb (gpointer user_data) * information (passwords, pin codes, etc) are wrong. */ - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); connection = nm_act_request_get_connection (req); @@ -2449,12 +2397,10 @@ supplicant_connection_timeout_cb (gpointer user_data) * (if any), so supplicant timeouts here are almost certainly the wifi * driver being really stupid. */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): %s network creation took " - "too long, failing activation.", - nm_device_get_iface (dev), - priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) %s network creation took too long, failing activation", + priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); return FALSE; } @@ -2468,9 +2414,8 @@ supplicant_connection_timeout_cb (gpointer user_data) /* Connection failed; either driver problems, the encryption key is * wrong, or the passwords or certificates were wrong. */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): association took too long.", - nm_device_get_iface (dev)); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) association took too long"); /* Ask for new secrets only if we've never activated this connection * before. If we've connected before, don't bother the user with @@ -2480,20 +2425,16 @@ supplicant_connection_timeout_cb (gpointer user_data) if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) new_secrets = !timestamp; - if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): asking for new secrets", - nm_device_get_iface (dev)); - } else { - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) + _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) asking for new secrets"); + else { + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); } } else { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): association took too long, " - "failing activation.", - nm_device_get_iface (dev)); - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) association took too long, failing activation"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); } @@ -2523,13 +2464,13 @@ build_supplicant_config (NMDeviceWifi *self, /* Warn if AP mode may not be supported */ if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0 && nm_supplicant_interface_get_ap_support (priv->sup_iface) == AP_SUPPORT_UNKNOWN) { - nm_log_warn (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); + _LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); } if (!nm_supplicant_config_add_setting_wireless (config, s_wireless, fixed_freq)) { - nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); goto error; } @@ -2544,13 +2485,12 @@ build_supplicant_config (NMDeviceWifi *self, s_wireless_sec, s_8021x, con_uuid)) { - nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to " - "supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to supplicant config."); goto error; } } else { if (!nm_supplicant_config_add_no_security (config)) { - nm_log_err (LOGD_WIFI, "Couldn't add unsecured option to supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add unsecured option to supplicant config."); goto error; } } @@ -2565,23 +2505,25 @@ error: /****************************************************************************/ static void -update_permanent_hw_address (NMDevice *dev) +update_permanent_hw_address (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); struct ifreq req; struct ethtool_perm_addr *epaddr = NULL; - int fd, ret; + int fd, ret, errsv; + + g_return_if_fail (priv->perm_hw_addr == NULL); fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_err (LOGD_HW, "could not open control socket."); + _LOGE (LOGD_HW, "could not open control socket."); return; } /* Get permanent MAC address */ memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); + strncpy (req.ifr_name, nm_device_get_iface (device), IFNAMSIZ); epaddr = g_malloc0 (sizeof (struct ethtool_perm_addr) + ETH_ALEN); epaddr->cmd = ETHTOOL_GPERMADDR; @@ -2590,56 +2532,50 @@ update_permanent_hw_address (NMDevice *dev) errno = 0; ret = ioctl (fd, SIOCETHTOOL, &req); - if ((ret < 0) || !nm_ethernet_address_is_valid ((struct ether_addr *) epaddr->data)) { - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", - nm_device_get_iface (dev), errno); + errsv = errno; + if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) { + _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)", + errsv); /* Fall back to current address */ - memcpy (epaddr->data, nm_device_get_hw_address (dev, NULL), ETH_ALEN); + nm_utils_hwaddr_aton (nm_device_get_hw_address (device), epaddr->data, ETH_ALEN); } - if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { - memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN); - g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); - } + priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN); g_free (epaddr); close (fd); } static void -update_initial_hw_address (NMDevice *dev) +update_initial_hw_address (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - char *mac_str; /* This sets initial MAC address from current MAC address. It should only * be called from NMDevice constructor() to really get the initial address. */ - memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (device)); - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr); } static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActStageReturn ret; NMAccessPoint *ap = NULL; NMActRequest *req; NMConnection *connection; NMSettingWireless *s_wireless; - const GByteArray *cloned_mac; + const char *cloned_mac; GSList *iter; const char *mode; const char *ap_path; - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; @@ -2670,15 +2606,15 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. */ if (is_adhoc_wpa (connection)) { - nm_log_warn (LOGD_WIFI, "Ad-Hoc WPA disabled due to kernel bugs"); + _LOGW (LOGD_WIFI, "Ad-Hoc WPA disabled due to kernel bugs"); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } /* Set spoof MAC to the interface */ cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_WIFI); + if (cloned_mac) + nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_WIFI); /* AP mode never uses a specific object or existing scanned AP */ if (priv->mode != NM_802_11_MODE_AP) { @@ -2716,7 +2652,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) nm_ap_set_broadcast (ap, FALSE); else if (nm_ap_is_hotspot (ap)) - nm_ap_set_address (ap, (const struct ether_addr *) nm_device_get_hw_address (dev, NULL)); + nm_ap_set_address (ap, nm_device_get_hw_address (device)); priv->ap_list = g_slist_prepend (priv->ap_list, ap); nm_ap_export_to_dbus (ap); @@ -2759,12 +2695,11 @@ ensure_hotspot_frequency (NMDeviceWifi *self, } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - const char *iface = nm_device_get_iface (dev); NMSupplicantConfig *config = NULL; NMActRequest *req; NMAccessPoint *ap; @@ -2776,7 +2711,7 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) remove_supplicant_timeouts (self); - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); ap = priv->current_ap; @@ -2794,10 +2729,9 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): access point '%s' has security," - " but secrets are required.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) access point '%s' has security, but secrets are required.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, req, FALSE); if (ret == NM_ACT_STAGE_RETURN_FAILURE) @@ -2807,15 +2741,13 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* have secrets, or no secrets required */ if (nm_connection_get_setting_wireless_security (connection)) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): connection '%s' has security" - ", and secrets exist. No new secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' has security, and secrets exist. No new secrets needed.", + nm_connection_get_id (connection)); } else { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): connection '%s' requires no " - "security. No secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id (connection)); } priv->ssid_found = FALSE; @@ -2830,9 +2762,8 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* Build up the supplicant configuration */ config = build_supplicant_config (self, connection, nm_ap_get_freq (ap)); if (config == NULL) { - nm_log_err (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): couldn't build wireless configuration.", - iface); + _LOGE (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) couldn't build wireless configuration."); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; goto out; } @@ -2844,9 +2775,8 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) self); if (!nm_supplicant_interface_set_config (priv->sup_iface, config)) { - nm_log_err (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): couldn't send wireless " - "configuration to the supplicant.", iface); + _LOGE (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) couldn't send wireless configuration to the supplicant."); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; goto out; } @@ -2879,14 +2809,14 @@ act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; const char *method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; connection = nm_device_get_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); /* Indicate that a critical protocol is about to start */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) @@ -2901,14 +2831,14 @@ act_stage3_ip6_config_start (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; const char *method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; connection = nm_device_get_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - method = nm_setting_ip6_config_get_method (s_ip6); + method = nm_setting_ip_config_get_method (s_ip6); /* Indicate that a critical protocol is about to start */ if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 || @@ -2933,7 +2863,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) /* MTU override */ mtu = nm_setting_wireless_get_mtu (s_wifi); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static gboolean @@ -2984,17 +2914,14 @@ handle_ip_config_timeout (NMDeviceWifi *self, */ if (!may_fail && is_static_wep (connection)) { /* Activation failed, we must have bad encryption key */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): could not get IP configuration for " - "connection '%s'.", - nm_device_get_iface (NM_DEVICE (self)), - nm_connection_get_id (connection)); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) could not get IP configuration for connection '%s'.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, NULL, TRUE); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): asking for new secrets", - nm_device_get_iface (NM_DEVICE (self))); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) asking for new secrets"); } else { *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } @@ -3008,60 +2935,60 @@ handle_ip_config_timeout (NMDeviceWifi *self, static NMActStageReturn -act_stage4_ip4_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) +act_stage4_ip4_config_timeout (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); - may_fail = nm_setting_ip4_config_get_may_fail (s_ip4); + may_fail = nm_setting_ip_config_get_may_fail (s_ip4); - ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); + ret = handle_ip_config_timeout (NM_DEVICE_WIFI (device), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (device, reason); return ret; } static NMActStageReturn -act_stage4_ip6_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) +act_stage4_ip6_config_timeout (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); - may_fail = nm_setting_ip6_config_get_may_fail (s_ip6); + may_fail = nm_setting_ip_config_get_may_fail (s_ip6); - ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); + ret = handle_ip_config_timeout (NM_DEVICE_WIFI (device), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (device, reason); return ret; } static void -activation_success_handler (NMDevice *dev) +activation_success_handler (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (dev); + int ifindex = nm_device_get_ifindex (device); NMAccessPoint *ap; - struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; + guint8 bssid[ETH_ALEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; NMAccessPoint *tmp_ap = NULL; NMActRequest *req; NMConnection *connection; - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); connection = nm_act_request_get_connection (req); @@ -3087,9 +3014,12 @@ activation_success_handler (NMDevice *dev) * But if activation was successful, the card will know the BSSID. Grab * the BSSID off the card and fill in the BSSID of the activation AP. */ - nm_platform_wifi_get_bssid (ifindex, &bssid); - if (!nm_ethernet_address_is_valid (nm_ap_get_address (ap))) - nm_ap_set_address (ap, &bssid); + nm_platform_wifi_get_bssid (ifindex, bssid); + if (!nm_ap_get_address (ap)) { + char *bssid_str = nm_utils_hwaddr_ntoa (bssid, ETH_ALEN); + nm_ap_set_address (ap, bssid_str); + g_free (bssid_str); + } if (!nm_ap_get_freq (ap)) nm_ap_set_freq (ap, nm_platform_wifi_get_frequency (ifindex)); if (!nm_ap_get_max_bitrate (ap)) @@ -3103,9 +3033,11 @@ activation_success_handler (NMDevice *dev) * instead. */ - /* If the better match was a hidden AP, update it's SSID */ - if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) - nm_ap_set_ssid (tmp_ap, nm_ap_get_ssid (ap)); + /* If the better match was a hidden AP, update its SSID */ + if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { + ssid = nm_ap_get_ssid (ap); + nm_ap_set_ssid (tmp_ap, ssid->data, ssid->len); + } nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (tmp_ap)); @@ -3130,18 +3062,18 @@ done: } static void -activation_failure_handler (NMDevice *dev) +activation_failure_handler (NMDevice *device) { NMConnection *connection; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); /* Clear wireless secrets tries on failure */ g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_ifindex (dev), FALSE); + nm_platform_wifi_indicate_addressing_running (nm_device_get_ifindex (device), FALSE); } static void @@ -3225,15 +3157,12 @@ set_enabled (NMDevice *device, gboolean enabled) priv->enabled = enabled; - nm_log_dbg (LOGD_WIFI, "(%s): device now %s", - nm_device_get_iface (NM_DEVICE (device)), - enabled ? "enabled" : "disabled"); + _LOGD (LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); state = nm_device_get_state (NM_DEVICE (self)); if (state < NM_DEVICE_STATE_UNAVAILABLE) { - nm_log_dbg (LOGD_WIFI, "(%s): %s blocked by UNMANAGED state", - enabled ? "enable" : "disable", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "(%s): device blocked by UNMANAGED state", + enabled ? "enable" : "disable"); return; } @@ -3241,11 +3170,10 @@ set_enabled (NMDevice *device, gboolean enabled) gboolean no_firmware = FALSE; if (state != NM_DEVICE_STATE_UNAVAILABLE) - nm_log_warn (LOGD_CORE, "not in expected unavailable state!"); + _LOGW (LOGD_CORE, "not in expected unavailable state!"); if (!nm_device_bring_up (NM_DEVICE (self), TRUE, &no_firmware)) { - nm_log_dbg (LOGD_WIFI, "(%s): enable blocked by failure to bring device up", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "enable blocked by failure to bring device up"); if (no_firmware) nm_device_set_firmware_missing (NM_DEVICE (device), TRUE); @@ -3261,8 +3189,7 @@ set_enabled (NMDevice *device, gboolean enabled) supplicant_interface_release (self); supplicant_interface_acquire (self); - nm_log_dbg (LOGD_WIFI, "(%s): enable waiting on supplicant state", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "enable waiting on supplicant state"); } else { nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, @@ -3321,6 +3248,18 @@ dispose (GObject *object) } static void +finalize (GObject *object) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + g_free (priv->perm_hw_addr); + g_free (priv->initial_hw_addr); + + G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); +} + +static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { @@ -3331,7 +3270,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); + g_value_set_string (value, priv->perm_hw_addr); break; case PROP_MODE: g_value_set_uint (value, priv->mode); @@ -3387,6 +3326,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; + object_class->finalize = finalize; parent_class->bring_up = bring_up; parent_class->update_permanent_hw_address = update_permanent_hw_address; @@ -3413,57 +3353,56 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) klass->scanning_allowed = scanning_allowed; /* Properties */ - g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_DEVICE_WIFI_MODE, - "Mode", - "Mode", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_BITRATE, - g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, - "Bitrate", - "Bitrate", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_PERM_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_AP, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_BITRATE, + g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACCESS_POINTS, - g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, - "Access points", - "Access points", + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_ACTIVE_ACCESS_POINT, - g_param_spec_boxed (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, - "Active access point", - "Currently active access point", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, - "Wireless Capabilities", - "Wireless Capabilities", - 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_SCANNING, - g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, - "Scanning", - "Scanning", - FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_ACCESS_POINT, + g_param_spec_boxed (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_SCANNING, + g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[ACCESS_POINT_ADDED] = @@ -3495,8 +3434,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_wifi_object_info); - - dbus_g_error_domain_register (NM_WIFI_ERROR, NULL, NM_TYPE_WIFI_ERROR); } diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index f0a1beac..bcba91da 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -19,12 +19,10 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_WIFI_H -#define NM_DEVICE_WIFI_H +#ifndef __NETWORKMANAGER_DEVICE_WIFI_H__ +#define __NETWORKMANAGER_DEVICE_WIFI_H__ #include <glib-object.h> -#include <dbus/dbus.h> -#include <net/ethernet.h> #include "nm-device.h" #include "nm-wifi-ap.h" @@ -40,16 +38,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) #define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -typedef enum { - NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, /*< nick=ConnectionNotWireless >*/ - NM_WIFI_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, /*< nick=AccessPointNotFound >*/ - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, /*< nick=ScanNotAllowed >*/ - NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, /*< nick=ApModeUnsupported >*/ - NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, /*< nick=AdhocModeUnsupported >*/ -} NMWifiError; - #define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_WIFI_MODE "mode" #define NM_DEVICE_WIFI_BITRATE "bitrate" diff --git a/src/devices/wifi/nm-wifi-ap-utils.c b/src/devices/wifi/nm-wifi-ap-utils.c index 9b03cbd4..9ac7052e 100644 --- a/src/devices/wifi/nm-wifi-ap-utils.c +++ b/src/devices/wifi/nm-wifi-ap-utils.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*-*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,15 @@ * (C) Copyright 2011 Red Hat, Inc. */ -#include <config.h> +#include "config.h" + #include <string.h> #include <stdlib.h> +#include <glib/gi18n.h> + #include "nm-wifi-ap-utils.h" +#include "nm-utils.h" static gboolean verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -35,9 +39,10 @@ verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **erro || nm_setting_wireless_security_get_wep_key_type (s_wsec)) { /* Dynamic WEP cannot have any WEP keys set */ g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with static WEP keys", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("%s is incompatible with static WEP keys"), tag); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; } @@ -68,17 +73,21 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, /* LEAP authentication requires at least a LEAP username */ if (!leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, - "LEAP requires a LEAP username"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("LEAP authentication requires a LEAP username")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); return FALSE; } } else if (leap_username) { /* Leap username requires 'leap' auth */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "LEAP requires 'leap' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP username requires 'leap' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); return FALSE; } } @@ -87,9 +96,11 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) { /* LEAP requires ieee8021x key management */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, - "LEAP requires IEEE 802.1x key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP authentication requires IEEE 802.1x key management")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -105,9 +116,10 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (adhoc) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "LEAP incompatible with Ad-Hoc mode"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with Ad-Hoc mode")); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; } @@ -116,9 +128,10 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, - "LEAP incompatible with 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -137,17 +150,23 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s incompatible with any WPA key management", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot use WPA key management"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } if (nm_setting_wireless_security_get_num_protos (s_wsec)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s incompatible with any 'proto' setting", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA protocols"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); return FALSE; } @@ -158,9 +177,12 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, pw = nm_setting_wireless_security_get_pairwise (s_wsec, i); if (!strcmp (pw, "tkip") || !strcmp (pw, "ccmp")) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with WPA pairwise ciphers", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA ciphers"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } } @@ -172,18 +194,24 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, gr = nm_setting_wireless_security_get_group (s_wsec, i); if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with WPA group ciphers", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA ciphers"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); return FALSE; } } if (nm_setting_wireless_security_get_psk (s_wsec)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with a WPA Pre-Shared Key", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific a WPA password"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); return FALSE; } @@ -209,18 +237,21 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (!s_8021x) { /* 802.1x key management requires an 802.1x setting */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires an 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("Dynamic WEP requires an 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* 802.1x key management must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -231,9 +262,11 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (s_8021x) { /* 802.1x setting requires 802.1x key management */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'ieee8021x' key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'ieee8021x' key management")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -242,9 +275,11 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (auth_alg && strcmp (auth_alg, "open")) { /* 802.1x key management must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -274,18 +309,21 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-psk") || !strcmp (key_mgmt, "wpa-none")) { if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-PSK incompatible with 802.1x"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA-PSK authentication is incompatible with 802.1x")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* WPA must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-PSK requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-PSK requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } } @@ -293,9 +331,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-none")) { if (!adhoc) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires an Ad-Hoc mode AP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires an Ad-Hoc mode AP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); return FALSE; } @@ -304,9 +344,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_proto (s_wsec, 0) : NULL; if (n > 1 || !tmp || strcmp (tmp, "wpa")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'wpa' proto"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'wpa' protocol")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); return FALSE; } @@ -314,9 +356,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_pairwise (s_wsec, 0) : NULL; if (n > 1 || g_strcmp0 (tmp, "none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'none' pairwise cipher"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'none' pairwise cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } @@ -324,9 +368,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_group (s_wsec, 0) : NULL; if (n > 1 || !tmp || strcmp (tmp, "tkip")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'tkip' group cipher"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc requires 'tkip' group cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); return FALSE; } } @@ -336,9 +382,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP does not support PSK but setting requires it"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point does not support PSK but setting requires it")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -364,27 +412,31 @@ verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-eap")) { if (!s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-EAP requires an 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("WPA-EAP authentication requires an 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* WPA must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-EAP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-EAP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } is_wpa_eap = TRUE; } else if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Setting requires 802.1x but does not use 'wpa-eap' key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("802.1x setting requires 'wpa-eap' key management")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -394,9 +446,10 @@ verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP does not support 802.1x but setting requires it"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point does not support 802.1x but setting requires it")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -421,41 +474,50 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, if (adhoc) { if (key_mgmt && strcmp (key_mgmt, "wpa-none") && strcmp (key_mgmt, "none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP mode is Ad-Hoc but setting requires Infrastructure security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point mode is Ad-Hoc but setting requires Infrastructure security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode incompatible with 802.1x security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Ad-Hoc mode is incompatible with 802.1x security")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode incompatible with LEAP security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode is incompatible with LEAP security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } } else { if (key_mgmt && !strcmp (key_mgmt, "wpa-none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP mode is Infrastructure but setting requires Ad-Hoc security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point mode is Infrastructure but setting requires Ad-Hoc security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -465,7 +527,7 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, gboolean nm_ap_utils_complete_connection (const GByteArray *ap_ssid, - const guint8 ap_bssid[ETH_ALEN], + const char *bssid, NM80211Mode ap_mode, guint32 ap_flags, guint32 ap_wpa_flags, @@ -477,7 +539,7 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - const GByteArray *ssid; + GBytes *ssid, *ap_ssid_bytes; const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; @@ -487,26 +549,23 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, s_8021x = nm_connection_get_setting_802_1x (connection); /* Fill in missing SSID */ + ap_ssid_bytes = g_bytes_new (ap_ssid->data, ap_ssid->len); ssid = nm_setting_wireless_get_ssid (s_wifi); if (!ssid) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); - else if ( ssid->len != ap_ssid->len - || memcmp (ssid->data, ap_ssid->data, ssid->len)) { + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid_bytes, NULL); + else if (!g_bytes_equal (ssid, ap_ssid_bytes)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - "Setting SSID did not match AP SSID"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); + g_bytes_unref (ap_ssid_bytes); return FALSE; } + g_bytes_unref (ap_ssid_bytes); - if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) { - GByteArray *bssid; - - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, ap_bssid, ETH_ALEN); + if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - g_byte_array_free (bssid, TRUE); - } /* And mode */ mode = nm_setting_wireless_get_mode (s_wifi); @@ -526,9 +585,10 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, if (valid == FALSE) { g_set_error (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRELESS_MODE); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); return FALSE; } } else { @@ -549,9 +609,13 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, /* Make sure the connection doesn't specify security */ if (s_wsec || s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP is unencrypted but setting specifies security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point is unencrypted but setting specifies security")); + if (s_wsec) + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + else + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } return TRUE; @@ -634,18 +698,20 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, /* Ensure key management is valid for WPA */ if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA incompatible with non-EAP (original) LEAP or Dynamic WEP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic WEP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } /* 'shared' auth incompatible with any type of WPA */ if (auth_alg && strcmp (auth_alg, "open")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA incompatible with Shared Key authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with Shared Key authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -689,9 +755,9 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, */ } else { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Failed to determine AP security information"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Failed to determine AP security information")); return FALSE; } diff --git a/src/devices/wifi/nm-wifi-ap-utils.h b/src/devices/wifi/nm-wifi-ap-utils.h index 992b839d..31c12cd7 100644 --- a/src/devices/wifi/nm-wifi-ap-utils.h +++ b/src/devices/wifi/nm-wifi-ap-utils.h @@ -18,19 +18,18 @@ * (C) Copyright 2011 Red Hat, Inc. */ -#ifndef NM_WIFI_AP_UTILS_H -#define NM_WIFI_AP_UTILS_H +#ifndef __NETWORKMANAGER_WIFI_AP_UTILS_H__ +#define __NETWORKMANAGER_WIFI_AP_UTILS_H__ -#include <net/ethernet.h> -#include <NetworkManager.h> +#include <nm-dbus-interface.h> #include <nm-connection.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> #include <nm-setting-8021x.h> gboolean nm_ap_utils_complete_connection (const GByteArray *ssid, - const guint8 bssid[ETH_ALEN], + const char *bssid, NM80211Mode mode, guint32 flags, guint32 wpa_flags, diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 363be2e3..ee07cf40 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -19,9 +19,10 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include <string.h> #include <stdlib.h> -#include <netinet/ether.h> #include "nm-wifi-ap.h" #include "nm-wifi-ap-utils.h" @@ -45,7 +46,7 @@ typedef struct /* Scanned or cached values */ GByteArray * ssid; - struct ether_addr address; + char * address; NM80211Mode mode; gint8 strength; guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ @@ -102,6 +103,7 @@ finalize (GObject *object) g_free (priv->supplicant_path); if (priv->ssid) g_byte_array_free (priv->ssid, TRUE); + g_free (priv->address); G_OBJECT_CLASS (nm_ap_parent_class)->finalize (object); } @@ -111,6 +113,7 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMAccessPoint *ap = NM_AP (object); + GByteArray *ssid; switch (prop_id) { case PROP_FLAGS: @@ -123,7 +126,11 @@ set_property (GObject *object, guint prop_id, nm_ap_set_rsn_flags (ap, g_value_get_uint (value)); break; case PROP_SSID: - nm_ap_set_ssid (ap, (GByteArray *) g_value_get_boxed (value)); + ssid = g_value_get_boxed (value); + if (ssid) + nm_ap_set_ssid (ap, ssid->data, ssid->len); + else + nm_ap_set_ssid (ap, NULL, 0); break; case PROP_FREQUENCY: nm_ap_set_freq (ap, g_value_get_uint (value)); @@ -176,7 +183,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->freq); break; case PROP_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->address, ARPHRD_ETHER)); + g_value_set_string (value, priv->address); break; case PROP_MODE: g_value_set_uint (value, priv->mode); @@ -219,81 +226,72 @@ nm_ap_class_init (NMAccessPointClass *ap_class) /* properties */ g_object_class_install_property (object_class, PROP_FLAGS, - g_param_spec_uint (NM_AP_FLAGS, - "Flags", - "Flags", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_FLAGS_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_FLAGS, "", "", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WPA_FLAGS, - g_param_spec_uint (NM_AP_WPA_FLAGS, - "WPA Flags", - "WPA Flags", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_WPA_FLAGS, "", "", + NM_802_11_AP_SEC_NONE, + all_sec_flags, + NM_802_11_AP_SEC_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSN_FLAGS, - g_param_spec_uint (NM_AP_RSN_FLAGS, - "RSN Flags", - "RSN Flags", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_RSN_FLAGS, "", "", + NM_802_11_AP_SEC_NONE, + all_sec_flags, + NM_802_11_AP_SEC_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SSID, - g_param_spec_boxed (NM_AP_SSID, - "SSID", - "SSID", + g_param_spec_boxed (NM_AP_SSID, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FREQUENCY, - g_param_spec_uint (NM_AP_FREQUENCY, - "Frequency", - "Frequency", - 0, 10000, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_FREQUENCY, "", "", + 0, 10000, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_AP_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_string (NM_AP_HW_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_AP_MODE, - "Mode", - "Mode", - NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_MODE, "", "", + NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MAX_BITRATE, - g_param_spec_uint (NM_AP_MAX_BITRATE, - "Max Bitrate", - "Max Bitrate", - 0, G_MAXUINT16, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_MAX_BITRATE, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STRENGTH, - g_param_spec_char (NM_AP_STRENGTH, - "Strength", - "Strength", - G_MININT8, G_MAXINT8, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_char (NM_AP_STRENGTH, "", "", + G_MININT8, G_MAXINT8, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (ap_class), @@ -402,7 +400,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (!strcmp (key, "SSID")) { guint32 len = MIN (32, array->len); - GByteArray *ssid; /* Stupid ieee80211 layer uses <hidden> */ if (((len == 8) || (len == 9)) @@ -412,18 +409,15 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len)) return; - ssid = g_byte_array_sized_new (len); - g_byte_array_append (ssid, (const guint8 *) array->data, len); - nm_ap_set_ssid (ap, ssid); - g_byte_array_free (ssid, TRUE); + nm_ap_set_ssid (ap, (const guint8 *) array->data, len); } else if (!strcmp (key, "BSSID")) { - struct ether_addr addr; + char *addr; if (array->len != ETH_ALEN) return; - memset (&addr, 0, sizeof (struct ether_addr)); - memcpy (&addr, array->data, ETH_ALEN); - nm_ap_set_address (ap, &addr); + addr = nm_utils_hwaddr_ntoa (array->data, array->len); + nm_ap_set_address (ap, addr); + g_free (addr); } else if (!strcmp (key, "Rates")) { guint32 maxrate = 0; int i; @@ -483,7 +477,7 @@ NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties) { NMAccessPoint *ap; - const struct ether_addr * addr; + const char *addr; const char bad_bssid1[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const char bad_bssid2[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -498,8 +492,8 @@ nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties) /* ignore APs with invalid BSSIDs */ addr = nm_ap_get_address (ap); - if ( !(memcmp (addr->ether_addr_octet, bad_bssid1, ETH_ALEN)) - || !(memcmp (addr->ether_addr_octet, bad_bssid2, ETH_ALEN))) { + if ( nm_utils_hwaddr_matches (addr, -1, bad_bssid1, ETH_ALEN) + || nm_utils_hwaddr_matches (addr, -1, bad_bssid2, ETH_ALEN)) { g_object_unref (ap); return NULL; } @@ -597,7 +591,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection) NMAccessPoint *ap; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; - const GByteArray *ssid; + GBytes *ssid; const char *mode, *band, *key_mgmt; guint32 channel; NM80211ApSecurityFlags flags; @@ -610,11 +604,11 @@ nm_ap_new_fake_from_connection (NMConnection *connection) ssid = nm_setting_wireless_get_ssid (s_wireless); g_return_val_if_fail (ssid != NULL, NULL); - g_return_val_if_fail (ssid->len > 0, NULL); + g_return_val_if_fail (g_bytes_get_size (ssid) > 0, NULL); ap = nm_ap_new (); nm_ap_set_fake (ap, TRUE); - nm_ap_set_ssid (ap, ssid); + nm_ap_set_ssid (ap, g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); // FIXME: bssid too? @@ -720,10 +714,6 @@ error: return NULL; } - -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] - void nm_ap_dump (NMAccessPoint *ap, const char *prefix) { @@ -737,7 +727,7 @@ nm_ap_dump (NMAccessPoint *ap, const char *prefix) prefix, priv->ssid ? nm_utils_escape_ssid (priv->ssid->data, priv->ssid->len) : "(none)", ap); - nm_log_dbg (LOGD_WIFI_SCAN, " BSSID " MAC_FMT, MAC_ARG (priv->address.ether_addr_octet)); + nm_log_dbg (LOGD_WIFI_SCAN, " BSSID %s", str_if_set (priv->address, "(none)")); nm_log_dbg (LOGD_WIFI_SCAN, " mode %d", priv->mode); nm_log_dbg (LOGD_WIFI_SCAN, " flags 0x%X", priv->flags); nm_log_dbg (LOGD_WIFI_SCAN, " wpa flags 0x%X", priv->wpa_flags); @@ -786,20 +776,18 @@ const GByteArray * nm_ap_get_ssid (const NMAccessPoint *ap) } void -nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) +nm_ap_set_ssid (NMAccessPoint *ap, const guint8 *ssid, gsize len) { NMAccessPointPrivate *priv; g_return_if_fail (NM_IS_AP (ap)); + g_return_if_fail (ssid == NULL || len > 0); priv = NM_AP_GET_PRIVATE (ap); - if (ssid == priv->ssid) - return; - /* same SSID */ - if ((ssid && priv->ssid) && (ssid->len == priv->ssid->len)) { - if (!memcmp (ssid->data, priv->ssid->data, ssid->len)) + if ((ssid && priv->ssid) && (len == priv->ssid->len)) { + if (!memcmp (ssid, priv->ssid->data, len)) return; } @@ -809,14 +797,8 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) } if (ssid) { - /* Should never get zero-length SSIDs */ - g_warn_if_fail (ssid->len > 0); - - if (ssid->len) { - priv->ssid = g_byte_array_sized_new (ssid->len); - priv->ssid->len = ssid->len; - memcpy (priv->ssid->data, ssid->data, ssid->len); - } + priv->ssid = g_byte_array_new (); + g_byte_array_append (priv->ssid, ssid, len); } g_object_notify (G_OBJECT (ap), NM_AP_SSID); @@ -897,24 +879,28 @@ nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags) * Get/set functions for address * */ -const struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap) +const char * +nm_ap_get_address (const NMAccessPoint *ap) { g_return_val_if_fail (NM_IS_AP (ap), NULL); - return &NM_AP_GET_PRIVATE (ap)->address; + return NM_AP_GET_PRIVATE (ap)->address; } -void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr) +void +nm_ap_set_address (NMAccessPoint *ap, const char *addr) { NMAccessPointPrivate *priv; g_return_if_fail (NM_IS_AP (ap)); g_return_if_fail (addr != NULL); + g_return_if_fail (nm_utils_hwaddr_valid (addr, ETH_ALEN)); priv = NM_AP_GET_PRIVATE (ap); - if (memcmp (addr, &priv->address, sizeof (priv->address))) { - memcpy (&NM_AP_GET_PRIVATE (ap)->address, addr, sizeof (struct ether_addr)); + if (!priv->address || !nm_utils_hwaddr_matches (addr, -1, priv->address, -1)) { + g_free (priv->address); + priv->address = g_strdup (addr); g_object_notify (G_OBJECT (ap), NM_AP_HW_ADDRESS); } } @@ -1118,9 +1104,10 @@ nm_ap_check_compatible (NMAccessPoint *self, NMAccessPointPrivate *priv; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; + GBytes *ssid; const char *mode; const char *band; - const GByteArray *bssid; + const char *bssid; guint32 channel; g_return_val_if_fail (NM_IS_AP (self), FALSE); @@ -1132,11 +1119,19 @@ nm_ap_check_compatible (NMAccessPoint *self, if (s_wireless == NULL) return FALSE; - if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), priv->ssid, TRUE)) + ssid = nm_setting_wireless_get_ssid (s_wireless); + if ( (ssid && !priv->ssid) + || (priv->ssid && !ssid)) + return FALSE; + + if ( ssid && priv->ssid && + !nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + priv->ssid->data, priv->ssid->len, + TRUE)) return FALSE; bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid && memcmp (bssid->data, &priv->address, ETH_ALEN)) + if (bssid && (!priv->address || !nm_utils_hwaddr_matches (bssid, -1, priv->address, -1))) return FALSE; mode = nm_setting_wireless_get_mode (s_wireless); @@ -1190,7 +1185,7 @@ nm_ap_complete_connection (NMAccessPoint *self, g_return_val_if_fail (connection != NULL, FALSE); return nm_ap_utils_complete_connection (priv->ssid, - priv->address.ether_addr_octet, + priv->address, priv->mode, priv->flags, priv->wpa_flags, @@ -1233,27 +1228,29 @@ nm_ap_match_in_list (NMAccessPoint *find_ap, for (iter = ap_list; iter; iter = g_slist_next (iter)) { NMAccessPoint * list_ap = NM_AP (iter->data); const GByteArray * list_ssid = nm_ap_get_ssid (list_ap); - const struct ether_addr * list_addr = nm_ap_get_address (list_ap); + const char * list_addr = nm_ap_get_address (list_ap); const GByteArray * find_ssid = nm_ap_get_ssid (find_ap); - const struct ether_addr * find_addr = nm_ap_get_address (find_ap); + const char * find_addr = nm_ap_get_address (find_ap); /* SSID match; if both APs are hiding their SSIDs, * let matching continue on BSSID and other properties */ if ( (!list_ssid && find_ssid) - || (list_ssid && !find_ssid) - || !nm_utils_same_ssid (list_ssid, find_ssid, TRUE)) + || (list_ssid && !find_ssid)) + continue; + if ( list_ssid + && find_ssid + && !nm_utils_same_ssid (list_ssid->data, list_ssid->len, + find_ssid->data, find_ssid->len, + TRUE)) continue; /* BSSID match */ - if ( (strict_match || nm_ethernet_address_is_valid (find_addr)) - && nm_ethernet_address_is_valid (list_addr) - && memcmp (list_addr->ether_addr_octet, - find_addr->ether_addr_octet, - ETH_ALEN) != 0) { + if ( (strict_match || nm_ethernet_address_is_valid (find_addr, -1)) + && nm_ethernet_address_is_valid (list_addr, -1) + && !nm_utils_hwaddr_matches (list_addr, -1, find_addr, -1)) continue; - } /* mode match */ if (nm_ap_get_mode (list_ap) != nm_ap_get_mode (find_ap)) diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index f51fa078..0abb28fc 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -19,12 +19,12 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_ACCESS_POINT_H -#define NM_ACCESS_POINT_H +#ifndef __NETWORKMANAGER_ACCESS_POINT_H__ +#define __NETWORKMANAGER_ACCESS_POINT_H__ #include <glib.h> #include <glib-object.h> -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-connection.h" #define NM_TYPE_AP (nm_ap_get_type ()) @@ -60,62 +60,62 @@ NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path, NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection); void nm_ap_export_to_dbus (NMAccessPoint *ap); -const char * nm_ap_get_dbus_path (NMAccessPoint *ap); +const char *nm_ap_get_dbus_path (NMAccessPoint *ap); -const char * nm_ap_get_supplicant_path (NMAccessPoint *ap); -void nm_ap_set_supplicant_path (NMAccessPoint *ap, - const char *path); +const char *nm_ap_get_supplicant_path (NMAccessPoint *ap); +void nm_ap_set_supplicant_path (NMAccessPoint *ap, + const char *path); -const GByteArray * nm_ap_get_ssid (const NMAccessPoint * ap); -void nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid); +const GByteArray *nm_ap_get_ssid (const NMAccessPoint * ap); +void nm_ap_set_ssid (NMAccessPoint * ap, const guint8 * ssid, gsize len); -NM80211ApFlags nm_ap_get_flags (NMAccessPoint *ap); -void nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags); +NM80211ApFlags nm_ap_get_flags (NMAccessPoint *ap); +void nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags); NM80211ApSecurityFlags nm_ap_get_wpa_flags (NMAccessPoint *ap); void nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); -NM80211ApSecurityFlags nm_ap_get_rsn_flags (NMAccessPoint *ap); -void nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); +NM80211ApSecurityFlags nm_ap_get_rsn_flags (NMAccessPoint *ap); +void nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); -const struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap); -void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr *addr); +const char *nm_ap_get_address (const NMAccessPoint *ap); +void nm_ap_set_address (NMAccessPoint *ap, const char *addr); -NM80211Mode nm_ap_get_mode (NMAccessPoint *ap); -void nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode); +NM80211Mode nm_ap_get_mode (NMAccessPoint *ap); +void nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode); -gboolean nm_ap_is_hotspot (NMAccessPoint *ap); +gboolean nm_ap_is_hotspot (NMAccessPoint *ap); -gint8 nm_ap_get_strength (NMAccessPoint *ap); -void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength); +gint8 nm_ap_get_strength (NMAccessPoint *ap); +void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength); -guint32 nm_ap_get_freq (NMAccessPoint *ap); -void nm_ap_set_freq (NMAccessPoint *ap, guint32 freq); +guint32 nm_ap_get_freq (NMAccessPoint *ap); +void nm_ap_set_freq (NMAccessPoint *ap, guint32 freq); -guint32 nm_ap_get_max_bitrate (NMAccessPoint *ap); -void nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate); +guint32 nm_ap_get_max_bitrate (NMAccessPoint *ap); +void nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate); -gboolean nm_ap_get_fake (const NMAccessPoint *ap); -void nm_ap_set_fake (NMAccessPoint *ap, gboolean fake); +gboolean nm_ap_get_fake (const NMAccessPoint *ap); +void nm_ap_set_fake (NMAccessPoint *ap, gboolean fake); -gboolean nm_ap_get_broadcast (NMAccessPoint *ap); -void nm_ap_set_broadcast (NMAccessPoint *ap, gboolean broadcast); +gboolean nm_ap_get_broadcast (NMAccessPoint *ap); +void nm_ap_set_broadcast (NMAccessPoint *ap, gboolean broadcast); -gint32 nm_ap_get_last_seen (const NMAccessPoint *ap); -void nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen); +gint32 nm_ap_get_last_seen (const NMAccessPoint *ap); +void nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen); -gboolean nm_ap_check_compatible (NMAccessPoint *self, - NMConnection *connection); +gboolean nm_ap_check_compatible (NMAccessPoint *self, + NMConnection *connection); -gboolean nm_ap_complete_connection (NMAccessPoint *self, - NMConnection *connection, - gboolean lock_bssid, - GError **error); +gboolean nm_ap_complete_connection (NMAccessPoint *self, + NMConnection *connection, + gboolean lock_bssid, + GError **error); NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap, GSList *ap_list, gboolean strict_match); -void nm_ap_dump (NMAccessPoint *ap, const char *prefix); +void nm_ap_dump (NMAccessPoint *ap, const char *prefix); -#endif /* NM_ACCESS_POINT_H */ +#endif /* __NETWORKMANAGER_ACCESS_POINT_H__ */ diff --git a/src/devices/wifi/nm-wifi-enum-types.c b/src/devices/wifi/nm-wifi-enum-types.c index e914cfd6..7cce51cd 100644 --- a/src/devices/wifi/nm-wifi-enum-types.c +++ b/src/devices/wifi/nm-wifi-enum-types.c @@ -9,50 +9,6 @@ #include "nm-wifi-ap.h" #include "nm-device-olpc-mesh.h" -GType -nm_wifi_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS, "NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS", "ConnectionNotWireless" }, - { NM_WIFI_ERROR_CONNECTION_INVALID, "NM_WIFI_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND", "AccessPointNotFound" }, - { NM_WIFI_ERROR_SCAN_NOT_ALLOWED, "NM_WIFI_ERROR_SCAN_NOT_ALLOWED", "ScanNotAllowed" }, - { NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, "NM_WIFI_ERROR_AP_MODE_UNSUPPORTED", "ApModeUnsupported" }, - { NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, "NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED", "AdhocModeUnsupported" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMWifiError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_olpc_mesh_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH", "ConnectionNotMesh" }, - { NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "NM_OLPC_MESH_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMOlpcMeshError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} diff --git a/src/devices/wifi/nm-wifi-enum-types.h b/src/devices/wifi/nm-wifi-enum-types.h index d4dca5bf..7fc64cd1 100644 --- a/src/devices/wifi/nm-wifi-enum-types.h +++ b/src/devices/wifi/nm-wifi-enum-types.h @@ -9,10 +9,6 @@ #include <glib-object.h> G_BEGIN_DECLS -GType nm_wifi_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) -GType nm_olpc_mesh_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ()) G_END_DECLS #endif /* __NM_WIFI_ENUM_TYPES_H__ */ diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 02ad93f4..4093c612 100644 --- a/src/devices/wifi/nm-wifi-factory.c +++ b/src/devices/wifi/nm-wifi-factory.c @@ -18,12 +18,15 @@ * Copyright (C) 2011 - 2014 Red Hat, Inc. */ +#include "config.h" + #include <gmodule.h> #include "nm-device-factory.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" #include "nm-settings-connection.h" +#include "nm-platform.h" #define NM_TYPE_WIFI_FACTORY (nm_wifi_factory_get_type ()) #define NM_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactory)) @@ -45,20 +48,12 @@ G_DEFINE_TYPE_EXTENDED (NMWifiFactory, nm_wifi_factory, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_WIFI - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WIFI_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /**************************************************************************/ static NMDevice * @@ -71,10 +66,17 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) return NULL; } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_WIFI; +} + static void device_factory_interface_init (NMDeviceFactory *factory_iface) { factory_iface->new_link = new_link; + factory_iface->get_device_type = get_device_type; } static void diff --git a/src/devices/wifi/tests/Makefile.am b/src/devices/wifi/tests/Makefile.am index 2667c5f1..09c6401f 100644 --- a/src/devices/wifi/tests/Makefile.am +++ b/src/devices/wifi/tests/Makefile.am @@ -1,14 +1,13 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/platform \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I${top_srcdir}/src/platform \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/devices/wifi \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/devices/wifi/tests/Makefile.in b/src/devices/wifi/tests/Makefile.in index c0e75eed..a8ae2e9d 100644 --- a/src/devices/wifi/tests/Makefile.in +++ b/src/devices/wifi/tests/Makefile.in @@ -205,6 +205,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -328,6 +330,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -347,6 +350,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -373,7 +377,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -454,15 +458,14 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/platform \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I${top_srcdir}/src/platform \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/devices/wifi \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c index 36d58f2a..fb335b89 100644 --- a/src/devices/wifi/tests/test-wifi-ap-utils.c +++ b/src/devices/wifi/tests/test-wifi-ap-utils.c @@ -18,16 +18,15 @@ * */ +#include "config.h" + #include <glib.h> #include <string.h> #include "nm-wifi-ap-utils.h" #include "nm-dbus-glib-types.h" -#include "nm-setting-connection.h" -#include "nm-setting-wireless.h" -#include "nm-setting-wireless-security.h" -#include "nm-setting-8021x.h" +#include "nm-core-internal.h" #define DEBUG 1 @@ -66,7 +65,7 @@ static gboolean complete_connection (const char *ssid, - const guint8 bssid[ETH_ALEN], + const char *bssid, NM80211Mode mode, guint32 flags, guint32 wpa_flags, @@ -113,7 +112,7 @@ set_items (NMSetting *setting, const KeyData *items) { const KeyData *item; GParamSpec *pspec; - GByteArray *tmp; + GBytes *tmp; for (item = items; item && item->key; item++) { g_assert (item->key); @@ -137,12 +136,11 @@ set_items (NMSetting *setting, const KeyData *items) g_assert (item->str == NULL); g_object_set (G_OBJECT (setting), item->key, foo, NULL); - } else if (pspec->value_type == DBUS_TYPE_G_UCHAR_ARRAY) { + } else if (pspec->value_type == G_TYPE_BYTES) { g_assert (item->str); - tmp = g_byte_array_sized_new (strlen (item->str)); - g_byte_array_append (tmp, (const guint8 *) item->str, strlen (item->str)); + tmp = g_bytes_new (item->str, strlen (item->str)); g_object_set (G_OBJECT (setting), item->key, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_bytes_unref (tmp); } else { /* Special types, check based on property name */ if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) @@ -217,31 +215,26 @@ fill_8021x (NMConnection *connection, const KeyData items[]) static NMConnection * create_basic (const char *ssid, - const guint8 *bssid, + const char *bssid, NM80211Mode mode) { NMConnection *connection; NMSettingWireless *s_wifi = NULL; - GByteArray *tmp; + GBytes *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); /* SSID */ - tmp = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid)); + tmp = g_bytes_new (ssid, strlen (ssid)); g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_bytes_unref (tmp); /* BSSID */ - if (bssid) { - tmp = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (tmp, bssid, ETH_ALEN); - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, tmp, NULL); - g_byte_array_free (tmp, TRUE); - } + if (bssid) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); if (mode == NM_802_11_MODE_INFRA) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); @@ -259,12 +252,12 @@ static void test_lock_bssid (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -283,7 +276,7 @@ static void test_open_ap_empty_connection (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; gboolean success; GError *error = NULL; @@ -292,7 +285,7 @@ test_open_ap_empty_connection (void) * SSID and Infra modes of the given AP details. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -311,7 +304,7 @@ static void test_open_ap_leap_connection_1 (gconstpointer add_wifi) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0 }, { NULL } }; gboolean success; GError *error = NULL; @@ -321,7 +314,7 @@ test_open_ap_leap_connection_1 (gconstpointer add_wifi) * the AP to have the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -332,7 +325,7 @@ test_open_ap_leap_connection_1 (gconstpointer add_wifi) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -343,7 +336,7 @@ static void test_open_ap_leap_connection_2 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; gboolean success; GError *error = NULL; @@ -352,7 +345,7 @@ test_open_ap_leap_connection_2 (void) * WEP or LEAP) is rejected when completion is attempted with an open AP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -362,7 +355,7 @@ test_open_ap_leap_connection_2 (void) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -373,7 +366,7 @@ static void test_open_ap_wep_connection (gconstpointer add_wifi) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0 }, { NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0 }, @@ -386,7 +379,7 @@ test_open_ap_wep_connection (gconstpointer add_wifi) * attempted with an open AP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -396,7 +389,7 @@ test_open_ap_wep_connection (gconstpointer add_wifi) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -410,11 +403,12 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, guint32 wpa_flags, guint32 rsn_flags, gboolean add_wifi, + guint error_code, NMConnection *expected) { NMConnection *src; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData exp_wifi[] = { { NM_SETTING_WIRELESS_SSID, ssid, 0 }, { NM_SETTING_WIRELESS_MODE, "infrastructure", 0 }, @@ -427,7 +421,7 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, both_wsec); @@ -438,7 +432,7 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, fill_wifi (expected, exp_wifi); fill_wsec (expected, both_wsec); } - COMPARE (src, expected, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, expected, success, error, NM_CONNECTION_ERROR, error_code); g_object_unref (src); } @@ -454,7 +448,9 @@ test_open_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -468,7 +464,9 @@ test_open_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE, NULL); + TRUE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -481,7 +479,9 @@ test_open_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -495,7 +495,9 @@ test_open_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -508,7 +510,9 @@ test_open_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } /*******************************************/ @@ -520,11 +524,10 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, guint32 wpa_flags, guint32 rsn_flags, gboolean add_wifi, - guint error_domain, guint error_code) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_empty[] = { { NULL } }; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, @@ -533,7 +536,7 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -542,7 +545,7 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, flags, wpa_flags, rsn_flags, FALSE, src, &error); /* Failure expected */ - COMPARE (src, NULL, success, error, error_domain, error_code); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, error_code); g_object_unref (src); } @@ -619,37 +622,22 @@ rsn_flags_for_idx (guint32 idx) } static guint32 -error_domain_for_idx (guint32 idx, guint num) -{ - if (idx == IDX_OPEN) - return NM_SETTING_WIRELESS_SECURITY_ERROR; - else if (idx == IDX_PRIV) { - if (num <= 3) - return NM_SETTING_802_1X_ERROR; - else - return NM_SETTING_WIRELESS_SECURITY_ERROR; - } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) - return NM_SETTING_WIRELESS_SECURITY_ERROR; - else - g_assert_not_reached (); -} - -static guint32 error_code_for_idx (guint32 idx, guint num) { if (idx == IDX_OPEN) - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + return NM_CONNECTION_ERROR_INVALID_SETTING; else if (idx == IDX_PRIV) { if (num <= 3) - return NM_SETTING_802_1X_ERROR_MISSING_PROPERTY; + return NM_CONNECTION_ERROR_MISSING_PROPERTY; else - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; - } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + } else if ( idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + if (num == 4) + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + else + return NM_CONNECTION_ERROR_INVALID_SETTING; else g_assert_not_reached (); } @@ -664,7 +652,6 @@ test_ap_wpa_eap_connection_1 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 1), error_code_for_idx (idx, 1)); } @@ -678,7 +665,6 @@ test_ap_wpa_eap_connection_2 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), TRUE, - error_domain_for_idx (idx, 2), error_code_for_idx (idx, 2)); } @@ -692,7 +678,6 @@ test_ap_wpa_eap_connection_3 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 3), error_code_for_idx (idx, 3)); } @@ -706,7 +691,6 @@ test_ap_wpa_eap_connection_4 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 4), error_code_for_idx (idx, 4)); } @@ -720,7 +704,6 @@ test_ap_wpa_eap_connection_5 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 5), error_code_for_idx (idx, 5)); } @@ -730,7 +713,7 @@ static void test_priv_ap_empty_connection (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; const KeyData exp_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0 }, @@ -742,7 +725,7 @@ test_priv_ap_empty_connection (void) * connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -765,7 +748,7 @@ test_priv_ap_leap_connection_1 (gconstpointer add_wifi) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *leap_username = "Bill Smith"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, @@ -784,7 +767,7 @@ test_priv_ap_leap_connection_1 (gconstpointer add_wifi) * with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -810,7 +793,7 @@ static void test_priv_ap_leap_connection_2 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, @@ -823,7 +806,7 @@ test_priv_ap_leap_connection_2 (void) * with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -832,7 +815,7 @@ test_priv_ap_leap_connection_2 (void) FALSE, src, &error); /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); g_object_unref (src); } @@ -844,7 +827,7 @@ test_priv_ap_dynamic_wep_1 (void) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, @@ -866,7 +849,7 @@ test_priv_ap_dynamic_wep_1 (void) * Dynamic WEP connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, both_8021x); @@ -892,7 +875,7 @@ test_priv_ap_dynamic_wep_2 (void) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; @@ -913,7 +896,7 @@ test_priv_ap_dynamic_wep_2 (void) * WEP connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, both_8021x); @@ -938,7 +921,7 @@ static void test_priv_ap_dynamic_wep_3 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0 }, { NULL } }; @@ -954,7 +937,7 @@ test_priv_ap_dynamic_wep_3 (void) * setting is rejected, as 802.1x is incompatible with 'shared' auth. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, src_8021x); @@ -964,7 +947,7 @@ test_priv_ap_dynamic_wep_3 (void) FALSE, src, &error); /* Expect failure; shared is not compatible with dynamic WEP */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -982,7 +965,9 @@ test_priv_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -996,7 +981,9 @@ test_priv_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE, NULL); + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1011,7 +998,9 @@ test_priv_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1026,7 +1015,9 @@ test_priv_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1041,7 +1032,9 @@ test_priv_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } /*******************************************/ @@ -1051,7 +1044,7 @@ test_wpa_ap_empty_connection (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; const KeyData exp_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, @@ -1065,7 +1058,7 @@ test_wpa_ap_empty_connection (gconstpointer data) * or RSN flags. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), @@ -1089,7 +1082,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) guint idx = GPOINTER_TO_UINT (data); NMConnection *src; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *leap_username = "Bill Smith"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, @@ -1102,7 +1095,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) * rejected since WPA APs (usually) do not support LEAP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection (ssid, bssid, @@ -1112,7 +1105,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) FALSE, src, &error); /* Expect failure here; WPA APs don't support old-school LEAP */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1124,7 +1117,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, @@ -1136,7 +1129,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) * rejected since WPA APs (usually) do not support LEAP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -1146,7 +1139,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) FALSE, src, &error); /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1158,7 +1151,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; @@ -1169,7 +1162,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) * rejected since WPA APs (usually) do not support Dynamic WEP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -1179,7 +1172,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) FALSE, src, &error); /* We expect failure here since Dynamic WEP is incompatible with WPA */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1196,13 +1189,15 @@ test_wpa_ap_wpa_psk_connection_1 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1216,13 +1211,15 @@ test_wpa_ap_wpa_psk_connection_2 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - TRUE, expected); + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1236,13 +1233,15 @@ test_wpa_ap_wpa_psk_connection_3 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, "open", NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1254,7 +1253,9 @@ test_wpa_ap_wpa_psk_connection_4 (gconstpointer data) NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1267,13 +1268,15 @@ test_wpa_ap_wpa_psk_connection_5 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base ("wpa-psk", "open", NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } diff --git a/src/devices/wimax/Makefile.am b/src/devices/wimax/Makefile.am index def8bf62..555b5ff2 100644 --- a/src/devices/wimax/Makefile.am +++ b/src/devices/wimax/Makefile.am @@ -1,20 +1,16 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(IWMX_SDK_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(IWMX_SDK_CFLAGS) pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la diff --git a/src/devices/wimax/Makefile.in b/src/devices/wimax/Makefile.in index ba16d277..f1ffb09c 100644 --- a/src/devices/wimax/Makefile.in +++ b/src/devices/wimax/Makefile.in @@ -215,6 +215,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -338,6 +340,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -357,6 +360,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -383,7 +387,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -465,20 +469,16 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(IWMX_SDK_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(IWMX_SDK_CFLAGS) pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la SYMBOL_VIS_FILE = $(srcdir)/exports.ver diff --git a/src/devices/wimax/exports.ver b/src/devices/wimax/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wimax/exports.ver +++ b/src/devices/wimax/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wimax/iwmxsdk.c b/src/devices/wimax/iwmxsdk.c index d1ef7b68..1c2c6821 100644 --- a/src/devices/wimax/iwmxsdk.c +++ b/src/devices/wimax/iwmxsdk.c @@ -19,24 +19,22 @@ * */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif +#include "config.h" #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/socket.h> -#include <linux/if.h> #include <glib.h> -#include <WiMaxType.h> +#include "nm-wimax-util.h" + #include <WiMaxAPI.h> #include <WiMaxAPIEx.h> -#include "logging/nm-logging.h" +#include "nm-logging.h" #include "iwmxsdk.h" static WIMAX_API_DEVICE_ID g_api; diff --git a/src/devices/wimax/iwmxsdk.h b/src/devices/wimax/iwmxsdk.h index 785ca8c2..c8e76696 100644 --- a/src/devices/wimax/iwmxsdk.h +++ b/src/devices/wimax/iwmxsdk.h @@ -19,10 +19,11 @@ * */ -#ifndef IWMXSDK_H -#define IWMXSDK_H +#ifndef __IWMXSDK_H__ +#define __IWMXSDK_H__ + +#include "nm-wimax-util.h" -#include <wimax/WiMaxType.h> #include <wimax/WiMaxTypesEx.h> #include <wimax/WiMaxAPIEx.h> @@ -108,4 +109,4 @@ int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk); int iwmx_sdk_api_init(void); void iwmx_sdk_api_exit(void); -#endif /* IWMXSDK_H */ +#endif /* __IWMXSDK_H__ */ diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c index 1bdda489..466cd979 100644 --- a/src/devices/wimax/nm-device-wimax.c +++ b/src/devices/wimax/nm-device-wimax.c @@ -19,14 +19,17 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> -#include <net/ethernet.h> #include <sys/socket.h> -#include <linux/if.h> -#include <netinet/ether.h> + +#include <glib/gi18n.h> + +#include "nm-wimax-util.h" #include <WiMaxAPI.h> #include <WiMaxAPIEx.h> @@ -36,8 +39,10 @@ #include "nm-logging.h" #include "nm-device-private.h" #include "NetworkManagerUtils.h" +#include "nm-active-connection.h" #include "nm-dbus-manager.h" #include "nm-connection.h" +#include "nm-platform.h" #include "nm-setting-connection.h" #include "nm-setting-wimax.h" #include "nm-utils.h" @@ -110,19 +115,6 @@ typedef struct { /***********************************************************/ -#define NM_WIMAX_ERROR (nm_wimax_error_quark ()) - -static GQuark -nm_wimax_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-wimax-error"); - return quark; -} - -/***********************************************************/ - static gboolean impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error) { @@ -316,7 +308,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMSettingConnection *s_con; NMSettingWimax *s_wimax; const char *connection_type; - const GByteArray *mac; + const char *mac; if (!NM_DEVICE_CLASS (nm_device_wimax_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -333,7 +325,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wimax_get_mac_address (s_wimax); - if (mac && memcmp (mac->data, nm_device_get_hw_address (device, NULL), ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1)) return FALSE; return TRUE; @@ -372,9 +364,8 @@ complete_connection (NMDevice *device, NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMSettingWimax *s_wimax; - const GByteArray *setting_mac; - const guint8 *hw_address; - char *format; + const char *setting_mac; + const char *hw_address; const char *nsp_name = NULL; NMWimaxNsp *nsp = NULL; GSList *iter; @@ -385,8 +376,8 @@ complete_connection (NMDevice *device, /* If not given a specific object, we need at minimum an NSP name */ if (!s_wimax) { g_set_error_literal (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting is required if no NSP path was given."); return FALSE; } @@ -394,8 +385,8 @@ complete_connection (NMDevice *device, nsp_name = nm_setting_wimax_get_network_name (s_wimax); if (!nsp_name || !strlen (nsp_name)) { g_set_error_literal (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting with a valid network name is required if no NSP path was given."); return FALSE; } @@ -422,8 +413,8 @@ complete_connection (NMDevice *device, if (!nsp) { g_set_error (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_NSP_NOT_FOUND, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "The NSP %s was not in the scan list.", specific_object); return FALSE; @@ -439,38 +430,31 @@ complete_connection (NMDevice *device, } g_assert (nsp_name); - format = g_strdup_printf ("%s %%d", nsp_name); nm_utils_complete_generic (connection, NM_SETTING_WIMAX_SETTING_NAME, existing_connections, - format, nsp_name, + nsp_name, + NULL, TRUE); - g_free (format); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); setting_mac = nm_setting_wimax_get_mac_address (s_wimax); - hw_address = nm_device_get_hw_address (device, NULL); + hw_address = nm_device_get_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, hw_address, ETH_ALEN)) { - g_set_error (error, - NM_SETTING_WIMAX_ERROR, - NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, - NM_SETTING_WIMAX_MAC_ADDRESS); + if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - /* Lock the connection to this device by default */ - if (memcmp (hw_address, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, hw_address, ETH_ALEN); - g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } + if (!nm_utils_hwaddr_matches (hw_address, -1, NULL, ETH_ALEN)) + g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, hw_address, NULL); } return TRUE; @@ -1047,7 +1031,7 @@ set_link_status (NMDeviceWimax *self, WIMAX_API_LINK_STATUS_INFO_EX *link_status conv_rssi = sdk_rssi_to_dbm (link_status->RSSI); conv_cinr = sdk_cinr_to_db (link_status->CINR); conv_tx_pow = sdk_tx_pow_to_dbm (link_status->txPWR); - new_bsid = nm_utils_hwaddr_ntoa_len (link_status->bsId, 6); + new_bsid = nm_utils_hwaddr_ntoa (link_status->bsId, 6); } if (priv->center_freq != center_freq) { @@ -1363,58 +1347,52 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_NSPS, - g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, - "Network access points", - "Network access points", + g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_ACTIVE_NSP, - g_param_spec_boxed (NM_DEVICE_WIMAX_ACTIVE_NSP, - "Active NSP", - "Currently active NSP", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_ACTIVE_NSP, + g_param_spec_boxed (NM_DEVICE_WIMAX_ACTIVE_NSP, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CENTER_FREQ, - g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, - "Center frequency", - "Center frequency", + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, "", "", 0, G_MAXUINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSSI, - g_param_spec_int (NM_DEVICE_WIMAX_RSSI, - "RSSI", - "RSSI", + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CINR, - g_param_spec_int (NM_DEVICE_WIMAX_CINR, - "CINR", - "CINR", + g_param_spec_int (NM_DEVICE_WIMAX_CINR, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TX_POWER, - g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, - "TX Power", - "TX Power", + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BSID, - g_param_spec_string (NM_DEVICE_WIMAX_BSID, - "BSID", - "BSID", + g_param_spec_string (NM_DEVICE_WIMAX_BSID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[NSP_ADDED] = @@ -1440,6 +1418,4 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_wimax_object_info); - - dbus_g_error_domain_register (NM_WIMAX_ERROR, NULL, NM_TYPE_WIMAX_ERROR); } diff --git a/src/devices/wimax/nm-device-wimax.h b/src/devices/wimax/nm-device-wimax.h index 8b252ee1..30b2481f 100644 --- a/src/devices/wimax/nm-device-wimax.h +++ b/src/devices/wimax/nm-device-wimax.h @@ -19,10 +19,9 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_DEVICE_WIMAX_H -#define NM_DEVICE_WIMAX_H +#ifndef __NETWORKMANAGER_DEVICE_WIMAX_H__ +#define __NETWORKMANAGER_DEVICE_WIMAX_H__ -#include <net/ethernet.h> #include "nm-device.h" #include "nm-wimax-nsp.h" @@ -35,14 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX)) #define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) -typedef enum -{ - NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0, /*< nick=ConnectionNotWimax >*/ - NM_WIMAX_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_WIMAX_ERROR_NSP_NOT_FOUND, /*< nick=NspNotFound >*/ -} NMWimaxError; - #define NM_DEVICE_WIMAX_NSPS "nsps" #define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" #define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" diff --git a/src/devices/wimax/nm-wimax-factory.c b/src/devices/wimax/nm-wimax-factory.c index ca962e68..39e9a287 100644 --- a/src/devices/wimax/nm-wimax-factory.c +++ b/src/devices/wimax/nm-wimax-factory.c @@ -18,10 +18,13 @@ * Copyright (C) 2011 - 2014 Red Hat, Inc. */ +#include "config.h" + #include <gmodule.h> #include "nm-device-factory.h" #include "nm-device-wimax.h" +#include "nm-platform.h" #define NM_TYPE_WIMAX_FACTORY (nm_wimax_factory_get_type ()) #define NM_WIMAX_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_WIMAX_FACTORY, NMWimaxFactory)) @@ -43,20 +46,12 @@ G_DEFINE_TYPE_EXTENDED (NMWimaxFactory, nm_wimax_factory, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_WIMAX - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WIMAX_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /**************************************************************************/ static NMDevice * @@ -71,10 +66,17 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) return (NMDevice *) nm_device_wimax_new (plink); } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_WIMAX; +} + static void device_factory_interface_init (NMDeviceFactory *factory_iface) { factory_iface->new_link = new_link; + factory_iface->get_device_type = get_device_type; } static void diff --git a/src/devices/wimax/nm-wimax-nsp.c b/src/devices/wimax/nm-wimax-nsp.c index efe3b058..f4db63f0 100644 --- a/src/devices/wimax/nm-wimax-nsp.c +++ b/src/devices/wimax/nm-wimax-nsp.c @@ -19,8 +19,10 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include "nm-wimax-nsp.h" -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-setting-wimax.h" #include "nm-wimax-nsp-glue.h" @@ -210,31 +212,28 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *klass) g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_WIMAX_NSP_NAME, - "Name", - "Name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_string (NM_WIMAX_NSP_NAME, "", "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIGNAL_QUALITY, - g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, - "SignalQuality", - "SignalQuality", - 0, - 100, - 0, - G_PARAM_READWRITE)); + g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, "", "", + 0, + 100, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NETWORK_TYPE, - g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, - "NetworkType", - "NetworkType", + g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, "", "", NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER, NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), diff --git a/src/devices/wimax/nm-wimax-nsp.h b/src/devices/wimax/nm-wimax-nsp.h index a74b68a7..8d0a6a14 100644 --- a/src/devices/wimax/nm-wimax-nsp.h +++ b/src/devices/wimax/nm-wimax-nsp.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_NSP_H -#define NM_WIMAX_NSP_H +#ifndef __NETWORKMANAGER_WIMAX_NSP_H__ +#define __NETWORKMANAGER_WIMAX_NSP_H__ #include <glib-object.h> #include "nm-wimax-types.h" diff --git a/src/devices/wimax/nm-wimax-types.h b/src/devices/wimax/nm-wimax-types.h index 8c807fd8..207d2477 100644 --- a/src/devices/wimax/nm-wimax-types.h +++ b/src/devices/wimax/nm-wimax-types.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_TYPES_H -#define NM_WIMAX_TYPES_H +#ifndef __NETWORKMANAGER_WIMAX_TYPES_H__ +#define __NETWORKMANAGER_WIMAX_TYPES_H__ typedef enum { NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, diff --git a/src/devices/wimax/nm-wimax-util.c b/src/devices/wimax/nm-wimax-util.c index bca25a1d..0ae285ae 100644 --- a/src/devices/wimax/nm-wimax-util.c +++ b/src/devices/wimax/nm-wimax-util.c @@ -18,7 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#include <WiMaxAPI.h> +#include "config.h" + #include "nm-wimax-util.h" #include "nm-utils.h" #include "iwmxsdk.h" diff --git a/src/devices/wimax/nm-wimax-util.h b/src/devices/wimax/nm-wimax-util.h index 71f5aa29..a1852d55 100644 --- a/src/devices/wimax/nm-wimax-util.h +++ b/src/devices/wimax/nm-wimax-util.h @@ -18,12 +18,17 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_UTIL_H -#define NM_WIMAX_UTIL_H +#ifndef __NETWORKMANAGER_WIMAX_UTIL_H__ +#define __NETWORKMANAGER_WIMAX_UTIL_H__ #include <glib.h> +#include "nm-utils-internal.h" + +NM_PRAGMA_WARNING_DISABLE("-Wstrict-prototypes") #include <WiMaxType.h> +NM_PRAGMA_WARNING_REENABLE + #include <WiMaxError.h> #include "nm-wimax-types.h" diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 988f4679..7e5b190b 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -5,18 +5,16 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) @@ -33,9 +31,8 @@ nm_modem_enum_types_sources = $(srcdir)/nm-modem.h BUILT_SOURCES += $(GLIB_GENERATED) libnm_wwan_la_SOURCES = \ - nm-modem-old.c \ - nm-modem-old.h \ - nm-modem-old-types.h \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ nm-modem-manager.c \ nm-modem-manager.h \ nm-modem.c \ @@ -43,12 +40,6 @@ libnm_wwan_la_SOURCES = \ \ $(GLIB_GENERATED) -if WITH_MODEM_MANAGER_1 -libnm_wwan_la_SOURCES += \ - nm-modem-broadband.c \ - nm-modem-broadband.h -endif - WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index ae33d1c8..18cbfdd3 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -78,13 +78,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_MODEM_MANAGER_1_TRUE@am__append_1 = \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.c \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.h - subdir = src/devices/wwan DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp README + $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -151,15 +147,9 @@ libnm_device_plugin_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ libnm_wwan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) -am__libnm_wwan_la_SOURCES_DIST = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h nm-modem-enum-types.h \ - nm-modem-enum-types.c nm-modem-broadband.c \ - nm-modem-broadband.h am__objects_1 = nm-modem-enum-types.lo -@WITH_MODEM_MANAGER_1_TRUE@am__objects_2 = nm-modem-broadband.lo -am_libnm_wwan_la_OBJECTS = nm-modem-old.lo nm-modem-manager.lo \ - nm-modem.lo $(am__objects_1) $(am__objects_2) +am_libnm_wwan_la_OBJECTS = nm-modem-broadband.lo nm-modem-manager.lo \ + nm-modem.lo $(am__objects_1) libnm_wwan_la_OBJECTS = $(am_libnm_wwan_la_OBJECTS) libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -201,7 +191,7 @@ am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ $(libnm_wwan_la_SOURCES) DIST_SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ - $(am__libnm_wwan_la_SOURCES_DIST) + $(libnm_wwan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -236,6 +226,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -359,6 +351,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -378,6 +371,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -404,7 +398,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -486,18 +480,16 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) nm-device-modem-glue.h @@ -508,9 +500,16 @@ GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM nm_modem_enum_types_sources = $(srcdir)/nm-modem.h -libnm_wwan_la_SOURCES = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h $(GLIB_GENERATED) $(am__append_1) +libnm_wwan_la_SOURCES = \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ + nm-modem-manager.c \ + nm-modem-manager.h \ + nm-modem.c \ + nm-modem.h \ + \ + $(GLIB_GENERATED) + WWAN_SYMBOL_VIS_FILE = $(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ -avoid-version \ @@ -624,7 +623,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-broadband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-enum-types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-old.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wwan-factory.Plo@am__quote@ diff --git a/src/devices/wwan/README b/src/devices/wwan/README deleted file mode 100644 index 4661c042..00000000 --- a/src/devices/wwan/README +++ /dev/null @@ -1,45 +0,0 @@ - -ModemManager integration is organized as follows: - - -Common source -******************************************************************************** - - * nm-modem.[h|c]: - Defines the basic `NMModem' object. The core NetworkManager implementation - will use this interface exclusively, regardless of the real final type of - the modem object. - - * nm-modem-manager.[h|c]: - Defines the `NMModemManager' object, which takes care of listening to - signals from the DBus interface notifying about added or removed modems. - It also takes care of creating proper `NMModem' objects from the - information retrieved from the DBus interface. - - -ModemManager 0.7 integration -******************************************************************************** - - * nm-modem-broadband.[h|c]: - Defines the `NMModemBroadband' object, which is a subclass of `NMModem'. - This object handles both 3GPP and 3GPP2 modems exposed in the new - `ModemManager1' interface. - - -ModemManager 0.4/0.5/0.6 integration -******************************************************************************** - - * nm-modem-old-types.h: - Defines helper types to use with the (old) ModemManager DBus API. - - * nm-modem-old.[h|c]: - Defines the `NMModemGeneric' object. All modem objects based on the old - ModemManager interface are subclasses of this one. - - * nm-modem-gsm.[h|c]: - Defines the `NMModemGsm' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP-specific (GSM, UMTS, HSPA, LTE) modems. - - * nm-modem-cdma.[h|c]: - Defines the `NMModemCdma' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP2-specific modems (CDMA, EV-DO). diff --git a/src/devices/wwan/exports.ver b/src/devices/wwan/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wwan/exports.ver +++ b/src/devices/wwan/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 678f7795..f681e59c 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -20,20 +20,22 @@ #include "config.h" +#include <string.h> #include <glib.h> #include "nm-device-modem.h" #include "nm-modem.h" -#include "nm-modem-old.h" #include "nm-device-private.h" #include "nm-rfkill-manager.h" #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-settings-connection.h" - -#if WITH_MODEM_MANAGER_1 #include "nm-modem-broadband.h" -#endif +#include "NetworkManagerUtils.h" +#include "nm-core-internal.h" + +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceModem); G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) @@ -91,7 +93,8 @@ modem_prepare_result (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); NMDeviceState state; state = nm_device_get_state (device); @@ -106,8 +109,7 @@ modem_prepare_result (NMModem *modem, * the SIM if the incorrect PIN continues to be used. */ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL); - nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN", - nm_device_get_iface (device)); + _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN"); } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); @@ -147,33 +149,110 @@ modem_auth_result (NMModem *modem, GError *error, gpointer user_data) } static void -modem_ip4_config_result (NMModem *self, +modem_ip4_config_result (NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { - nm_log_warn (LOGD_MB | LOGD_IP4, "retrieving IP4 configuration failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else - nm_device_activate_schedule_ip4_config_result (device, config); + } else { + nm_device_set_wwan_ip4_config (device, config); + nm_device_activate_schedule_ip4_config_result (device, NULL); + } +} + +static void +modem_ip6_config_result (NMModem *modem, + NMIP6Config *config, + gboolean do_slaac, + GError *error, + gpointer user_data) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); + NMActStageReturn ret; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMIP6Config *ignored = NULL; + gboolean got_config = !!config; + + g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); + + if (error) { + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); + + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + /* Re-enable IPv6 on the interface */ + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "0"); + + if (config) + nm_device_set_wwan_ip6_config (device, config); + + if (do_slaac == FALSE) { + if (got_config) + nm_device_activate_schedule_ip6_config_result (device); + else { + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + return; + } + + /* Start SLAAC now that we have a link-local address from the modem */ + ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip6_config_start (device, &ignored, &reason); + g_assert (ignored == NULL); + switch (ret) { + case NM_ACT_STAGE_RETURN_FAILURE: + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + break; + case NM_ACT_STAGE_RETURN_STOP: + /* all done */ + nm_device_activate_schedule_ip6_config_result (device); + break; + case NM_ACT_STAGE_RETURN_POSTPONE: + /* let SLAAC run */ + break; + default: + /* Should never get here since we've assured that the IPv6 method + * will either be "auto" or "ignored" when starting IPv6 configuration. + */ + g_assert_not_reached (); + } } static void data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); + const char *old = nm_device_get_ip_iface (self); + const char *new = nm_modem_get_data_port (modem); + gboolean changed = FALSE; + + if (new && g_strcmp0 (new, old)) + changed = TRUE; /* We set the IP iface in the device as soon as we know it, so that we * properly ifup it if needed */ - nm_device_set_ip_iface (self, nm_modem_get_data_port (modem)); + nm_device_set_ip_iface (self, new); + + /* Disable IPv6 immediately on the interface since NM handles IPv6 + * internally, and leaving it enabled could allow the kernel's IPv6 + * RA handling code to run before NM is ready. + */ + if (changed) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); } static void @@ -258,6 +337,7 @@ device_state_changed (NMDevice *device, NMDeviceState old_state, NMDeviceStateReason reason) { + NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMConnection *connection = nm_device_get_connection (device); @@ -266,9 +346,8 @@ device_state_changed (NMDevice *device, if (new_state == NM_DEVICE_STATE_UNAVAILABLE && old_state < NM_DEVICE_STATE_UNAVAILABLE) { /* Log initial modem state */ - nm_log_info (LOGD_MB, "(%s): modem state '%s'", - nm_device_get_iface (device), - nm_modem_state_to_string (nm_modem_get_state (priv->modem))); + _LOGI (LOGD_MB, "modem state '%s'", + nm_modem_state_to_string (nm_modem_get_state (priv->modem))); } nm_modem_device_state_changed (priv->modem, new_state, old_state, reason); @@ -294,10 +373,10 @@ device_state_changed (NMDevice *device, } } -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) +static guint32 +get_generic_capabilities (NMDevice *device) { - return 0; + return NM_DEVICE_CAP_IS_NON_KERNEL; } static gboolean @@ -404,11 +483,24 @@ act_stage3_ip6_config_start (NMDevice *device, NMDeviceStateReason *reason) { return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), + nm_device_get_act_request (device), reason); } +static gboolean +get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + gboolean success; + + g_return_val_if_fail (priv->modem, FALSE); + success = nm_modem_get_iid (priv->modem, out_iid); + if (!success) + success = NM_DEVICE_CLASS (nm_device_modem_parent_class)->get_ip_iface_identifier (device, out_iid); + return success; +} + /*****************************************************************************/ static gboolean @@ -444,23 +536,22 @@ set_enabled (NMDevice *device, gboolean enabled) } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (dev); + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMModemState modem_state; if (!priv->rf_enabled) { - nm_log_dbg (LOGD_MB, "(%s): not available because WWAN airplane mode is on", - nm_device_get_iface (dev)); + _LOGD (LOGD_MB, "not available because WWAN airplane mode is on"); return FALSE; } g_assert (priv->modem); modem_state = nm_modem_get_state (priv->modem); if (modem_state <= NM_MODEM_STATE_INITIALIZING) { - nm_log_dbg (LOGD_MB, "(%s): not available because modem is not ready (%s)", - nm_device_get_iface (dev), - nm_modem_state_to_string (modem_state)); + _LOGD (LOGD_MB, "not available because modem is not ready (%s)", + nm_modem_state_to_string (modem_state)); return FALSE; } @@ -496,8 +587,10 @@ nm_device_modem_new (NMModem *modem) /* If the data port is known, set it as the IP interface immediately */ data_port = nm_modem_get_data_port (modem); - if (data_port) + if (data_port) { nm_device_set_ip_iface (device, data_port); + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); + } return device; } @@ -508,6 +601,18 @@ nm_device_modem_init (NMDeviceModem *self) } static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object); + + /* DHCP is always done by the modem firmware, not by the network, and + * by the time we get around to DHCP the firmware should already know + * the IP addressing details. So the DHCP timeout can be much shorter. + */ + nm_device_set_dhcp_timeout (NM_DEVICE (object), 15); +} + +static void set_modem (NMDeviceModem *self, NMModem *modem) { NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); @@ -519,6 +624,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); + g_signal_connect (modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK (modem_ip6_config_result), self); g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); @@ -599,8 +705,9 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; + object_class->constructed = constructed; - device_class->get_hw_address_length = get_hw_address_length; + device_class->get_generic_capabilities = get_generic_capabilities; device_class->check_connection_compatible = check_connection_compatible; device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; @@ -614,31 +721,31 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->set_enabled = set_enabled; device_class->owns_iface = owns_iface; device_class->is_available = is_available; + device_class->get_ip_iface_identifier = get_ip_iface_identifier; device_class->state_changed = device_state_changed; /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_DEVICE_MODEM_MODEM, - "Modem", - "Modem", + g_param_spec_object (NM_DEVICE_MODEM_MODEM, "", "", NM_TYPE_MODEM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, - "Modem Capabilities", - "Modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CURRENT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, - "Current modem Capabilities", - "Current modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CURRENT_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (mclass), diff --git a/src/devices/wwan/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h index ee6b2988..996195c4 100644 --- a/src/devices/wwan/nm-device-modem.h +++ b/src/devices/wwan/nm-device-modem.h @@ -18,8 +18,8 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_MODEM_H -#define NM_DEVICE_MODEM_H +#ifndef __NETWORKMANAGER_DEVICE_MODEM_H__ +#define __NETWORKMANAGER_DEVICE_MODEM_H__ #include <glib.h> #include <glib-object.h> @@ -51,4 +51,4 @@ GType nm_device_modem_get_type (void); NMDevice *nm_device_modem_new (NMModem *modem); -#endif /* NM_DEVICE_MODEM_H */ +#endif /* __NETWORKMANAGER_DEVICE_MODEM_H__ */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 807b8924..f8239b79 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -18,14 +18,19 @@ * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> */ +#include "config.h" + #include <glib/gi18n.h> #include <string.h> +#include <arpa/inet.h> #include <libmm-glib.h> + #include "nm-modem-broadband.h" -#include "nm-setting-connection.h" +#include "nm-core-internal.h" #include "nm-logging.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" +#include "nm-platform.h" G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) @@ -156,13 +161,29 @@ ask_for_pin (NMModemBroadband *self) NM_SETTING_GSM_PIN); } +static NMModemIPMethod +get_bearer_ip_method (MMBearerIpConfig *config) +{ + MMBearerIpMethod mm_method; + + mm_method = mm_bearer_ip_config_get_method (config); + if (mm_method == MM_BEARER_IP_METHOD_PPP) + return NM_MODEM_IP_METHOD_PPP; + else if (mm_method == MM_BEARER_IP_METHOD_STATIC) + return NM_MODEM_IP_METHOD_STATIC; + else if (mm_method == MM_BEARER_IP_METHOD_DHCP) + return NM_MODEM_IP_METHOD_AUTO; + return NM_MODEM_IP_METHOD_UNKNOWN; +} + static void connect_ready (MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { GError *error = NULL; - guint ip_method; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_clear_object (&self->priv->connect_properties); @@ -195,35 +216,31 @@ connect_ready (MMModemSimple *simple_iface, /* Grab IP configurations */ self->priv->ipv4_config = mm_bearer_get_ipv4_config (self->priv->bearer); - self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv4_config) + ip4_method = get_bearer_ip_method (self->priv->ipv4_config); - switch (mm_bearer_ip_config_get_method (self->priv->ipv4_config)) { - case MM_BEARER_IP_METHOD_PPP: - ip_method = MM_MODEM_IP_METHOD_PPP; - break; - case MM_BEARER_IP_METHOD_STATIC: - ip_method = MM_MODEM_IP_METHOD_STATIC; - break; - case MM_BEARER_IP_METHOD_DHCP: - ip_method = MM_MODEM_IP_METHOD_DHCP; - break; - default: - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, - "invalid IP config"); - nm_log_warn (LOGD_MB, "(%s) failed to connect modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - error->message); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv6_config) + ip6_method = get_bearer_ip_method (self->priv->ipv6_config); + + if (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN && + ip6_method == NM_MODEM_IP_METHOD_UNKNOWN) { + nm_log_warn (LOGD_MB, "(%s) failed to connect modem: invalid bearer IP configuration", + nm_modem_get_uid (NM_MODEM (self))); + + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "invalid bearer IP configuration"); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, error); g_error_free (error); g_object_unref (self); return; } - /* IPv4 for now only */ g_object_set (self, NM_MODEM_DATA_PORT, mm_bearer_get_interface (self->priv->bearer), - NM_MODEM_IP_METHOD, ip_method, + NM_MODEM_IP4_METHOD, ip4_method, + NM_MODEM_IP6_METHOD, ip6_method, NM_MODEM_IP_TIMEOUT, mm_bearer_get_ip_timeout (self->priv->bearer), NULL); @@ -249,12 +266,15 @@ create_cdma_connect_properties (NMConnection *connection) } static MMSimpleConnectProperties * -create_gsm_connect_properties (NMConnection *connection) +create_gsm_connect_properties (NMModem *modem, + NMConnection *connection, + GError **error) { NMSettingGsm *setting; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; MMSimpleConnectProperties *properties; const gchar *str; + NMModemIPType ip_type; setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); @@ -264,9 +284,9 @@ create_gsm_connect_properties (NMConnection *connection) if (str) mm_simple_connect_properties_set_number (properties, str); + /* Blank APN ("") means the default subscription APN */ str = nm_setting_gsm_get_apn (setting); - if (str) - mm_simple_connect_properties_set_apn (properties, str); + mm_simple_connect_properties_set_apn (properties, str ? str : ""); str = nm_setting_gsm_get_network_id (setting); if (str) @@ -309,6 +329,22 @@ create_gsm_connect_properties (NMConnection *connection) mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); } + /* Determine IP types to use when connecting */ + ip_type = nm_modem_get_connection_ip_type (modem, connection, error); + if (ip_type == NM_MODEM_IP_TYPE_UNKNOWN) { + g_object_unref (properties); + return NULL; + } + + if (ip_type == NM_MODEM_IP_TYPE_IPV4) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4); + else if (ip_type == NM_MODEM_IP_TYPE_IPV6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV6); + else if (ip_type == NM_MODEM_IP_TYPE_IPV4V6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4V6); + else + g_assert_not_reached (); + return properties; } @@ -319,17 +355,29 @@ act_stage1_prepare (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability caps; + GError *error = NULL; g_clear_object (&self->priv->connect_properties); caps = mm_modem_get_current_capabilities (self->priv->modem_iface); if (MODEM_CAPS_3GPP (caps)) - self->priv->connect_properties = create_gsm_connect_properties (connection); + self->priv->connect_properties = create_gsm_connect_properties (_self, connection, &error); else if (MODEM_CAPS_3GPP2 (caps)) self->priv->connect_properties = create_cdma_connect_properties (connection); else { nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem", nm_modem_get_uid (NM_MODEM (self))); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (error) { + nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s", + nm_modem_get_uid (NM_MODEM (self)), + nm_connection_get_id (connection), + error->message); + g_clear_error (&error); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -400,14 +448,14 @@ complete_connection (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability modem_caps; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); /* PPP settings common to 3GPP and 3GPP2 */ s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); g_object_set (G_OBJECT (s_ppp), NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, @@ -419,12 +467,13 @@ complete_connection (NMModem *_self, NMSettingGsm *s_gsm; s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ + if (!s_gsm) { + /* Need a GSM setting at least */ g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("GSM mobile broadband connection requires a 'gsm' setting")); + g_prefix_error (error, "%s: ", NM_SETTING_GSM_SETTING_NAME); return FALSE; } @@ -435,7 +484,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_GSM_SETTING_NAME, existing_connections, - _("GSM connection %d"), + NULL, + _("GSM connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -457,7 +507,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_CDMA_SETTING_NAME, existing_connections, - _("CDMA connection %d"), + NULL, + _("CDMA connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -465,8 +516,8 @@ complete_connection (NMModem *_self, } g_set_error (error, - NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Device is not a mobile broadband modem"); return FALSE; } @@ -590,11 +641,10 @@ set_mm_enabled (NMModem *_self, } /*****************************************************************************/ -/* IP method static */ +/* IPv4 method static */ static gboolean -ip_string_to_network_address (const gchar *str, - guint32 *out) +ip4_string_to_num (const gchar *str, guint32 *out) { guint32 addr = 0; gboolean success = FALSE; @@ -609,7 +659,7 @@ ip_string_to_network_address (const gchar *str, } static gboolean -static_stage3_done (NMModemBroadband *self) +static_stage3_ip4_done (NMModemBroadband *self) { GError *error = NULL; NMIP4Config *config = NULL; @@ -628,9 +678,9 @@ static_stage3_done (NMModemBroadband *self) /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config); - if (!ip_string_to_network_address (address_string, &address_network)) { - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, + if (!ip4_string_to_num (address_string, &address_network)) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IP4 configuration failed: invalid address given '%s'", nm_modem_get_uid (NM_MODEM (self)), address_string); @@ -639,14 +689,14 @@ static_stage3_done (NMModemBroadband *self) /* Missing gateway not a hard failure */ gw_string = mm_bearer_ip_config_get_gateway (self->priv->ipv4_config); - ip_string_to_network_address (gw_string, &gw); + ip4_string_to_num (gw_string, &gw); config = nm_ip4_config_new (); memset (&address, 0, sizeof (address)); address.address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); - address.source = NM_PLATFORM_SOURCE_WWAN; + address.source = NM_IP_CONFIG_SOURCE_WWAN; nm_ip4_config_add_address (config, &address); nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); @@ -659,7 +709,7 @@ static_stage3_done (NMModemBroadband *self) /* DNS servers */ dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config); for (i = 0; dns[i]; i++) { - if ( ip_string_to_network_address (dns[i], &address_network) + if ( ip4_string_to_num (dns[i], &address_network) && address_network > 0) { nm_ip4_config_add_nameserver (config, address_network); nm_log_info (LOGD_MB, " DNS %s", dns[i]); @@ -681,7 +731,110 @@ static_stage3_ip4_config_start (NMModem *_self, /* We schedule it in an idle just to follow the same logic as in the * generic modem implementation. */ - g_idle_add ((GSourceFunc)static_stage3_done, self); + g_idle_add ((GSourceFunc) static_stage3_ip4_done, self); + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +/*****************************************************************************/ +/* IPv6 method static */ + +static gboolean +stage3_ip6_done (NMModemBroadband *self) +{ + GError *error = NULL; + NMIP6Config *config = NULL; + const gchar *address_string; + NMPlatformIP6Address address; + NMModemIPMethod ip_method; + const gchar **dns; + guint i; + + g_assert (self->priv->ipv6_config); + + memset (&address, 0, sizeof (address)); + + ip_method = get_bearer_ip_method (self->priv->ipv6_config); + + address_string = mm_bearer_ip_config_get_address (self->priv->ipv6_config); + if (!address_string) { + /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ + if (ip_method != NM_MODEM_IP_METHOD_AUTO) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: no address given", + nm_modem_get_uid (NM_MODEM (self))); + } + goto out; + } + + /* Fail if invalid IP address retrieved */ + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + + nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:", + nm_modem_get_uid (NM_MODEM (self))); + + config = nm_ip6_config_new (); + + address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv6_config); + nm_ip6_config_add_address (config, &address); + + nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + + address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config); + if (address_string) { + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + nm_log_info (LOGD_MB, " gateway %s", address_string); + nm_ip6_config_set_gateway (config, &address.address); + } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { + /* Gateway required for the 'static' method */ + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: missing gateway", + nm_modem_get_uid (NM_MODEM (self))); + goto out; + } + + /* DNS servers */ + dns = mm_bearer_ip_config_get_dns (self->priv->ipv6_config); + for (i = 0; dns[i]; i++) { + struct in6_addr addr; + + if (inet_pton (AF_INET6, dns[i], &addr)) { + nm_ip6_config_add_nameserver (config, &addr); + nm_log_info (LOGD_MB, " DNS %s", dns[i]); + } + } + +out: + nm_modem_emit_ip6_config_result (NM_MODEM (self), config, error); + g_clear_object (&config); + g_clear_error (&error); + return FALSE; +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *_self, NMDeviceStateReason *reason) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + + /* We schedule it in an idle just to follow the same logic as in the + * generic modem implementation. */ + g_idle_add ((GSourceFunc) stage3_ip6_done, self); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -720,11 +873,15 @@ simple_disconnect_ready (MMModemSimple *modem_iface, } static void -disconnect (NMModem *self, +disconnect (NMModem *modem, gboolean warn) { + NMModemBroadband *self = NM_MODEM_BROADBAND (modem); SimpleDisconnectContext *ctx; + if (!self->priv->simple_iface) + return; + ctx = g_slice_new (SimpleDisconnectContext); ctx->self = g_object_ref (self); @@ -806,6 +963,21 @@ modem_state_changed (MMModem *modem, /*****************************************************************************/ +static NMModemIPType +mm_ip_family_to_nm (MMBearerIpFamily family) +{ + NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN; + + if (family & MM_BEARER_IP_FAMILY_IPV4) + nm_type |= NM_MODEM_IP_TYPE_IPV4; + if (family & MM_BEARER_IP_FAMILY_IPV6) + nm_type |= NM_MODEM_IP_TYPE_IPV6; + if (family & MM_BEARER_IP_FAMILY_IPV4V6) + nm_type |= MM_BEARER_IP_FAMILY_IPV4V6; + + return nm_type; +} + NMModem * nm_modem_broadband_new (GObject *object, GError **error) { @@ -830,6 +1002,7 @@ nm_modem_broadband_new (GObject *object, GError **error) NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), NM_MODEM_DATA_PORT, NULL, /* We don't know it until bearer created */ + NM_MODEM_IP_TYPES, mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem_iface)), NM_MODEM_STATE, mm_state_to_nm (mm_modem_get_state (modem_iface)), NM_MODEM_DEVICE_ID, mm_modem_get_device_identifier (modem_iface), NM_MODEM_BROADBAND_MODEM, modem_object, @@ -967,6 +1140,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->get_capabilities = get_capabilities; modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; + modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; modem_class->deactivate = deactivate; modem_class->set_mm_enabled = set_mm_enabled; @@ -979,9 +1153,8 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_MODEM_BROADBAND_MODEM, - "Modem", - "Broadband modem object", + g_param_spec_object (NM_MODEM_BROADBAND_MODEM, "", "", MM_GDBUS_TYPE_OBJECT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index e12ca68c..2268bac4 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -18,10 +18,9 @@ * Copyright (C) 2012 - Aleksander Morgado <aleksander@gnu.org> */ -#ifndef NM_MODEM_BROADBAND_H -#define NM_MODEM_BROADBAND_H +#ifndef __NETWORKMANAGER_MODEM_BROADBAND_H__ +#define __NETWORKMANAGER_MODEM_BROADBAND_H__ -#include <dbus/dbus-glib.h> #include <glib-object.h> #include "nm-modem.h" @@ -55,4 +54,4 @@ NMModem *nm_modem_broadband_new (GObject *object, GError **error); G_END_DECLS -#endif /* NM_MODEM_BROADBAND_H */ +#endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */ diff --git a/src/devices/wwan/nm-modem-enum-types.c b/src/devices/wwan/nm-modem-enum-types.c index cf59ba2b..6fbb3b6d 100644 --- a/src/devices/wwan/nm-modem-enum-types.c +++ b/src/devices/wwan/nm-modem-enum-types.c @@ -8,22 +8,42 @@ #include "nm-modem.h" GType -nm_modem_error_get_type (void) +nm_modem_ip_method_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_MODEM_ERROR_CONNECTION_NOT_GSM, "NM_MODEM_ERROR_CONNECTION_NOT_GSM", "ConnectionNotGsm" }, - { NM_MODEM_ERROR_CONNECTION_NOT_CDMA, "NM_MODEM_ERROR_CONNECTION_NOT_CDMA", "ConnectionNotCdma" }, - { NM_MODEM_ERROR_CONNECTION_INVALID, "NM_MODEM_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, "NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_MODEM_ERROR_INITIALIZATION_FAILED, "NM_MODEM_ERROR_INITIALIZATION_FAILED", "InitializationFailed" }, + { NM_MODEM_IP_METHOD_UNKNOWN, "NM_MODEM_IP_METHOD_UNKNOWN", "unknown" }, + { NM_MODEM_IP_METHOD_PPP, "NM_MODEM_IP_METHOD_PPP", "ppp" }, + { NM_MODEM_IP_METHOD_STATIC, "NM_MODEM_IP_METHOD_STATIC", "static" }, + { NM_MODEM_IP_METHOD_AUTO, "NM_MODEM_IP_METHOD_AUTO", "auto" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMModemError"), values); + g_enum_register_static (g_intern_static_string ("NMModemIPMethod"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_modem_ip_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_MODEM_IP_TYPE_UNKNOWN, "NM_MODEM_IP_TYPE_UNKNOWN", "unknown" }, + { NM_MODEM_IP_TYPE_IPV4, "NM_MODEM_IP_TYPE_IPV4", "ipv4" }, + { NM_MODEM_IP_TYPE_IPV6, "NM_MODEM_IP_TYPE_IPV6", "ipv6" }, + { NM_MODEM_IP_TYPE_IPV4V6, "NM_MODEM_IP_TYPE_IPV4V6", "ipv4v6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMModemIPType"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } diff --git a/src/devices/wwan/nm-modem-enum-types.h b/src/devices/wwan/nm-modem-enum-types.h index 81ccd8d2..ccbe6201 100644 --- a/src/devices/wwan/nm-modem-enum-types.h +++ b/src/devices/wwan/nm-modem-enum-types.h @@ -9,8 +9,10 @@ #include <glib-object.h> G_BEGIN_DECLS -GType nm_modem_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_MODEM_ERROR (nm_modem_error_get_type ()) +GType nm_modem_ip_method_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_METHOD (nm_modem_ip_method_get_type ()) +GType nm_modem_ip_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_TYPE (nm_modem_ip_type_get_type ()) GType nm_modem_state_get_type (void) G_GNUC_CONST; #define NM_TYPE_MODEM_STATE (nm_modem_state_get_type ()) G_END_DECLS diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index c4811700..f0e56926 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -20,42 +20,28 @@ * Copyright (C) 2009 Canonical Ltd. */ -#include <string.h> #include "config.h" + +#include <string.h> + +#include <libmm-glib.h> + #include "nm-modem-manager.h" #include "nm-logging.h" #include "nm-modem.h" -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-modem-old-types.h" -#include "nm-dbus-glib-types.h" - -#if WITH_MODEM_MANAGER_1 -#include <libmm-glib.h> #include "nm-modem-broadband.h" -#endif #define MODEM_POKE_INTERVAL 120 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) struct _NMModemManagerPrivate { - /* ModemManager < 0.7 */ - NMDBusManager *dbus_mgr; - DBusGProxy *proxy; - guint poke_id; - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ GDBusConnection *dbus_connection; - MMManager *modem_manager_1; - guint modem_manager_1_launch_id; - gboolean old_modem_manager_found; - gboolean new_modem_manager_found; - guint modem_manager_1_name_owner_changed_id; - guint modem_manager_1_object_added_id; - guint modem_manager_1_object_removed_id; -#endif + MMManager *modem_manager; + guint mm_launch_id; + guint mm_name_owner_changed_id; + guint mm_object_added_id; + guint mm_object_removed_id; /* Common */ GHashTable *modems; @@ -85,191 +71,6 @@ handle_new_modem (NMModemManager *self, NMModem *modem) g_signal_emit (self, signals[MODEM_ADDED], 0, modem); } -/************************************************************************/ -/* Support for ModemManager < 0.7 */ - -static void -clear_modem_manager_support (NMModemManager *self) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } -} - -static void -create_modem (NMModemManager *self, const char *path) -{ - DBusGProxy *proxy; - GError *error = NULL; - NMModem *modem = NULL; - GHashTable *properties; - - if (g_hash_table_lookup (self->priv->modems, path)) { - nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); - return; - } - - proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, - path, - DBUS_INTERFACE_PROPERTIES); - g_assert (proxy); - if (dbus_g_proxy_call_with_timeout (proxy, "GetAll", 15000, &error, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_VARIANT, &properties, - G_TYPE_INVALID)) { - /* Success, create the modem */ - modem = nm_modem_old_new (path, properties, &error); - if (modem) - handle_new_modem (self, modem); - else { - nm_log_warn (LOGD_MB, "failed to create modem: %s", - error ? error->message : "(unknown)"); - } - g_hash_table_destroy (properties); - } else { - nm_log_warn (LOGD_MB, "could not get modem properties: %s %s", - error ? dbus_g_error_get_name (error) : "(none)", - error ? error->message : "(unknown)"); - } - - g_object_unref (proxy); - g_clear_error (&error); -} - -static void -modem_added (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - create_modem (NM_MODEM_MANAGER (user_data), path); -} - -static void -modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - NMModem *modem; - - modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); - if (modem) { - nm_modem_emit_removed (modem); - g_hash_table_remove (self->priv->modems, path); - } -} - -static void -mm_poke_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - GPtrArray *modems; - int i; - - if (dbus_g_proxy_end_call (proxy, call, NULL, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &modems, - G_TYPE_INVALID)) { - /* Don't care about the returned value, just free it */ - for (i = 0; i < modems->len; i++) - g_free ((char *) g_ptr_array_index (modems, i)); - g_ptr_array_free (modems, TRUE); - } - g_object_unref (proxy); -} - -static gboolean -poke_modem_cb (gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - DBusGConnection *g_connection; - DBusGProxy *proxy; - - g_connection = nm_dbus_manager_get_connection (self->priv->dbus_mgr); - proxy = dbus_g_proxy_new_for_name (g_connection, - MM_OLD_DBUS_SERVICE, - MM_OLD_DBUS_PATH, - MM_OLD_DBUS_INTERFACE); - - nm_log_dbg (LOGD_MB, "Requesting to (re)launch modem-manager..."); - - dbus_g_proxy_begin_call_with_timeout (proxy, - "EnumerateDevices", - mm_poke_cb, - NULL, - NULL, - 5000, - G_TYPE_INVALID); - return TRUE; -} - -static void -enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data) -{ - NMModemManager *manager = NM_MODEM_MANAGER (data); - GPtrArray *modems; - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "could not get modem list: %s", error->message); - g_error_free (error); - } else { - int i; - - for (i = 0; i < modems->len; i++) { - char *path = (char *) g_ptr_array_index (modems, i); - - create_modem (manager, path); - g_free (path); - } - - g_ptr_array_free (modems, TRUE); - } -} - -#if WITH_MODEM_MANAGER_1 -static void clear_modem_manager_1_support (NMModemManager *self); -#endif - -static void -modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - nm_log_info (LOGD_MB, "modem-manager is now available"); - -#if WITH_MODEM_MANAGER_1 - self->priv->old_modem_manager_found = TRUE; - if (self->priv->new_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_1_support (self); -#endif - - self->priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, MM_OLD_DBUS_PATH, MM_OLD_DBUS_INTERFACE); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceAdded", - G_CALLBACK (modem_added), self, - NULL); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceRemoved", - G_CALLBACK (modem_removed), self, - NULL); - - if (enumerate_devices) - dbus_g_proxy_begin_call (self->priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); -} - static gboolean remove_one_modem (gpointer key, gpointer value, gpointer user_data) { @@ -278,93 +79,34 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) } static void -modem_manager_disappeared (NMModemManager *self) +modem_manager_clear_signals (NMModemManager *self) { - g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, self); - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } - - /* Try to activate the modem-manager */ - nm_log_dbg (LOGD_MB, "trying to start the modem manager..."); - poke_modem_cb (self); - self->priv->poke_id = g_timeout_add_seconds (MODEM_POKE_INTERVAL, poke_modem_cb, self); -} - -static void -nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) -{ - gboolean old_owner_good; - gboolean new_owner_good; - - /* Can't handle the signal if its not from the modem service */ - if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0) + if (!self->priv->modem_manager) return; - old_owner_good = (old_owner && strlen (old_owner)); - new_owner_good = (new_owner && strlen (new_owner)); - - if (!old_owner_good && new_owner_good) { - modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE); - } else if (old_owner_good && !new_owner_good) { - nm_log_info (LOGD_MB, "the modem manager disappeared"); - modem_manager_disappeared (NM_MODEM_MANAGER (user_data)); - } -} - -/************************************************************************/ -/* Support for ModemManager >= 0.7 */ - -#if WITH_MODEM_MANAGER_1 - -static void -modem_manager_1_clear_signals (NMModemManager *self) -{ - if (!self->priv->modem_manager_1) - return; - - if (self->priv->modem_manager_1_name_owner_changed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id); - self->priv->modem_manager_1_name_owner_changed_id = 0; - } - - if (self->priv->modem_manager_1_object_added_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id); - self->priv->modem_manager_1_object_added_id = 0; + if (self->priv->mm_name_owner_changed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id); + self->priv->mm_name_owner_changed_id = 0; } - if (self->priv->modem_manager_1_object_removed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id); - self->priv->modem_manager_1_object_removed_id = 0; + if (self->priv->mm_object_added_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_added_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_added_id); + self->priv->mm_object_added_id = 0; } -} -static void -clear_modem_manager_1_support (NMModemManager *self) -{ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_object_removed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_removed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_removed_id); + self->priv->mm_object_removed_id = 0; } - - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); - g_clear_object (&self->priv->dbus_connection); } static void @@ -426,49 +168,43 @@ modem_object_removed (MMManager *manager, } static void -modem_manager_1_available (NMModemManager *self) +modem_manager_available (NMModemManager *self) { GList *modems, *l; nm_log_info (LOGD_MB, "ModemManager available in the bus"); - self->priv->new_modem_manager_found = TRUE; - if (self->priv->old_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_support (self); - /* Update initial modems list */ - modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager_1)); - for (l = modems; l; l = g_list_next (l)) - modem_object_added (self->priv->modem_manager_1, MM_OBJECT (l->data), self); - g_list_free_full (modems, (GDestroyNotify) g_object_unref); + modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager)); + for (l = modems; l; l = g_list_next (l)) + modem_object_added (self->priv->modem_manager, MM_OBJECT (l->data), self); + g_list_free_full (modems, (GDestroyNotify) g_object_unref); } -static void schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds); -static void ensure_client (NMModemManager *self); +static void schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds); +static void ensure_client (NMModemManager *self); static void -modem_manager_1_name_owner_changed (MMManager *modem_manager_1, - GParamSpec *pspec, - NMModemManager *self) +modem_manager_name_owner_changed (MMManager *modem_manager, + GParamSpec *pspec, + NMModemManager *self) { gchar *name_owner; /* Quit poking, if any */ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; } - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager)); if (!name_owner) { nm_log_info (LOGD_MB, "ModemManager disappeared from bus"); #if !HAVE_SYSTEMD /* If not managed by systemd, schedule relaunch */ - schedule_modem_manager_1_relaunch (self, 0); + schedule_modem_manager_relaunch (self, 0); #endif return; @@ -481,21 +217,21 @@ modem_manager_1_name_owner_changed (MMManager *modem_manager_1, * nor 'object-removed' if it was created while there was no ModemManager in * the bus. This hack avoids this issue until we get a GIO with the fix * included... */ - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); ensure_client (self); /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: - * modem_manager_1_available (self); + * modem_manager_available (self); */ } #if !HAVE_SYSTEMD static void -modem_manager_1_poke_cb (GDBusConnection *connection, - GAsyncResult *res, - NMModemManager *self) +modem_manager_poke_cb (GDBusConnection *connection, + GAsyncResult *res, + NMModemManager *self) { GError *error = NULL; GVariant *result; @@ -514,7 +250,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else g_variant_unref (result); @@ -523,7 +259,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, } static void -modem_manager_1_poke (NMModemManager *self) +modem_manager_poke (NMModemManager *self) { /* If there is no current owner right away, ensure we poke to get one */ g_dbus_connection_call (self->priv->dbus_connection, @@ -536,28 +272,28 @@ modem_manager_1_poke (NMModemManager *self) G_DBUS_CALL_FLAGS_NONE, -1, NULL, /* cancellable */ - (GAsyncReadyCallback)modem_manager_1_poke_cb, /* callback */ + (GAsyncReadyCallback)modem_manager_poke_cb, /* callback */ g_object_ref (self)); /* user_data */ } #endif /* HAVE_SYSTEMD */ static void -modem_manager_1_check_name_owner (NMModemManager *self) +modem_manager_check_name_owner (NMModemManager *self) { gchar *name_owner; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager)); if (name_owner) { /* Available! */ - modem_manager_1_available (self); + modem_manager_available (self); g_free (name_owner); return; } #if !HAVE_SYSTEMD /* If the lifecycle is not managed by systemd, poke */ - modem_manager_1_poke (self); + modem_manager_poke (self); #endif } @@ -570,38 +306,35 @@ manager_new_ready (GObject *source, GError *error = NULL; - g_assert (!self->priv->modem_manager_1); - self->priv->modem_manager_1 = mm_manager_new_finish (res, &error); - if (!self->priv->modem_manager_1) { + g_assert (!self->priv->modem_manager); + self->priv->modem_manager = mm_manager_new_finish (res, &error); + if (!self->priv->modem_manager) { /* We're not really supposed to get any error here. If we do get one, * though, just re-schedule the MMManager creation after some time. * During this period, name-owner changes won't be followed. */ nm_log_warn (LOGD_MB, "error creating ModemManager client: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Setup signals in the GDBusObjectManagerClient */ - self->priv->modem_manager_1_name_owner_changed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_name_owner_changed_id = + g_signal_connect (self->priv->modem_manager, "notify::name-owner", - G_CALLBACK (modem_manager_1_name_owner_changed), + G_CALLBACK (modem_manager_name_owner_changed), self); - self->priv->modem_manager_1_object_added_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_added_id = + g_signal_connect (self->priv->modem_manager, "object-added", G_CALLBACK (modem_object_added), self); - self->priv->modem_manager_1_object_removed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_removed_id = + g_signal_connect (self->priv->modem_manager, "object-removed", G_CALLBACK (modem_object_removed), self); - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } /* Balance refcount */ @@ -616,7 +349,7 @@ ensure_client (NMModemManager *self) /* Create the GDBusObjectManagerClient. We do not request to autostart, as * we don't really want the MMManager creation to fail. We can always poke * later on if we want to request the autostart */ - if (!self->priv->modem_manager_1) { + if (!self->priv->modem_manager) { mm_manager_new (self->priv->dbus_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, NULL, @@ -626,7 +359,7 @@ ensure_client (NMModemManager *self) } /* If already available, recheck name owner! */ - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } static void @@ -643,10 +376,7 @@ bus_get_ready (GObject *source, nm_log_warn (LOGD_CORE, "error getting bus connection: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Got the bus, ensure client */ ensure_client (self); @@ -660,7 +390,7 @@ static gboolean ensure_bus (NMModemManager *self) { /* Clear launch ID */ - self->priv->modem_manager_1_launch_id = 0; + self->priv->mm_launch_id = 0; if (!self->priv->dbus_connection) g_bus_get (G_BUS_TYPE_SYSTEM, @@ -675,20 +405,18 @@ ensure_bus (NMModemManager *self) } static void -schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds) +schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds) { /* No need to pass an extra reference to self; timeout/idle will be * cancelled if the object gets disposed. */ if (n_seconds) - self->priv->modem_manager_1_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); else - self->priv->modem_manager_1_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); } -#endif /* WITH_MODEM_MANAGER_1 */ - /************************************************************************/ static void @@ -698,20 +426,7 @@ nm_modem_manager_init (NMModemManager *self) self->priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - /* ModemManager < 0.7 */ - self->priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (self->priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (nm_modem_manager_name_owner_changed), - self); - if (nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, MM_OLD_DBUS_SERVICE)) - modem_manager_appeared (self, TRUE); - else - modem_manager_disappeared (self); - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - schedule_modem_manager_1_relaunch (self, 0); -#endif + schedule_modem_manager_relaunch (self, 0); } static void @@ -719,21 +434,20 @@ dispose (GObject *object) { NMModemManager *self = NM_MODEM_MANAGER (object); - /* ModemManager < 0.7 */ - clear_modem_manager_support (self); + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; + } -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - clear_modem_manager_1_support (self); -#endif + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); + g_clear_object (&self->priv->dbus_connection); if (self->priv->modems) { g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, object); g_hash_table_destroy (self->priv->modems); } - self->priv->dbus_mgr = NULL; - /* Chain up to the parent class */ G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object); } diff --git a/src/devices/wwan/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h index 3082bdb3..9e0db41e 100644 --- a/src/devices/wwan/nm-modem-manager.h +++ b/src/devices/wwan/nm-modem-manager.h @@ -20,8 +20,8 @@ * Copyright (C) 2009 Canonical Ltd. */ -#ifndef NM_MODEM_MANAGER_H -#define NM_MODEM_MANAGER_H +#ifndef __NETWORKMANAGER_MODEM_MANAGER_H__ +#define __NETWORKMANAGER_MODEM_MANAGER_H__ #include <glib-object.h> #include "nm-modem.h" @@ -46,4 +46,4 @@ typedef struct { GType nm_modem_manager_get_type (void); -#endif /* NM_MODEM_MANAGER_H */ +#endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */ diff --git a/src/devices/wwan/nm-modem-old-types.h b/src/devices/wwan/nm-modem-old-types.h deleted file mode 100644 index 84065a68..00000000 --- a/src/devices/wwan/nm-modem-old-types.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- 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 (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_TYPES_H -#define NM_MODEM_OLD_TYPES_H - -#define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_PATH "/org/freedesktop/ModemManager" -#define MM_OLD_DBUS_INTERFACE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" -#define MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE "org.freedesktop.ModemManager.Modem.Simple" -#define MM_OLD_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" - -#define MM_OLD_MODEM_TYPE_UNKNOWN 0 -#define MM_OLD_MODEM_TYPE_GSM 1 -#define MM_OLD_MODEM_TYPE_CDMA 2 - -/* Errors */ - -#define MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER MM_OLD_DBUS_INTERFACE_MODEM ".NoCarrier" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE MM_OLD_DBUS_INTERFACE_MODEM ".NoDialtone" -#define MM_OLD_MODEM_CONNECT_ERROR_BUSY MM_OLD_DBUS_INTERFACE_MODEM ".Busy" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER MM_OLD_DBUS_INTERFACE_MODEM ".NoAnswer" - -#define MM_OLD_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" - -#define MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_OLD_MODEM_ERROR ".NetworkNotAllowed" -#define MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT MM_OLD_MODEM_ERROR ".NetworkTimeout" -#define MM_OLD_MODEM_ERROR_NO_NETWORK MM_OLD_MODEM_ERROR ".NoNetwork" -#define MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED MM_OLD_MODEM_ERROR ".SimNotInserted" -#define MM_OLD_MODEM_ERROR_SIM_PIN MM_OLD_MODEM_ERROR ".SimPinRequired" -#define MM_OLD_MODEM_ERROR_SIM_PUK MM_OLD_MODEM_ERROR ".SimPukRequired" -#define MM_OLD_MODEM_ERROR_SIM_WRONG MM_OLD_MODEM_ERROR ".SimWrong" -#define MM_OLD_MODEM_ERROR_WRONG_PASSWORD MM_OLD_MODEM_ERROR ".IncorrectPassword" - -typedef enum { - MM_OLD_MODEM_STATE_UNKNOWN = 0, - MM_OLD_MODEM_STATE_DISABLED = 10, - MM_OLD_MODEM_STATE_DISABLING = 20, - MM_OLD_MODEM_STATE_ENABLING = 30, - MM_OLD_MODEM_STATE_ENABLED = 40, - MM_OLD_MODEM_STATE_SEARCHING = 50, - MM_OLD_MODEM_STATE_REGISTERED = 60, - MM_OLD_MODEM_STATE_DISCONNECTING = 70, - MM_OLD_MODEM_STATE_CONNECTING = 80, - MM_OLD_MODEM_STATE_CONNECTED = 90, - - MM_OLD_MODEM_STATE_LAST = MM_OLD_MODEM_STATE_CONNECTED -} MMOldModemState; - -#endif /* NM_MODEM_OLD_TYPES_H */ diff --git a/src/devices/wwan/nm-modem-old.c b/src/devices/wwan/nm-modem-old.c deleted file mode 100644 index ce1a382e..00000000 --- a/src/devices/wwan/nm-modem-old.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* -*- 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 (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#include <string.h> -#include <glib/gi18n.h> - -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-setting-connection.h" -#include "nm-properties-changed-signal.h" -#include "nm-modem-old-types.h" -#include "nm-logging.h" -#include "NetworkManagerUtils.h" -#include "nm-device-private.h" -#include "nm-dbus-glib-types.h" -#include "nm-glib-compat.h" - -G_DEFINE_TYPE (NMModemOld, nm_modem_old, NM_TYPE_MODEM) - -#define NM_MODEM_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OLD, NMModemOldPrivate)) - -typedef struct { - DBusGProxy *proxy; - DBusGProxy *props_proxy; - - MMOldModemState state; - NMDeviceModemCapabilities caps; - char *unlock_required; - - DBusGProxyCall *call; - GHashTable *connect_properties; - - guint32 pin_tries; - guint enable_delay_id; -} NMModemOldPrivate; - -#define CAPS_3GPP (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE) - -/*****************************************************************************/ - -typedef enum { - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY = 0, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_GPRS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_EDGE, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_UMTS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSDPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA, - - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA -} MMModemDeprecatedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_MODE_ANY = 0, - MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED = 1, - MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED = 2, - MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY = 3, - MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY = 4, - MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED = 5, - MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY = 6, - - MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY -} MMModemGsmAllowedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN = 0x0000, - /* bits 0..4 order match Ericsson device bitmap */ - MM_MODEM_GSM_ALLOWED_AUTH_NONE = 0x0001, - MM_MODEM_GSM_ALLOWED_AUTH_PAP = 0x0002, - MM_MODEM_GSM_ALLOWED_AUTH_CHAP = 0x0004, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP = 0x0008, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2 = 0x0010, - MM_MODEM_GSM_ALLOWED_AUTH_EAP = 0x0020, - - MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP -} MMModemGsmAllowedAuth; - -static NMDeviceStateReason -translate_mm_error (GError *error) -{ - NMDeviceStateReason reason; - - if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_BUSY)) - reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER)) - reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NO_NETWORK)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PUK)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_WRONG_PASSWORD)) - reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT; - else { - /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ - nm_log_dbg (LOGD_MB, "unmapped dbus error detected: '%s'", dbus_g_error_get_name (error)); - reason = NM_DEVICE_STATE_REASON_UNKNOWN; - } - - /* FIXME: We have only GSM error messages here, and we have no idea which - activation state failed. Reasons like: - NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, - NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, - NM_DEVICE_STATE_REASON_GSM_APN_FAILED, - NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, - NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED - are not used. - */ - return reason; -} - -#define MAP_STATE(name) case MM_OLD_MODEM_STATE_##name: return NM_MODEM_STATE_##name; - -static NMModemState -mm_state_to_nm (MMOldModemState mm_state, const char *unlock_required) -{ - if (unlock_required && *unlock_required) - return NM_MODEM_STATE_LOCKED; - - switch (mm_state) { - MAP_STATE(UNKNOWN) - MAP_STATE(DISABLED) - MAP_STATE(DISABLING) - MAP_STATE(ENABLING) - MAP_STATE(ENABLED) - MAP_STATE(SEARCHING) - MAP_STATE(REGISTERED) - MAP_STATE(DISCONNECTING) - MAP_STATE(CONNECTING) - MAP_STATE(CONNECTED) - } - return NM_MODEM_STATE_UNKNOWN; -}; - -/*****************************************************************************/ - -static DBusGProxy * -nm_modem_old_get_proxy (NMModemOld *self, const char *interface) -{ - - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *current_iface; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), NULL); - - /* Default to the default interface. */ - if (interface == NULL) - interface = MM_OLD_DBUS_INTERFACE_MODEM; - - if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES)) - return priv->props_proxy; - - current_iface = dbus_g_proxy_get_interface (priv->proxy); - if (!current_iface || strcmp (current_iface, interface)) - dbus_g_proxy_set_interface (priv->proxy, interface); - - return priv->proxy; -} - -/*****************************************************************************/ -/* Query/Update enabled state */ - -static void -set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - nm_modem_set_prev_state (NM_MODEM (user_data), "enable/disable failed"); - } - /* Wait for the state change signal to indicate enabled state changed */ -} - -static void -set_mm_enabled (NMModem *self, gboolean enabled) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM), - "Enable", set_mm_enabled_done, - g_object_ref (self), g_object_unref, - G_TYPE_BOOLEAN, enabled, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -ask_for_pin (NMModemOld *self, gboolean always_ask) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - guint32 tries = 0; - - g_return_if_fail (NM_IS_MODEM_OLD (self)); - - if (!always_ask) - tries = priv->pin_tries++; - - nm_modem_get_secrets (NM_MODEM (self), - NM_SETTING_GSM_SETTING_NAME, - (tries || always_ask) ? TRUE : FALSE, - NM_SETTING_GSM_PIN); -} - -static void -stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GError *error = NULL; - gboolean asked = FALSE; - - priv->call = NULL; - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); - else { - if (priv->caps & CAPS_3GPP) { - if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) { - ask_for_pin (self, FALSE); - asked = TRUE; - } else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) { - ask_for_pin (self, TRUE); - asked = TRUE; - } - } - - if (!asked) { - nm_log_warn (LOGD_MB, "Mobile connection failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); - } - g_error_free (error); - } -} - -static void -do_connect (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - DBusGProxy *proxy; - - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); - priv->call = dbus_g_proxy_begin_call_with_timeout (proxy, - "Connect", stage1_prepare_done, - self, NULL, 120000, - DBUS_TYPE_G_MAP_OF_VARIANT, priv->connect_properties, - G_TYPE_INVALID); -} - -static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data); - -/* do_enable() is used as a GSourceFunc, hence the gboolean return */ -static gboolean -do_enable (NMModemOld *self) -{ - DBusGProxy *proxy; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), FALSE); - - NM_MODEM_OLD_GET_PRIVATE (self)->enable_delay_id = 0; - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM); - dbus_g_proxy_begin_call_with_timeout (proxy, - "Enable", stage1_enable_done, - self, NULL, 20000, - G_TYPE_BOOLEAN, TRUE, - G_TYPE_INVALID); - return FALSE; -} - -static void -stage1_pin_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - /* Success; try to enable the modem again. Wait a few seconds to ensure - * that ModemManager is ready for the enable right after the unlock. - */ - if (priv->enable_delay_id == 0) - priv->enable_delay_id = g_timeout_add_seconds (4, (GSourceFunc) do_enable, self); - } else { - nm_log_warn (LOGD_MB, "GSM PIN unlock failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - g_error_free (error); - } -} - -static void -handle_enable_pin_required (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *pin = NULL; - GValue *value; - DBusGProxy *proxy; - - g_assert (priv->caps & CAPS_3GPP); - - /* See if we have a PIN already */ - value = g_hash_table_lookup (priv->connect_properties, "pin"); - if (value && G_VALUE_HOLDS_STRING (value)) - pin = g_value_get_string (value); - - /* If we do, send it */ - if (pin) { - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD); - dbus_g_proxy_begin_call_with_timeout (proxy, - "SendPin", stage1_pin_done, - self, NULL, 10000, - G_TYPE_STRING, pin, - G_TYPE_INVALID); - } else - ask_for_pin (self, FALSE); -} - -static void -stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) - do_connect (self); - else { - if ((priv->caps & CAPS_3GPP) && dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - handle_enable_pin_required (self); - else { - nm_log_warn (LOGD_MB, "Modem enable failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - } - - g_error_free (error); - } -} - -static GHashTable * -create_connect_properties (NMConnection *connection) -{ - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - NMSettingPPP *s_ppp; - GHashTable *properties; - const char *str; - - properties = value_hash_create (); - - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - str = nm_setting_cdma_get_number (s_cdma); - if (str) - value_hash_add_str (properties, "number", str); - return properties; - } - - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - str = nm_setting_gsm_get_number (s_gsm); - if (str) - value_hash_add_str (properties, "number", str); - - str = nm_setting_gsm_get_apn (s_gsm); - if (str) - value_hash_add_str (properties, "apn", str); - - str = nm_setting_gsm_get_network_id (s_gsm); - if (str) - value_hash_add_str (properties, "network_id", str); - - str = nm_setting_gsm_get_pin (s_gsm); - if (str) - value_hash_add_str (properties, "pin", str); - - str = nm_setting_gsm_get_username (s_gsm); - if (str) - value_hash_add_str (properties, "username", str); - - str = nm_setting_gsm_get_password (s_gsm); - if (str) - value_hash_add_str (properties, "password", str); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* Add both old and new preferred modes */ - switch (nm_setting_gsm_get_network_type (s_gsm)) { - case NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY); - break; - default: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_ANY); - break; - } -G_GNUC_END_IGNORE_DEPRECATIONS - - /* Roaming */ - if (nm_setting_gsm_get_home_only (s_gsm)) - value_hash_add_bool (properties, "home_only", TRUE); - - /* For IpMethod == STATIC or DHCP */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - guint32 auth = MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN; - - if (nm_setting_ppp_get_noauth (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_NONE; - if (!nm_setting_ppp_get_refuse_pap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_PAP; - if (!nm_setting_ppp_get_refuse_chap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_CHAP; - if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP; - if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2; - if (!nm_setting_ppp_get_refuse_eap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_EAP; - - if (auth != MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN) - value_hash_add_uint (properties, "allowed_auth", auth); - } - - return properties; - } - - g_hash_table_destroy (properties); - return NULL; -} - -static NMActStageReturn -act_stage1_prepare (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *reason) -{ - NMModemOld *self = NM_MODEM_OLD (modem); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - if (priv->connect_properties) - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = create_connect_properties (connection); - - if (nm_modem_get_state (modem) >= NM_MODEM_STATE_ENABLING) - do_connect (self); - else - do_enable (self); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ -/* IP method static */ - -static char addr_to_string_buf[INET6_ADDRSTRLEN + 1]; - -static const char * -ip_address_to_string (guint32 numeric) -{ - guint32 temp_addr; - - memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf)); - temp_addr = numeric; - - if (inet_ntop (AF_INET, &temp_addr, addr_to_string_buf, INET_ADDRSTRLEN)) { - return addr_to_string_buf; - } else { - nm_log_warn (LOGD_VPN, "error converting IP4 address 0x%X", - ntohl (temp_addr)); - return NULL; - } -} - -static void -static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValueArray *ret_array = NULL; - GError *error = NULL; - NMIP4Config *config = NULL; - - priv->call = NULL; - - /* Returned value array is (uuuu): [IP, DNS1, DNS2, DNS3], all in - * network byte order. - */ - if (dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_VALUE_ARRAY, &ret_array, - G_TYPE_INVALID)) { - NMPlatformIP4Address address; - int i; - - config = nm_ip4_config_new (); - memset (&address, 0, sizeof (address)); - - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", - nm_modem_get_uid (NM_MODEM (self))); - - /* IP address */ - address.address = g_value_get_uint (g_value_array_get_nth (ret_array, 0)); - address.plen = 32; - address.source = NM_PLATFORM_SOURCE_WWAN; - nm_ip4_config_add_address (config, &address); - - nm_log_info (LOGD_MB, " address %s/%d", - ip_address_to_string (address.address), - address.plen); - - /* DNS servers */ - for (i = 1; i < ret_array->n_values; i++) { - GValue *value = g_value_array_get_nth (ret_array, i); - guint32 tmp = g_value_get_uint (value); - - if (tmp > 0) { - nm_ip4_config_add_nameserver (config, tmp); - nm_log_info (LOGD_MB, " DNS %s", ip_address_to_string (tmp)); - } - } - g_value_array_free (ret_array); - } - - g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, config, error); - g_clear_error (&error); -} - -static NMActStageReturn -static_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) -{ - NMModemOldPrivate *priv; - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->call = dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "GetIP4Config", static_stage3_done, - self, NULL, - G_TYPE_INVALID); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ - -static void -disconnect_done (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) -{ - GError *error = NULL; - gboolean warn = GPOINTER_TO_UINT (user_data); - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) && warn) { - nm_log_info (LOGD_MB, "disconnect failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } -} - -static void -disconnect (NMModem *self, - gboolean warn) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "Disconnect", - disconnect_done, - GUINT_TO_POINTER (warn), - NULL, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -deactivate (NMModem *self, NMDevice *device) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->pin_tries = 0; - - if (priv->call) { - dbus_g_proxy_cancel_call (priv->proxy, priv->call); - priv->call = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - /* Chain up parent */ - NM_MODEM_CLASS (nm_modem_old_parent_class)->deactivate (self, device); -} - -/*****************************************************************************/ - -static void -modem_properties_changed (DBusGProxy *proxy, - const char *interface, - GHashTable *props, - gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValue *value; - gboolean update_state = FALSE; - - if (strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM) && - strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD)) - return; - - value = g_hash_table_lookup (props, "IpMethod"); - if (value && G_VALUE_HOLDS_UINT (value)) { - g_object_set (self, - NM_MODEM_IP_METHOD, g_value_get_uint (value), - NULL); - } - - value = g_hash_table_lookup (props, "SimIdentifier"); - if (value && G_VALUE_HOLDS_STRING (value)) { - const char *sim_id = g_value_get_string (value); - - g_object_set (self, - NM_MODEM_SIM_ID, (sim_id && *sim_id) ? sim_id : NULL, - NULL); - } - - value = g_hash_table_lookup (props, "UnlockRequired"); - if (value && G_VALUE_HOLDS_STRING (value)) { - g_free (priv->unlock_required); - priv->unlock_required = g_value_dup_string (value); - update_state = TRUE; - } - - value = g_hash_table_lookup (props, "State"); - if (value && G_VALUE_HOLDS_UINT (value)) { - priv->state = g_value_get_uint (value); - update_state = TRUE; - } - - if (update_state) { - nm_modem_set_state (NM_MODEM (self), - mm_state_to_nm (priv->state, priv->unlock_required), - NULL); - } -} - -/*****************************************************************************/ - -static gboolean -check_connection_compatible (NMModem *modem, NMConnection *connection) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingConnection *s_con; - gboolean valid_cdma = FALSE, valid_gsm = FALSE; - const char *ctype; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - ctype = nm_setting_connection_get_connection_type (s_con); - g_assert (ctype); - - /* Check for valid CDMA first */ - if (strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) == 0) - valid_cdma = !!nm_connection_get_setting_cdma (connection); - - if (strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) == 0) - valid_gsm = !!nm_connection_get_setting_gsm (connection); - - /* Validate CDMA */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - if (valid_cdma) - return TRUE; - - /* If the modem is only CDMA and the connection is not CDMA, error */ - if ((priv->caps ^ NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) == 0) - return FALSE; - } - - /* Validate 3GPP */ - if (priv->caps & CAPS_3GPP) - return valid_gsm; - - return FALSE; -} - -/*****************************************************************************/ - -static void -complete_ppp_setting (NMConnection *connection) -{ - NMSettingPPP *s_ppp; - - s_ppp = nm_connection_get_setting_ppp (connection); - if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); - g_object_set (G_OBJECT (s_ppp), - NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, - NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - } -} - -static gboolean -complete_connection_3gpp (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingGsm *s_gsm; - - s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ - g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); - return FALSE; - } - - if (!nm_setting_gsm_get_number (s_gsm)) - g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_GSM_SETTING_NAME, - existing_connections, - _("GSM connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection_cdma (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingCdma *s_cdma; - - s_cdma = nm_connection_get_setting_cdma (connection); - if (!s_cdma) { - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - } - - if (!nm_setting_cdma_get_number (s_cdma)) - g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_CDMA_SETTING_NAME, - existing_connections, - _("CDMA connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection (NMModem *modem, - NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - - /* If the modem has LTE, complete as 3GPP */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_LTE) - return complete_connection_3gpp (connection, existing_connections, error); - - /* Otherwise, prefer CDMA on the theory that if the modem has CDMA/EVDO - * that's most likely what the user will be using. - */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) - return complete_connection_cdma (connection, existing_connections, error); - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) - return complete_connection_3gpp (connection, existing_connections, error); - - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, - "Modem had no WWAN capabilities."); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - if (user) - *user = nm_setting_cdma_get_username (s_cdma); - if (pass) - *pass = nm_setting_cdma_get_password (s_cdma); - return TRUE; - } - } - - /* Fall back to GSM; will be used for CDMA devices on LTE networks too */ - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - if (user) - *user = nm_setting_gsm_get_username (s_gsm); - if (pass) - *pass = nm_setting_gsm_get_password (s_gsm); - return TRUE; - } - - return FALSE; -} - -/*****************************************************************************/ - -static void -get_capabilities (NMModem *_self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) -{ - NMModemOld *self = NM_MODEM_OLD (_self); - - *current_caps = *modem_caps = NM_MODEM_OLD_GET_PRIVATE (self)->caps; -} - -/*****************************************************************************/ - -NMModem * -nm_modem_old_new (const char *path, GHashTable *properties, GError **error) -{ - NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; - NMModemOld *self; - GHashTableIter iter; - const char *prop; - GValue *value; - const char *data_device = NULL; - const char *driver = NULL; - const char *master_device = NULL; - const char *unlock_required = NULL; - const char *device_id = NULL; - guint32 modem_type = MM_OLD_MODEM_TYPE_UNKNOWN; - guint32 ip_method = MM_MODEM_IP_METHOD_PPP; - guint32 ip_timeout = 0; - MMOldModemState state = MM_OLD_MODEM_STATE_UNKNOWN; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (properties != NULL, NULL); - - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, (gpointer) &prop, (gpointer) &value)) { - if (g_strcmp0 (prop, "Type") == 0) - modem_type = g_value_get_uint (value); - else if (g_strcmp0 (prop, "MasterDevice") == 0) - master_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpMethod") == 0) - ip_method = g_value_get_uint (value); - else if (g_strcmp0 (prop, "Device") == 0) - data_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "Driver") == 0) - driver = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpTimeout") == 0) - ip_timeout = g_value_get_uint (value); - else if (g_strcmp0 (prop, "State") == 0) - state = g_value_get_uint (value); - else if (g_strcmp0 (prop, "UnlockRequired") == 0) - unlock_required = g_value_get_string (value); - else if (g_strcmp0 (prop, "DeviceIdentifier") == 0) - device_id = g_value_get_string (value); - } - - if (modem_type == MM_OLD_MODEM_TYPE_UNKNOWN) { - g_set_error (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Unhandled modem type %d", modem_type); - return NULL; - } - - if (!master_device || !strlen (master_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem master device."); - return NULL; - } - - if (!driver || !strlen (driver)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem driver."); - return NULL; - } - - if (!data_device || !strlen (data_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem data device."); - return NULL; - } - - self = (NMModemOld *) g_object_new (NM_TYPE_MODEM_OLD, - NM_MODEM_PATH, path, - NM_MODEM_DRIVER, driver, - NM_MODEM_UID, data_device, - NM_MODEM_CONTROL_PORT, NULL, - NM_MODEM_DATA_PORT, data_device, - NM_MODEM_IP_METHOD, ip_method, - NM_MODEM_IP_TIMEOUT, ip_timeout, - NM_MODEM_DEVICE_ID, device_id, - NM_MODEM_STATE, mm_state_to_nm (state, unlock_required), - NULL); - if (self) { - if (modem_type == MM_OLD_MODEM_TYPE_CDMA) - caps |= NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO; - if (modem_type == MM_OLD_MODEM_TYPE_GSM) - caps |= NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; - - NM_MODEM_OLD_GET_PRIVATE (self)->caps = caps; - NM_MODEM_OLD_GET_PRIVATE (self)->state = state; - NM_MODEM_OLD_GET_PRIVATE (self)->unlock_required = g_strdup (unlock_required); - } - - return (NMModem *) self; -} - -static void -nm_modem_old_init (NMModemOld *self) -{ -} - -static void -get_sim_id_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - GValue value = G_VALUE_INIT; - - if (dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - if (G_VALUE_HOLDS_STRING (&value)) { - const char *sim_id = g_value_get_string (&value); - - if (sim_id && *sim_id) - g_object_set (G_OBJECT (self), NM_MODEM_SIM_ID, sim_id, NULL); - } - g_value_unset (&value); - } -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMModemOldPrivate *priv; - DBusGConnection *bus; - - object = G_OBJECT_CLASS (nm_modem_old_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - priv = NM_MODEM_OLD_GET_PRIVATE (object); - - bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - priv->proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - MM_OLD_DBUS_INTERFACE_MODEM); - - priv->props_proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - DBUS_INTERFACE_PROPERTIES); - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged", - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged", - G_CALLBACK (modem_properties_changed), - object, - NULL); - - /* Request the SIM ID */ - dbus_g_proxy_begin_call (priv->props_proxy, - "Get", - get_sim_id_done, - g_object_ref (object), g_object_unref, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD, - G_TYPE_STRING, "SimIdentifier", - G_TYPE_INVALID); - - return object; -} - -static void -dispose (GObject *object) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (object); - - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; - } - - if (priv->props_proxy) { - g_object_unref (priv->props_proxy); - priv->props_proxy = NULL; - } - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - g_free (priv->unlock_required); - priv->unlock_required = NULL; - - G_OBJECT_CLASS (nm_modem_old_parent_class)->dispose (object); -} - -static void -nm_modem_old_class_init (NMModemOldClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMModemClass *modem_class = NM_MODEM_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMModemOldPrivate)); - - /* Virtual methods */ - object_class->constructor = constructor; - object_class->dispose = dispose; - - modem_class->get_capabilities = get_capabilities; - modem_class->get_user_pass = get_user_pass; - modem_class->complete_connection = complete_connection; - modem_class->check_connection_compatible = check_connection_compatible; - modem_class->act_stage1_prepare = act_stage1_prepare; - modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; - modem_class->disconnect = disconnect; - modem_class->deactivate = deactivate; - modem_class->set_mm_enabled = set_mm_enabled; -} diff --git a/src/devices/wwan/nm-modem-old.h b/src/devices/wwan/nm-modem-old.h deleted file mode 100644 index 65e3db2d..00000000 --- a/src/devices/wwan/nm-modem-old.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- 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 (C) 2009 - 2011 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_H -#define NM_MODEM_OLD_H - -#include <dbus/dbus-glib.h> -#include <glib-object.h> -#include "nm-modem.h" -#include "nm-modem-old-types.h" - -G_BEGIN_DECLS - -#define NM_TYPE_MODEM_OLD (nm_modem_old_get_type ()) -#define NM_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OLD, NMModemOld)) -#define NM_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OLD, NMModemOldClass)) -#define NM_IS_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OLD)) -#define NM_IS_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OLD)) -#define NM_MODEM_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OLD, NMModemOldClass)) - -typedef struct { - NMModem parent; -} NMModemOld; - -typedef struct { - NMModemClass parent; -} NMModemOldClass; - -GType nm_modem_old_get_type (void); - -NMModem *nm_modem_old_new (const char *path, GHashTable *properties, GError **error); - -G_END_DECLS - -#endif /* NM_MODEM_OLD_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index fd3b4a36..ba1db8a4 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -19,6 +19,8 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include <string.h> #include "nm-modem.h" #include "nm-platform.h" @@ -42,11 +44,13 @@ enum { PROP_PATH, PROP_UID, PROP_DRIVER, - PROP_IP_METHOD, + PROP_IP4_METHOD, + PROP_IP6_METHOD, PROP_IP_TIMEOUT, PROP_STATE, PROP_DEVICE_ID, PROP_SIM_ID, + PROP_IP_TYPES, LAST_PROP }; @@ -58,11 +62,14 @@ typedef struct { char *control_port; char *data_port; char *ppp_iface; - guint32 ip_method; + NMModemIPMethod ip4_method; + NMModemIPMethod ip6_method; + NMUtilsIPv6IfaceId iid; NMModemState state; NMModemState prev_state; /* revert to this state if enable/disable fails */ char *device_id; char *sim_id; + NMModemIPType ip_types; NMPPPManager *ppp_manager; @@ -82,6 +89,7 @@ enum { PPP_FAILED, PREPARE_RESULT, IP4_CONFIG_RESULT, + IP6_CONFIG_RESULT, AUTH_REQUESTED, AUTH_RESULT, REMOVED, @@ -94,17 +102,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; /*****************************************************************************/ - -GQuark -nm_modem_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-modem-error"); - return quark; -} - -/*****************************************************************************/ /* State/enabled/connected */ static const char *state_table[] = { @@ -126,7 +123,7 @@ static const char *state_table[] = { const char * nm_modem_state_to_string (NMModemState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return NULL; } @@ -218,6 +215,102 @@ nm_modem_emit_removed (NMModem *self) g_signal_emit (self, signals[REMOVED], 0); } +NMModemIPType +nm_modem_get_supported_ip_types (NMModem *self) +{ + return NM_MODEM_GET_PRIVATE (self)->ip_types; +} + +/** + * nm_modem_get_connection_ip_type: + * @self: the #NMModem + * @connection: the #NMConnection to determine IP type to use + * + * Given a modem and a connection, determine which NMModemIpType to use + * when connecting. + * + * Returns: a single %NMModemIpType value + */ +NMModemIPType +nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMSettingIPConfig *s_ip4, *s_ip6; + const char *method; + gboolean ip4 = TRUE, ip6 = TRUE; + gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4) { + method = nm_setting_ip_config_get_method (s_ip4); + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + ip4 = FALSE; + ip4_may_fail = nm_setting_ip_config_get_may_fail (s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) { + method = nm_setting_ip_config_get_method (s_ip6); + if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + ip6 = FALSE; + ip6_may_fail = nm_setting_ip_config_get_may_fail (s_ip6); + } + + if (ip4 && !ip6) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv4 but IPv4 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV4; + } + + if (ip6 && !ip4) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv6 but IPv6 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV6; + } + + if (ip4 && ip6) { + /* Modem supports dual-stack */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) + return NM_MODEM_IP_TYPE_IPV4V6; + + /* Both IPv4 and IPv6 requested, but modem doesn't support dual-stack; + * if one method is marked "may-fail" then use the other. + */ + if (ip6_may_fail) + return NM_MODEM_IP_TYPE_IPV4; + else if (ip4_may_fail) + return NM_MODEM_IP_TYPE_IPV6; + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested both IPv4 and IPv6 " + "but dual-stack addressing is unsupported " + "by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection specified no IP configuration!"); + return NM_MODEM_IP_TYPE_UNKNOWN; +} + /*****************************************************************************/ /* IP method PPP */ @@ -237,13 +330,24 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ } static void +set_data_port (NMModem *self, const char *new_data_port) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + + if (g_strcmp0 (priv->data_port, new_data_port) != 0) { + g_free (priv->data_port); + priv->data_port = g_strdup (new_data_port); + g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + } +} + +static void ppp_ip4_config (NMPPPManager *ppp_manager, const char *iface, NMIP4Config *config, gpointer user_data) { NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); guint32 i, num; guint32 bad_dns1 = htonl (0x0A0B0C0D); guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ @@ -252,9 +356,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gboolean dns_workaround = FALSE; /* Notify about the new data port to use */ - g_free (priv->ppp_iface); - priv->ppp_iface = g_strdup (iface); - g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + set_data_port (self, iface); /* Work around a PPP bug (#1732) which causes many mobile broadband * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. @@ -296,6 +398,23 @@ ppp_ip4_config (NMPPPManager *ppp_manager, } static void +ppp_ip6_config (NMPPPManager *ppp_manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config, + gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + + /* Notify about the new data port to use */ + set_data_port (self, iface); + + NM_MODEM_GET_PRIVATE (self)->iid = *iid; + + nm_modem_emit_ip6_config_result (self, config, NULL); +} + +static void ppp_stats (NMPPPManager *ppp_manager, guint32 in_bytes, guint32 out_bytes, @@ -313,20 +432,27 @@ ppp_stats (NMPPPManager *ppp_manager, } static NMActStageReturn -ppp_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) +ppp_stage3_ip_config_start (NMModem *self, + NMActRequest *req, + NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; - guint ip_timeout = 20; + guint ip_timeout = 30; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* If we're already running PPP don't restart it; for example, if both + * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the + * same pppd for both v4 and v6. + */ + if (priv->ppp_manager) + return NM_ACT_STAGE_RETURN_POSTPONE; + if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); @@ -336,7 +462,7 @@ ppp_stage3_ip4_config_start (NMModem *self, } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, - * use the default one (20s) */ + * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); @@ -351,6 +477,9 @@ ppp_stage3_ip4_config_start (NMModem *self, g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); + g_signal_connect (priv->ppp_manager, "ip6-config", + G_CALLBACK (ppp_ip6_config), + self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); @@ -382,6 +511,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, { NMModemPrivate *priv; NMActRequest *req; + NMConnection *connection; + const char *method; NMActStageReturn ret; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -391,21 +522,36 @@ nm_modem_stage3_ip4_config_start (NMModem *self, req = nm_device_get_act_request (device); g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + + /* Only Disabled and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP4, + "(%s): unhandled WWAN IPv4 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip4_config_start (self, req, reason); + switch (priv->ip4_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_STATIC: ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_DHCP: + case NM_MODEM_IP_METHOD_AUTO: ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - ret = NM_ACT_STAGE_RETURN_FAILURE; + nm_log_info (LOGD_MB, "(%s): IPv4 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; break; } @@ -423,8 +569,8 @@ nm_modem_ip4_pre_commit (NMModem *modem, * not point-to-point) and IP config has a /32 prefix, then we assume that * ARP will be pointless and we turn it off. */ - if ( priv->ip_method == MM_MODEM_IP_METHOD_STATIC - || priv->ip_method == MM_MODEM_IP_METHOD_DHCP) { + if ( priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, 0); g_assert (address); @@ -435,15 +581,100 @@ nm_modem_ip4_pre_commit (NMModem *modem, /*****************************************************************************/ +void +nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + guint i, num; + gboolean do_slaac = TRUE; + + if (error) { + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); + return; + } + + if (config) { + /* If the IPv6 configuration only included a Link-Local address, then + * we have to run SLAAC to get the full IPv6 configuration. + */ + num = nm_ip6_config_get_num_addresses (config); + g_assert (num > 0); + for (i = 0; i < num; i++) { + const NMPlatformIP6Address * addr = nm_ip6_config_get_address (config, i); + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + if (!priv->iid.id) + priv->iid.id = ((guint64 *)(&addr->address.s6_addr))[1]; + } else + do_slaac = FALSE; + } + } + g_assert (config || do_slaac); + + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *self, NMDeviceStateReason *reason) +{ + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; +} + NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason) { - /* FIXME: We don't support IPv6 on modems quite yet... */ - nm_device_activate_schedule_ip6_config_timeout (device); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMModemPrivate *priv; + NMActStageReturn ret; + NMConnection *connection; + const char *method; + + g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + + /* Only Ignore and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP6, + "(%s): unhandled WWAN IPv6 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE (self); + switch (priv->ip6_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_AUTO: + /* Both static and DHCP/Auto retrieve a base IP config from the modem + * which in the static case is the full config, and the DHCP/Auto case + * is just the IPv6LL address to use for SLAAC. + */ + ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, reason); + break; + default: + nm_log_info (LOGD_MB, "(%s): IPv6 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; + break; + } + + return ret; } /*****************************************************************************/ @@ -486,12 +717,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -524,7 +755,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; NMConnection *connection; if (priv->act_request) @@ -543,7 +774,7 @@ nm_modem_act_stage1_prepare (NMModem *self, /* Secrets required... */ if (priv->secrets_tries++) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, @@ -633,22 +864,19 @@ deactivate (NMModem *self, NMDevice *device) priv->ppp_manager = NULL; } - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - break; - case MM_MODEM_IP_METHOD_STATIC: - case MM_MODEM_IP_METHOD_DHCP: + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || + priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { ifindex = nm_device_get_ip_ifindex (device); if (ifindex > 0) { nm_platform_route_flush (ifindex); nm_platform_address_flush (ifindex); nm_platform_link_set_down (ifindex); } - break; - default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - break; } + priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_free (priv->ppp_iface); priv->ppp_iface = NULL; @@ -772,6 +1000,15 @@ nm_modem_owns_port (NMModem *self, const char *iface) return FALSE; } +gboolean +nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid) +{ + g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + + *out_iid = NM_MODEM_GET_PRIVATE (self)->iid; + return TRUE; +} + /*****************************************************************************/ void @@ -846,8 +1083,11 @@ get_property (GObject *object, guint prop_id, case PROP_UID: g_value_set_string (value, priv->uid); break; - case PROP_IP_METHOD: - g_value_set_uint (value, priv->ip_method); + case PROP_IP4_METHOD: + g_value_set_uint (value, priv->ip4_method); + break; + case PROP_IP6_METHOD: + g_value_set_uint (value, priv->ip6_method); break; case PROP_IP_TIMEOUT: g_value_set_uint (value, priv->mm_ip_timeout); @@ -861,6 +1101,9 @@ get_property (GObject *object, guint prop_id, case PROP_SIM_ID: g_value_set_string (value, priv->sim_id); break; + case PROP_IP_TYPES: + g_value_set_uint (value, priv->ip_types); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,8 +1135,11 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->uid = g_value_dup_string (value); break; - case PROP_IP_METHOD: - priv->ip_method = g_value_get_uint (value); + case PROP_IP4_METHOD: + priv->ip4_method = g_value_get_uint (value); + break; + case PROP_IP6_METHOD: + priv->ip6_method = g_value_get_uint (value); break; case PROP_IP_TIMEOUT: priv->mm_ip_timeout = g_value_get_uint (value); @@ -909,6 +1155,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->sim_id); priv->sim_id = g_value_dup_string (value); break; + case PROP_IP_TYPES: + priv->ip_types = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -959,92 +1208,100 @@ nm_modem_class_init (NMModemClass *klass) object_class->finalize = finalize; klass->act_stage1_prepare = act_stage1_prepare; + klass->stage3_ip6_config_request = stage3_ip6_config_request; klass->deactivate = deactivate; /* Properties */ g_object_class_install_property (object_class, PROP_UID, - g_param_spec_string (NM_MODEM_UID, - "UID", - "Modem unique ID", + g_param_spec_string (NM_MODEM_UID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_MODEM_PATH, - "DBus path", - "DBus path", + g_param_spec_string (NM_MODEM_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_MODEM_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_MODEM_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONTROL_PORT, - g_param_spec_string (NM_MODEM_CONTROL_PORT, - "Control port", - "The port controlling the modem", + g_param_spec_string (NM_MODEM_CONTROL_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DATA_PORT, - g_param_spec_string (NM_MODEM_DATA_PORT, - "Data port", - "The port to connect to", + g_param_spec_string (NM_MODEM_DATA_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property - (object_class, PROP_IP_METHOD, - g_param_spec_uint (NM_MODEM_IP_METHOD, - "IP method", - "IP method", - MM_MODEM_IP_METHOD_PPP, - MM_MODEM_IP_METHOD_DHCP, - MM_MODEM_IP_METHOD_PPP, - G_PARAM_READWRITE)); + (object_class, PROP_IP4_METHOD, + g_param_spec_uint (NM_MODEM_IP4_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP6_METHOD, + g_param_spec_uint (NM_MODEM_IP6_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_TIMEOUT, - g_param_spec_uint (NM_MODEM_IP_TIMEOUT, - "IP timeout", - "IP timeout", + g_param_spec_uint (NM_MODEM_IP_TIMEOUT, "", "", 0, 360, 20, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_enum (NM_MODEM_STATE, - "State", - "State", - NM_TYPE_MODEM_STATE, - NM_MODEM_STATE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_enum (NM_MODEM_STATE, "", "", + NM_TYPE_MODEM_STATE, + NM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_ID, - g_param_spec_string (NM_MODEM_DEVICE_ID, - "DeviceId", - "Device ID", + g_param_spec_string (NM_MODEM_DEVICE_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIM_ID, - g_param_spec_string (NM_MODEM_SIM_ID, - "SimId", - "Sim ID", + g_param_spec_string (NM_MODEM_SIM_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP_TYPES, + g_param_spec_uint (NM_MODEM_IP_TYPES, + "IP Types", + "Supported IP types", + 0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /* Signals */ @@ -1073,6 +1330,27 @@ nm_modem_class_init (NMModemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); + /** + * NMModem::ip6-config-result: + * @modem: the #NMModem on which the signal is emitted + * @config: the #NMIP6Config to apply to the modem's data port + * @do_slaac: %TRUE if IPv6 SLAAC should be started + * @error: a #GError if any error occurred during IP configuration + * + * This signal is emitted when IPv6 configuration has completed or failed. + * If @error is set the configuration failed. If @config is set, then + * the details should be applied to the data port before any further + * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC + * should be started after applying @config to the data port. + */ + signals[IP6_CONFIG_RESULT] = + g_signal_new (NM_MODEM_IP6_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ip6_config_result), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_POINTER); + signals[PREPARE_RESULT] = g_signal_new (NM_MODEM_PREPARE_RESULT, G_OBJECT_CLASS_TYPE (object_class), @@ -1112,8 +1390,4 @@ nm_modem_class_init (NMModemClass *klass) G_STRUCT_OFFSET (NMModemClass, state_changed), NULL, NULL, NULL, G_TYPE_NONE, 2, NM_TYPE_MODEM_STATE, NM_TYPE_MODEM_STATE); - - dbus_g_error_domain_register (NM_MODEM_ERROR, - NM_DBUS_INTERFACE_DEVICE_MODEM, - NM_TYPE_MODEM_ERROR); } diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c992cf72..2a4d9173 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -19,10 +19,9 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_MODEM_H -#define NM_MODEM_H +#ifndef __NETWORKMANAGER_MODEM_H__ +#define __NETWORKMANAGER_MODEM_H__ -#include <dbus/dbus-glib.h> #include <glib-object.h> #include "ppp-manager/nm-ppp-manager.h" #include "nm-device.h" @@ -42,33 +41,50 @@ G_BEGIN_DECLS #define NM_MODEM_DRIVER "driver" #define NM_MODEM_CONTROL_PORT "control-port" #define NM_MODEM_DATA_PORT "data-port" -#define NM_MODEM_IP_METHOD "ip-method" +#define NM_MODEM_IP4_METHOD "ip4-method" +#define NM_MODEM_IP6_METHOD "ip6-method" #define NM_MODEM_IP_TIMEOUT "ip-timeout" #define NM_MODEM_STATE "state" #define NM_MODEM_DEVICE_ID "device-id" #define NM_MODEM_SIM_ID "sim-id" +#define NM_MODEM_IP_TYPES "ip-types" /* Supported IP types */ /* Signals */ #define NM_MODEM_PPP_STATS "ppp-stats" #define NM_MODEM_PPP_FAILED "ppp-failed" #define NM_MODEM_PREPARE_RESULT "prepare-result" #define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result" +#define NM_MODEM_IP6_CONFIG_RESULT "ip6-config-result" #define NM_MODEM_AUTH_REQUESTED "auth-requested" #define NM_MODEM_AUTH_RESULT "auth-result" #define NM_MODEM_REMOVED "removed" #define NM_MODEM_STATE_CHANGED "state-changed" -#define MM_MODEM_IP_METHOD_PPP 0 -#define MM_MODEM_IP_METHOD_STATIC 1 -#define MM_MODEM_IP_METHOD_DHCP 2 - typedef enum { - NM_MODEM_ERROR_CONNECTION_NOT_GSM, /*< nick=ConnectionNotGsm >*/ - NM_MODEM_ERROR_CONNECTION_NOT_CDMA, /*< nick=ConnectionNotCdma >*/ - NM_MODEM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_MODEM_ERROR_INITIALIZATION_FAILED, /*< nick=InitializationFailed >*/ -} NMModemError; + NM_MODEM_IP_METHOD_UNKNOWN = 0, + NM_MODEM_IP_METHOD_PPP, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */ +} NMModemIPMethod; + +/** + * NMModemIPType: + * @NM_MODEM_IP_TYPE_UNKNOWN: unknown or no IP support + * @NM_MODEM_IP_TYPE_IPV4: IPv4-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV6: IPv6-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV4V6: dual-stack IPv4 + IPv6 bearers are supported + * + * Indicates what IP protocols the modem supports for an IP bearer. Any + * combination of flags is possible. For example, (%NM_MODEM_IP_TYPE_IPV4 | + * %NM_MODEM_IP_TYPE_IPV6) indicates that the modem supports IPv4 and IPv6 + * but not simultaneously on the same bearer. + */ +typedef enum { + NM_MODEM_IP_TYPE_UNKNOWN = 0x0, + NM_MODEM_IP_TYPE_IPV4 = 0x1, + NM_MODEM_IP_TYPE_IPV6 = 0x2, + NM_MODEM_IP_TYPE_IPV4V6 = 0x4 +} NMModemIPType; typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_UNKNOWN = 0, @@ -86,9 +102,6 @@ typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_CONNECTED = 12, } NMModemState; -#define NM_MODEM_ERROR (nm_modem_error_quark ()) -GQuark nm_modem_error_quark (void); - typedef struct { GObject parent; @@ -122,6 +135,12 @@ typedef struct { NMActRequest *req, NMDeviceStateReason *reason); + /* Request the IP6 config; when the config returns the modem + * subclass should emit the ip6_config_result signal. + */ + NMActStageReturn (*stage3_ip6_config_request) (NMModem *self, + NMDeviceStateReason *reason); + void (*set_mm_enabled) (NMModem *self, gboolean enabled); void (*disconnect) (NMModem *self, gboolean warn); @@ -136,6 +155,10 @@ typedef struct { void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason); void (*ip4_config_result) (NMModem *self, NMIP4Config *config, GError *error); + void (*ip6_config_result) (NMModem *self, + NMIP6Config *config, + gboolean do_slaac, + GError *error); void (*auth_requested) (NMModem *self); void (*auth_result) (NMModem *self, GError *error); @@ -154,6 +177,7 @@ const char *nm_modem_get_uid (NMModem *modem); const char *nm_modem_get_control_port (NMModem *modem); const char *nm_modem_get_data_port (NMModem *modem); const char *nm_modem_get_driver (NMModem *modem); +gboolean nm_modem_get_iid (NMModem *modem, NMUtilsIPv6IfaceId *out_iid); gboolean nm_modem_owns_port (NMModem *modem, const char *iface); @@ -182,8 +206,7 @@ NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem, NMDeviceStateReason *reason); NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason); void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config); @@ -209,9 +232,20 @@ void nm_modem_set_state (NMModem *self, void nm_modem_set_prev_state (NMModem *self, const char *reason); const char * nm_modem_state_to_string (NMModemState state); +NMModemIPType nm_modem_get_supported_ip_types (NMModem *self); + /* For the modem-manager only */ void nm_modem_emit_removed (NMModem *self); +NMModemIPType nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error); + +/* For subclasses */ +void nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error); + G_END_DECLS -#endif /* NM_MODEM_H */ +#endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index b1e2307e..2b9c3d4d 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -18,10 +18,11 @@ * Copyright (C) 2014 Red Hat, Inc. */ +#include "config.h" + #include <string.h> #include <gmodule.h> -#include "config.h" #include "nm-device-factory.h" #include "nm-wwan-factory.h" #include "nm-modem-manager.h" @@ -43,20 +44,12 @@ typedef struct { /************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_MODEM - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WWAN_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ static void @@ -93,9 +86,17 @@ modem_added_cb (NMModemManager *manager, g_object_unref (device); } + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_MODEM; +} + static void -nm_wwan_factory_init (NMWwanFactory *self) +start (NMDeviceFactory *factory) { + NMWwanFactory *self = NM_WWAN_FACTORY (factory); NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); priv->mm = g_object_new (NM_TYPE_MODEM_MANAGER, NULL); @@ -107,8 +108,15 @@ nm_wwan_factory_init (NMWwanFactory *self) } static void +nm_wwan_factory_init (NMWwanFactory *self) +{ +} + +static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h index b7aee01f..c6c03f1f 100644 --- a/src/devices/wwan/nm-wwan-factory.h +++ b/src/devices/wwan/nm-wwan-factory.h @@ -18,8 +18,8 @@ * Copyright (C) 2014 Red Hat, Inc. */ -#ifndef NM_WWAN_FACTORY_H -#define NM_WWAN_FACTORY_H +#ifndef __NETWORKMANAGER_WWAN_FACTORY_H__ +#define __NETWORKMANAGER_WWAN_FACTORY_H__ #include <glib-object.h> @@ -34,4 +34,4 @@ typedef struct { GObjectClass parent; } NMWwanFactoryClass; -#endif /* NM_WWAN_FACTORY_H */ +#endif /* __NETWORKMANAGER_WWAN_FACTORY_H__ */ diff --git a/src/devices/wwan/wwan-exports.ver b/src/devices/wwan/wwan-exports.ver index dc505d17..c23ab24b 100644 --- a/src/devices/wwan/wwan-exports.ver +++ b/src/devices/wwan/wwan-exports.ver @@ -6,11 +6,11 @@ global: nm_modem_complete_connection; nm_modem_deactivate; nm_modem_device_state_changed; - nm_modem_error_quark; nm_modem_get_capabilities; nm_modem_get_control_port; nm_modem_get_data_port; nm_modem_get_driver; + nm_modem_get_iid; nm_modem_get_path; nm_modem_get_secrets; nm_modem_get_state; |