diff options
Diffstat (limited to 'src/devices')
29 files changed, 390 insertions, 268 deletions
diff --git a/src/devices/adsl/Makefile.am b/src/devices/adsl/Makefile.am index 07a8f9ee..d7457c88 100644 --- a/src/devices/adsl/Makefile.am +++ b/src/devices/adsl/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ diff --git a/src/devices/adsl/Makefile.in b/src/devices/adsl/Makefile.in index 6f7fe174..b6e944f8 100644 --- a/src/devices/adsl/Makefile.in +++ b/src/devices/adsl/Makefile.in @@ -341,6 +341,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -487,6 +488,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am index 8ab561ac..e6e378f0 100644 --- a/src/devices/bluetooth/Makefile.am +++ b/src/devices/bluetooth/Makefile.am @@ -10,11 +10,13 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/devices/wwan \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -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 \ + $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in index 6233a751..bdc3b5cb 100644 --- a/src/devices/bluetooth/Makefile.in +++ b/src/devices/bluetooth/Makefile.in @@ -361,6 +361,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -504,12 +505,12 @@ with_valgrind = @with_valgrind@ 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 \ + -I${top_srcdir}/include -I$(top_builddir)/include \ + -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) \ - $(am__append_1) + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(GLIB_CFLAGS) \ + $(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 diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index d5426052..89ad8270 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -603,8 +603,10 @@ 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) + if (device && priv->bluez_version == 5) { priv->connected = TRUE; + g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_CONNECTED); + } return device; } diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 7f139424..afcba3b3 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -572,6 +572,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, { const char *iface = nm_connection_get_interface_name (connection); NMPlatformError plerr; + const NMPlatformLink *plink; g_assert (iface); @@ -584,14 +585,15 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, nm_platform_error_to_string (plerr)); return NULL; } + plink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface); 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); + 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); } NM_DEVICE_FACTORY_DEFINE_INTERNAL (BOND, Bond, bond, diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index e1cafd60..d6435530 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -498,6 +498,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, const char *mac_address_str; guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; NMPlatformError plerr; + const NMPlatformLink *plink; g_assert (iface); @@ -523,9 +524,10 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, nm_platform_error_to_string (plerr)); return NULL; } + plink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_IFACE, iface, + NM_DEVICE_PLATFORM_DEVICE, plink, NM_DEVICE_DRIVER, "bridge", NM_DEVICE_TYPE_DESC, "Bridge", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index beb86e11..8a023843 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -560,15 +560,18 @@ build_supplicant_config (NMDeviceEthernet *self) NMSupplicantConfig *config = NULL; NMSetting8021x *security; NMConnection *connection; + guint32 mtu; connection = nm_device_get_connection (NM_DEVICE (self)); g_assert (connection); con_uuid = nm_connection_get_uuid (connection); + mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, + nm_device_get_ifindex (NM_DEVICE (self))); config = nm_supplicant_config_new (); security = nm_connection_get_setting_802_1x (connection); - if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, TRUE)) { + if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, mtu, TRUE)) { _LOGW (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); g_object_unref (config); config = NULL; @@ -1195,15 +1198,22 @@ wake_on_lan_enable (NMDevice *device) value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, "ethernet.wake-on-lan", device); + if (value) { wol = _nm_utils_ascii_str_to_int64 (value, 10, NM_SETTING_WIRED_WAKE_ON_LAN_NONE, - NM_SETTING_WIRED_WAKE_ON_LAN_ALL, + G_MAXINT32, NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); + + if ( NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS) + && !nm_utils_is_power_of_two (wol)) { + nm_log_dbg (LOGD_ETHER, "invalid default value %u for wake-on-lan", (guint) wol); + wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; + } if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) goto found; } - wol = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + wol = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; found: return nmp_utils_ethtool_set_wake_on_lan (nm_device_get_iface (device), wol, password); } @@ -1474,6 +1484,7 @@ new_default_connection (NMDevice *self) NM_SETTING_CONNECTION_ID, defname, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL); diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 2d519f61..c1571fd9 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -327,6 +327,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, int p_key, parent_ifindex; const char *iface; NMPlatformError plerr; + const NMPlatformLink *plink; if (!NM_IS_DEVICE_INFINIBAND (parent)) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, @@ -352,9 +353,10 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, nm_platform_error_to_string (plerr)); return NULL; } + plink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_DEVICE_IFACE, iface, + NM_DEVICE_PLATFORM_DEVICE, plink, NM_DEVICE_DRIVER, nm_device_get_driver (parent), NM_DEVICE_TYPE_DESC, "InfiniBand", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index e523e6bb..b330397f 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -56,6 +56,7 @@ typedef struct { NMDevice *parent; guint parent_state_id; + guint parent_hwaddr_id; int vlan_id; } NMDeviceVlanPrivate; @@ -88,6 +89,36 @@ parent_state_changed (NMDevice *parent, } static void +parent_hwaddr_changed (NMDevice *parent, + GParamSpec *pspec, + gpointer user_data) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); + NMConnection *connection; + NMSettingWired *s_wired; + const char *cloned_mac = NULL; + + /* Never touch assumed devices */ + if (nm_device_uses_assumed_connection (self)) + return; + + connection = nm_device_get_connection (self); + if (!connection) + return; + + /* Update the VLAN MAC only if configuration does not specify one */ + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + + if (!cloned_mac) { + _LOGD (LOGD_VLAN, "parent hardware address changed"); + nm_device_set_hw_addr (self, nm_device_get_hw_address (parent), + "set", LOGD_VLAN); + } +} + +static void nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean construct) { NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); @@ -96,10 +127,8 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean constr if (parent == priv->parent) return; - if (priv->parent_state_id) { - g_signal_handler_disconnect (priv->parent, priv->parent_state_id); - priv->parent_state_id = 0; - } + nm_clear_g_signal_handler (priv->parent, &priv->parent_state_id); + nm_clear_g_signal_handler (priv->parent, &priv->parent_hwaddr_id); g_clear_object (&priv->parent); if (parent) { @@ -109,6 +138,9 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean constr G_CALLBACK (parent_state_changed), device); + priv->parent_hwaddr_id = g_signal_connect (priv->parent, "notify::" NM_DEVICE_HW_ADDRESS, + G_CALLBACK (parent_hwaddr_changed), device); + /* Set parent-dependent unmanaged flag */ if (construct) { nm_device_set_initial_unmanaged_flag (device, @@ -666,6 +698,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, NMSettingVlan *s_vlan; gs_free char *iface = NULL; NMPlatformError plerr; + const NMPlatformLink *plink; if (!NM_IS_DEVICE (parent)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, @@ -696,9 +729,10 @@ create_virtual_device_for_connection (NMDeviceFactory *factory, nm_platform_error_to_string (plerr)); return NULL; } + plink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface); device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_IFACE, iface, + NM_DEVICE_PLATFORM_DEVICE, plink, NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent, NM_DEVICE_DRIVER, "8021q", NM_DEVICE_TYPE_DESC, "VLAN", diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 58895821..9b69d5ab 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -95,6 +95,7 @@ enum { REMOVED, RECHECK_AUTO_ACTIVATE, RECHECK_ASSUME, + LINK_INITIALIZED, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -342,6 +343,7 @@ typedef struct { /* master interface for bridge/bond/team slave */ NMDevice * master; gboolean enslaved; + gboolean master_ready_handled; guint master_ready_id; /* slave management */ @@ -1142,8 +1144,9 @@ nm_device_finish_init (NMDevice *self) /* Do not manage externally created software devices until they are IFF_UP */ if ( NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self) - && !nm_platform_link_is_up (NM_PLATFORM_GET, priv->ifindex) - && priv->ifindex > 0) + && priv->ifindex > 0 + && ( !priv->up + || !priv->platform_link_initialized)) nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN, TRUE); if (priv->master) @@ -1158,8 +1161,8 @@ nm_device_finish_init (NMDevice *self) * Currently it can happen that NM deletes 127.0.0.1 address. */ nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_DEFAULT, TRUE); } else if (priv->platform_link_initialized || (priv->is_nm_owned && nm_device_is_software (self))) { - nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged); - nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_DEFAULT, platform_unmanaged); + if (nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged)) + nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_DEFAULT, platform_unmanaged); } else { /* Hardware and externally-created software links stay unmanaged * until they are fully initialized by the platform. NM created @@ -1322,9 +1325,7 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier) 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; + if (nm_clear_g_source (&priv->carrier_wait_id)) { nm_device_remove_pending_action (self, "carrier wait", TRUE); _carrier_wait_check_queued_act_request (self); } @@ -1373,6 +1374,8 @@ device_link_changed (NMDevice *self) NMPlatformLink info; const NMPlatformLink *pllink; int ifindex; + gboolean emit_link_initialized = FALSE; + gboolean was_up; priv->device_link_changed_id = 0; @@ -1448,8 +1451,29 @@ device_link_changed (NMDevice *self) if (ip_ifname_changed) update_dynamic_ip_setup (self); - if (priv->up != NM_FLAGS_HAS (info.flags, IFF_UP)) { - priv->up = NM_FLAGS_HAS (info.flags, IFF_UP); + if (priv->ifindex > 0 && !priv->platform_link_initialized && info.initialized) { + priv->platform_link_initialized = TRUE; + + if (nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged)) { + nm_device_set_unmanaged (self, + NM_UNMANAGED_DEFAULT, + platform_unmanaged, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + + nm_device_set_unmanaged (self, + NM_UNMANAGED_PLATFORM_INIT, + FALSE, + NM_DEVICE_STATE_REASON_NOW_MANAGED); + + emit_link_initialized = TRUE; + } + + was_up = priv->up; + priv->up = NM_FLAGS_HAS (info.flags, IFF_UP); + + if ( priv->platform_link_initialized + && (emit_link_initialized || priv->up != was_up)) { /* Manage externally-created software interfaces only when they are IFF_UP */ g_assert (priv->ifindex > 0); @@ -1491,21 +1515,8 @@ device_link_changed (NMDevice *self) } } - if (priv->ifindex > 0 && !priv->platform_link_initialized && info.initialized) { - priv->platform_link_initialized = TRUE; - - if (nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged)) { - nm_device_set_unmanaged (self, - NM_UNMANAGED_DEFAULT, - platform_unmanaged, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - } - - nm_device_set_unmanaged (self, - NM_UNMANAGED_PLATFORM_INIT, - FALSE, - NM_DEVICE_STATE_REASON_NOW_MANAGED); - } + if (emit_link_initialized) + g_signal_emit (self, signals[LINK_INITIALIZED], 0); return G_SOURCE_REMOVE; } @@ -1894,9 +1905,10 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success) if (activating) { priv->ip4_state = IP_DONE; priv->ip6_state = IP_DONE; - nm_device_queue_state (self, - success ? NM_DEVICE_STATE_SECONDARIES : NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NONE); + if (success) + nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE); + else + nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); } else nm_device_queue_recheck_assume (self); } @@ -2613,19 +2625,23 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) act_source_func = &priv->act_source_func; } - 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 - * streams of associate events before NM has had a chance to process - * the first one. - */ - if (!*act_source_id || (*act_source_func != func)) { - activation_source_clear (self, TRUE, family); - *act_source_id = g_idle_add (func, self); - *act_source_func = func; + if (*act_source_id) { + if (*act_source_func == func) { + /* Don't bother rescheduling the same function that's about to + * run anyway. Fixes issues with crappy wireless drivers sending + * streams of associate events before NM has had a chance to process + * the first one. + */ + _LOGD (LOGD_DEVICE, "activation stage already scheduled"); + return; + } else { + _LOGW (LOGD_DEVICE, "a different activation stage already scheduled"); + activation_source_clear (self, TRUE, family); + } } + + *act_source_id = g_idle_add (func, self); + *act_source_func = func; } static gboolean @@ -2655,19 +2671,22 @@ get_ip_config_may_fail (NMDevice *self, int family) } static void -master_ready_cb (NMActiveConnection *active, - GParamSpec *pspec, - NMDevice *self) +master_ready (NMDevice *self, + NMActiveConnection *active) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActiveConnection *master; - g_assert (priv->state == NM_DEVICE_STATE_PREPARE); + g_return_if_fail (priv->state == NM_DEVICE_STATE_PREPARE); + g_return_if_fail (!priv->master_ready_handled); /* Notify a master device that it has a new slave */ - g_assert (nm_active_connection_get_master_ready (active)); + g_return_if_fail (nm_active_connection_get_master_ready (active)); master = nm_active_connection_get_master (active); + priv->master_ready_handled = TRUE; + nm_clear_g_signal_handler (active, &priv->master_ready_id); + priv->master = g_object_ref (nm_active_connection_get_device (master)); nm_device_master_add_slave (priv->master, self, @@ -2676,11 +2695,14 @@ master_ready_cb (NMActiveConnection *active, _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); - priv->master_ready_id = 0; - } +} +static void +master_ready_cb (NMActiveConnection *active, + GParamSpec *pspec, + NMDevice *self) +{ + master_ready (self, active); nm_device_activate_schedule_stage2_device_config (self); } @@ -2728,23 +2750,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); } - if (nm_active_connection_get_master (active)) { - /* If the master connection is ready for slaves, attach ourselves */ - if (nm_active_connection_get_master_ready (active)) - master_ready_cb (active, NULL, self); - else { - _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); - priv->master_ready_id = g_signal_connect (active, - "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, - (GCallback) master_ready_cb, - self); - /* Postpone */ - } - } else - nm_device_activate_schedule_stage2_device_config (self); + nm_device_activate_schedule_stage2_device_config (self); out: _LOGD (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) complete."); @@ -2862,6 +2868,31 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); + if (!priv->master_ready_handled) { + NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); + + if (!nm_active_connection_get_master (active)) { + g_warn_if_fail (!priv->master_ready_id); + priv->master_ready_handled = TRUE; + } else { + /* If the master connection is ready for slaves, attach ourselves */ + if (nm_active_connection_get_master_ready (active)) + master_ready (self, active); + else { + _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); + + if (priv->master_ready_id == 0) { + priv->master_ready_id = g_signal_connect (active, + "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, + (GCallback) master_ready_cb, + self); + } + /* Postpone */ + return; + } + } + } + activation_source_schedule (self, nm_device_activate_stage2_device_config, 0); _LOGD (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) scheduled..."); @@ -3467,6 +3498,16 @@ dhcp4_fail (NMDevice *self, gboolean timeout) return; } + /* Instead of letting an assumed connection fail (which means that the + * device will transition to the ACTIVATED state without IP configuration), + * retry DHCP again. + */ + if (nm_device_uses_assumed_connection (self)) { + _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because the connection is assumed"); + priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self); + return; + } + if (timeout || (priv->ip4_state == IP_CONF)) nm_device_activate_schedule_ip4_config_timeout (self); else if (priv->ip4_state == IP_DONE) @@ -4141,6 +4182,16 @@ dhcp6_fail (NMDevice *self, gboolean timeout) return; } + /* Instead of letting an assumed connection fail (which means that the + * device will transition to the ACTIVATED state without IP configuration), + * retry DHCP again. + */ + if (nm_device_uses_assumed_connection (self)) { + _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed"); + priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self); + return; + } + if (timeout || (priv->ip6_state == IP_CONF)) nm_device_activate_schedule_ip6_config_timeout (self); else if (priv->ip6_state == IP_DONE) @@ -4513,7 +4564,12 @@ linklocal6_start (NMDevice *self) check_and_add_ipv6ll_addr (self); - priv->linklocal6_timeout_id = g_timeout_add_seconds (5, linklocal6_timeout_cb, self); + /* Depending on the network and what the 'dad_transmits' and 'retrans_time_ms' + * sysctl values are, DAD for the IPv6LL address may take quite a while. + * FIXME: use dad/retrans sysctl values if they are higher than a minimum time. + * (rh #1101809) + */ + priv->linklocal6_timeout_id = g_timeout_add_seconds (15, linklocal6_timeout_cb, self); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -5060,7 +5116,6 @@ act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *ip_iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMConnection *connection; const char *method; @@ -5071,8 +5126,6 @@ act_stage3_ip6_config_start (NMDevice *self, g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - ip_iface = nm_device_get_ip_iface (self); - connection = nm_device_get_connection (self); g_assert (connection); @@ -5347,11 +5400,13 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) } /* IPv4 */ - if (!nm_device_activate_stage3_ip4_start (self)) + if ( nm_device_activate_ip4_state_in_wait (self) + && !nm_device_activate_stage3_ip4_start (self)) goto out; /* IPv6 */ - if (!nm_device_activate_stage3_ip6_start (self)) + if ( nm_device_activate_ip6_state_in_wait (self) + && !nm_device_activate_stage3_ip6_start (self)) goto out; nm_device_check_ip_failed (self, TRUE); @@ -6003,10 +6058,8 @@ clear_act_request (NMDevice *self) nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE); - if (priv->master_ready_id) { - g_signal_handler_disconnect (priv->act_request, priv->master_ready_id); - priv->master_ready_id = 0; - } + priv->master_ready_handled = FALSE; + nm_clear_g_signal_handler (priv->act_request, &priv->master_ready_id); g_clear_object (&priv->act_request); g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION); @@ -6302,7 +6355,7 @@ _carrier_wait_check_queued_act_request (NMDevice *self) priv->queued_act_request_is_waiting_for_carrier = FALSE; if (!priv->carrier) { _LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout"); - g_clear_object (&priv->queued_act_request); + _clear_queued_act_request (priv); } else { _LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier"); queued_req = priv->queued_act_request; @@ -6326,6 +6379,8 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) return FALSE; connection = nm_act_request_get_connection (req); + if (!connection_requires_carrier (connection)) + return FALSE; if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) { /* We passed all @flags we have, and no @specific_object. @@ -6457,7 +6512,6 @@ nm_device_set_ip4_config (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv; - const char *ip_iface; NMIP4Config *old_config = NULL; gboolean has_changes = FALSE; gboolean success = TRUE; @@ -6467,7 +6521,6 @@ nm_device_set_ip4_config (NMDevice *self, g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); - ip_iface = nm_device_get_ip_iface (self); ip_ifindex = nm_device_get_ip_ifindex (self); old_config = priv->ip4_config; @@ -6592,7 +6645,6 @@ nm_device_set_ip6_config (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv; - const char *ip_iface; NMIP6Config *old_config = NULL; gboolean has_changes = FALSE; gboolean success = TRUE; @@ -6602,7 +6654,6 @@ nm_device_set_ip6_config (NMDevice *self, g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); - ip_iface = nm_device_get_ip_iface (self); ip_ifindex = nm_device_get_ip_ifindex (self); old_config = priv->ip6_config; @@ -7058,9 +7109,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) * a timeout is reached. */ if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - if (priv->carrier_wait_id) - g_source_remove (priv->carrier_wait_id); - else + if (!nm_clear_g_source (&priv->carrier_wait_id)) nm_device_add_pending_action (self, "carrier wait", TRUE); priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self); } @@ -8032,16 +8081,23 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) 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; - priv->v4_commit_first_time = TRUE; - priv->v6_commit_first_time = TRUE; + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { + priv->default_route.v4_is_assumed = FALSE; + priv->default_route.v6_is_assumed = FALSE; + 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); + } + priv->default_route.v4_is_assumed = TRUE; + 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); + priv->v4_commit_first_time = TRUE; + priv->v6_commit_first_time = TRUE; + /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ @@ -8206,15 +8262,9 @@ nm_device_spawn_iface_helper (NMDevice *self) 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) { + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { 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); @@ -8227,29 +8277,30 @@ nm_device_spawn_iface_helper (NMDevice *self) 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); - } + if (priv->dhcp4_client) { + const char *hostname; + GBytes *client_id; + + 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 (hostname) { - g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); - g_ptr_array_add (argv, g_strdup (hostname)); + hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client); + if (hostname) { + 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) { + if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { NMSettingIPConfig *s_ip6; char *hex_iid; NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; @@ -8611,6 +8662,14 @@ _set_state_full (NMDevice *self, nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL); break; case NM_DEVICE_STATE_FAILED: + /* Usually upon failure the activation chain is interrupted in + * one of the stages; but in some cases the device fails for + * external events (as a failure of master connection) while + * the activation sequence is running and so we need to ensure + * that the chain is terminated here. + */ + _cancel_activation (self); + if (nm_device_uses_assumed_connection (self)) { /* Avoid tearing down assumed connection, assume it's connected */ nm_device_queue_state (self, @@ -9195,10 +9254,7 @@ dispose (GObject *object) g_hash_table_remove_all (priv->available_connections); - if (priv->carrier_wait_id) { - g_source_remove (priv->carrier_wait_id); - priv->carrier_wait_id = 0; - } + nm_clear_g_source (&priv->carrier_wait_id); _clear_queued_act_request (priv); @@ -9822,6 +9878,13 @@ nm_device_class_init (NMDeviceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[LINK_INITIALIZED] = + g_signal_new (NM_DEVICE_LINK_INITIALIZED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_object_info); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index e9d5b948..49cef8e1 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -74,6 +74,7 @@ #define NM_DEVICE_REMOVED "removed" #define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate" #define NM_DEVICE_RECHECK_ASSUME "recheck-assume" +#define NM_DEVICE_LINK_INITIALIZED "link-initialized" G_BEGIN_DECLS diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am index 6fea9b3f..46c5fe1d 100644 --- a/src/devices/team/Makefile.am +++ b/src/devices/team/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ diff --git a/src/devices/team/Makefile.in b/src/devices/team/Makefile.in index 342c41ee..7305b05a 100644 --- a/src/devices/team/Makefile.in +++ b/src/devices/team/Makefile.in @@ -345,6 +345,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -487,8 +488,8 @@ 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 \ + -I${top_srcdir}/include -I$(top_builddir)/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) \ diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 09b2dd7d..1950fd2a 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -710,6 +710,7 @@ nm_device_team_new_for_connection (NMConnection *connection, GError **error) { const char *iface = nm_connection_get_interface_name (connection); NMPlatformError plerr; + const NMPlatformLink *plink; g_assert (iface); @@ -722,9 +723,10 @@ nm_device_team_new_for_connection (NMConnection *connection, GError **error) nm_platform_error_to_string (plerr)); return NULL; } + plink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, iface); return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, - NM_DEVICE_IFACE, iface, + NM_DEVICE_PLATFORM_DEVICE, plink, NM_DEVICE_DRIVER, "team", NM_DEVICE_TYPE_DESC, "Team", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, diff --git a/src/devices/wifi/Makefile.am b/src/devices/wifi/Makefile.am index 230c00ac..4ac59e3d 100644 --- a/src/devices/wifi/Makefile.am +++ b/src/devices/wifi/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ diff --git a/src/devices/wifi/Makefile.in b/src/devices/wifi/Makefile.in index b679bfc2..82ebad74 100644 --- a/src/devices/wifi/Makefile.in +++ b/src/devices/wifi/Makefile.in @@ -385,6 +385,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -534,6 +535,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ -I${top_srcdir}/include \ + -I$(top_builddir)/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ diff --git a/src/devices/wifi/nm-device-wifi-glue.h b/src/devices/wifi/nm-device-wifi-glue.h index 3d0f63db..8f8da2af 100644 --- a/src/devices/wifi/nm-device-wifi-glue.h +++ b/src/devices/wifi/nm-device-wifi-glue.h @@ -74,9 +74,9 @@ dbus_glib_marshal_nm_device_wifi_BOOLEAN__POINTER_POINTER (GClosure *closure gpointer arg_1, gpointer arg_2, gpointer data2); - register GMarshalFunc_BOOLEAN__POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; + GMarshalFunc_BOOLEAN__POINTER_POINTER callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); @@ -121,9 +121,9 @@ dbus_glib_marshal_nm_device_wifi_VOID__BOXED_POINTER (GClosure *closure, gpointer arg_1, gpointer arg_2, gpointer data2); - register GMarshalFunc_VOID__BOXED_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; + GMarshalFunc_VOID__BOXED_POINTER callback; + GCClosure *cc = (GCClosure*) closure; + gpointer data1, data2; g_return_if_fail (n_param_values == 3); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index dde743b1..15d41206 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -499,7 +499,7 @@ update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap) } static void -set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_available_connections, gboolean force_remove_old_ap) +set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_available_connections) { NMDeviceWifiPrivate *priv; NMAccessPoint *old_ap; @@ -530,7 +530,7 @@ set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_avai if (old_ap) { NM80211Mode mode = nm_ap_get_mode (old_ap); - if (force_remove_old_ap || mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_ap_get_fake (old_ap)) { + if (mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_ap_get_fake (old_ap)) { remove_access_point (self, old_ap); if (recheck_available_connections) nm_device_recheck_available_connections (NM_DEVICE (self)); @@ -629,7 +629,7 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) 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); + set_current_ap (self, new_ap, TRUE); } new_rate = nm_platform_wifi_get_rate (NM_PLATFORM_GET, ifindex); @@ -690,7 +690,7 @@ remove_all_aps (NMDeviceWifi *self) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); if (priv->ap_list) { - set_current_ap (self, NULL, FALSE, FALSE); + set_current_ap (self, NULL, FALSE); while (priv->ap_list) remove_access_point (self, NM_AP (priv->ap_list->data)); @@ -728,7 +728,7 @@ deactivate (NMDevice *device) * was non-broadcasting or something) get rid of it, because 'fake' * APs should only live for as long as we're connected to them. **/ - set_current_ap (self, NULL, TRUE, FALSE); + set_current_ap (self, NULL, TRUE); /* Clear any critical protocol notification in the Wi-Fi stack */ nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE); @@ -958,8 +958,6 @@ complete_connection (NMDevice *device, NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; const char *setting_mac; char *str_ssid = NULL; NMAccessPoint *ap = NULL; @@ -971,8 +969,6 @@ complete_connection (NMDevice *device, const char *perm_hw_addr; s_wifi = nm_connection_get_setting_wireless (connection); - s_wsec = nm_connection_get_setting_wireless_security (connection); - s_8021x = nm_connection_get_setting_802_1x (connection); if (!specific_object) { /* If not given a specific object, we need at minimum an SSID */ @@ -1548,6 +1544,9 @@ request_wireless_scan (NMDeviceWifi *self, GHashTable *scan_options) static gboolean request_wireless_scan_periodic (gpointer user_data) { + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (user_data); + + priv->pending_scan_id = 0; request_wireless_scan (user_data, NULL); return FALSE; } @@ -1650,7 +1649,7 @@ try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) g_return_if_fail (nm_ap_get_ssid (ap) == NULL); bssid = nm_ap_get_address (ap); - g_assert (bssid); + g_return_if_fail (bssid); /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ @@ -1692,11 +1691,9 @@ merge_scanned_ap (NMDeviceWifi *self, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMAccessPoint *found_ap = NULL; const GByteArray *ssid; - const char *bssid; gboolean strict_match = TRUE; /* Let the manager try to fill in the SSID from seen-bssids lists */ - bssid = nm_ap_get_address (merge_ap); ssid = nm_ap_get_ssid (merge_ap); if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { /* Try to fill the SSID from the AP database */ @@ -1706,12 +1703,12 @@ merge_scanned_ap (NMDeviceWifi *self, if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { /* Yay, matched it, no longer treat as hidden */ _LOGD (LOGD_WIFI_SCAN, "matched hidden AP %s => '%s'", - str_if_set (bssid, "(none)"), nm_utils_escape_ssid (ssid->data, ssid->len)); + nm_ap_get_address (merge_ap), 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 */ _LOGD (LOGD_WIFI_SCAN, "failed to match hidden AP %s", - str_if_set (bssid, "(none)")); + nm_ap_get_address (merge_ap)); } } @@ -1730,7 +1727,7 @@ merge_scanned_ap (NMDeviceWifi *self, if (found_ap) { _LOGD (LOGD_WIFI_SCAN, "merging AP '%s' %s (%p) with existing (%p)", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - str_if_set (bssid, "(none)"), + nm_ap_get_address (merge_ap), merge_ap, found_ap); @@ -1753,7 +1750,7 @@ merge_scanned_ap (NMDeviceWifi *self, /* New entry in the list */ _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); + nm_ap_get_address (merge_ap), merge_ap); g_object_ref (merge_ap); priv->ap_list = g_slist_prepend (priv->ap_list, merge_ap); @@ -1872,7 +1869,7 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, merge_scanned_ap (self, ap); g_object_unref (ap); } else - _LOGW (LOGD_WIFI_SCAN, "invalid AP properties received"); + _LOGD (LOGD_WIFI_SCAN, "invalid AP properties received for %s", object_path); /* Remove outdated access points */ schedule_scanlist_cull (self); @@ -2010,11 +2007,21 @@ link_timeout_cb (gpointer user_data) /* If the access point failed, and wasn't found by the supplicant when it * attempted to reconnect, then it's probably out of range or turned off. - * Remove it from the list and if it's actually still present, it'll be - * found in the next scan. */ - if (priv->ssid_found == FALSE && priv->current_ap) - set_current_ap (self, NULL, TRUE, TRUE); + if (priv->ssid_found == FALSE && priv->current_ap) { + NMAccessPoint *old_ap = g_object_ref (priv->current_ap); + + set_current_ap (self, NULL, TRUE); + + /* If it was an external entity and the supplicant doesn't know about + * it, remove it from the scan list. If it's still around, it'll get + * found in the next scan. + */ + if ( nm_ap_get_mode (old_ap) == NM_802_11_MODE_INFRA + && g_object_get_data (G_OBJECT (old_ap), WPAS_REMOVED_TAG)) + remove_access_point (self, old_ap); + g_object_unref (old_ap); + } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, @@ -2486,13 +2493,16 @@ build_supplicant_config (NMDeviceWifi *self, if (s_wireless_sec) { NMSetting8021x *s_8021x; const char *con_uuid = nm_connection_get_uuid (connection); + guint32 mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, + nm_device_get_ifindex (NM_DEVICE (self))); g_assert (con_uuid); s_8021x = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_wireless_security (config, s_wireless_sec, s_8021x, - con_uuid)) { + con_uuid, + mtu)) { _LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to supplicant config."); goto error; } @@ -2609,14 +2619,14 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) priv->ap_list = g_slist_prepend (priv->ap_list, ap); nm_ap_export_to_dbus (ap); g_object_freeze_notify (G_OBJECT (self)); - set_current_ap (self, ap, FALSE, FALSE); + set_current_ap (self, ap, FALSE); emit_ap_added_removed (self, ACCESS_POINT_ADDED, ap, TRUE); g_object_thaw_notify (G_OBJECT (self)); nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap)); return NM_ACT_STAGE_RETURN_SUCCESS; done: - set_current_ap (self, ap, TRUE, FALSE); + set_current_ap (self, ap, TRUE); return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -3004,10 +3014,10 @@ done: * then the fake one and reset it. Reset the fake current_ap to NULL * now, which will remove the fake ap. **/ - set_current_ap (self, NULL, TRUE, FALSE); + set_current_ap (self, NULL, TRUE); } - /* No need to update seen BSSIDs cache, that is done by set_current_ap() already */ + update_seen_bssids_cache (self, priv->current_ap); /* Reset scan interval to something reasonable */ priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2); diff --git a/src/devices/wifi/nm-wifi-ap-utils.c b/src/devices/wifi/nm-wifi-ap-utils.c index 9ac7052e..1a772fb7 100644 --- a/src/devices/wifi/nm-wifi-ap-utils.c +++ b/src/devices/wifi/nm-wifi-ap-utils.c @@ -549,11 +549,11 @@ 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); + ap_ssid_bytes = ap_ssid ? g_bytes_new (ap_ssid->data, ap_ssid->len) : NULL; ssid = nm_setting_wireless_get_ssid (s_wifi); if (!ssid) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid_bytes, NULL); - else if (!g_bytes_equal (ssid, ap_ssid_bytes)) { + else if (!ap_ssid_bytes || !g_bytes_equal (ssid, ap_ssid_bytes)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 1485f4c1..72430021 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -476,9 +476,10 @@ nm_ap_new_from_properties (const char *supplicant_path, GVariant *properties) nm_ap_set_supplicant_path (ap, supplicant_path); - /* ignore APs with invalid BSSIDs */ + /* ignore APs with invalid or missing BSSIDs */ addr = nm_ap_get_address (ap); - if ( nm_utils_hwaddr_matches (addr, -1, bad_bssid1, ETH_ALEN) + if ( !addr + || 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; diff --git a/src/devices/wifi/tests/Makefile.am b/src/devices/wifi/tests/Makefile.am index 2a7d7849..f76bdbf5 100644 --- a/src/devices/wifi/tests/Makefile.am +++ b/src/devices/wifi/tests/Makefile.am @@ -1,5 +1,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -I${top_srcdir}/src/platform \ diff --git a/src/devices/wifi/tests/Makefile.in b/src/devices/wifi/tests/Makefile.in index f807ee77..f2488c7d 100644 --- a/src/devices/wifi/tests/Makefile.in +++ b/src/devices/wifi/tests/Makefile.in @@ -511,6 +511,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -653,6 +654,7 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -I${top_srcdir}/src/platform \ diff --git a/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c index 3c405e26..26e130c4 100644 --- a/src/devices/wifi/tests/test-wifi-ap-utils.c +++ b/src/devices/wifi/tests/test-wifi-ap-utils.c @@ -1364,10 +1364,10 @@ main (int argc, char **argv) test_open_ap_leap_connection_1); g_test_add_func ("/wifi/open_ap/leap_connection/2", test_open_ap_leap_connection_2); - g_test_add_data_func ("/wifi/open_ap/wep_connection", + g_test_add_data_func ("/wifi/open_ap/wep_connection_true", (gconstpointer) TRUE, test_open_ap_wep_connection); - g_test_add_data_func ("/wifi/open_ap/wep_connection", + g_test_add_data_func ("/wifi/open_ap/wep_connection_false", (gconstpointer) FALSE, test_open_ap_wep_connection); @@ -1441,104 +1441,57 @@ main (int argc, char **argv) (gconstpointer) IDX_PRIV, test_ap_wpa_eap_connection_5); +#define ADD_FUNC(func) do { \ + gchar *name_idx = g_strdup_printf ("/wifi/wpa_psk/" G_STRINGIFY (func) "/%zd", i); \ + g_test_add_data_func (name_idx, (gconstpointer) i, func); \ + g_free (name_idx); \ + } while (0) + /* WPA-PSK tests */ for (i = IDX_WPA_PSK_PTKIP_GTKIP; i <= IDX_WPA_RSN_PSK_PCCMP_GCCMP; i++) { - g_test_add_data_func ("/wifi/wpa_psk/empty_connection", - (gconstpointer) i, - test_wpa_ap_empty_connection); - g_test_add_data_func ("/wifi/wpa_psk/leap_connection/1", - (gconstpointer) i, - test_wpa_ap_leap_connection_1); - g_test_add_data_func ("/wifi/wpa_psk/leap_connection/2", - (gconstpointer) i, - test_wpa_ap_leap_connection_2); - - g_test_add_data_func ("/wifi/wpa_psk/dynamic_wep_connection", - (gconstpointer) i, - test_wpa_ap_dynamic_wep_connection); - - g_test_add_data_func ("/wifi/wpa_psk/wpa_psk_connection/1", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_1); - g_test_add_data_func ("/wifi/wpa_psk/wpa_psk_connection/2", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_2); - g_test_add_data_func ("/wifi/wpa_psk/wpa_psk_connection/3", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_3); - g_test_add_data_func ("/wifi/wpa_psk/wpa_psk_connection/4", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_4); - g_test_add_data_func ("/wifi/wpa_psk/wpa_psk_connection/5", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_5); - - g_test_add_data_func ("/wifi/wpa_psk/wpa_eap_connection/1", - (gconstpointer) i, - test_ap_wpa_eap_connection_1); - g_test_add_data_func ("/wifi/wpa_psk/wpa_eap_connection/2", - (gconstpointer) i, - test_ap_wpa_eap_connection_2); - g_test_add_data_func ("/wifi/wpa_psk/wpa_eap_connection/3", - (gconstpointer) i, - test_ap_wpa_eap_connection_3); - g_test_add_data_func ("/wifi/wpa_psk/wpa_eap_connection/4", - (gconstpointer) i, - test_ap_wpa_eap_connection_4); - g_test_add_data_func ("/wifi/wpa_psk/wpa_eap_connection/5", - (gconstpointer) i, - test_ap_wpa_eap_connection_5); + ADD_FUNC(test_wpa_ap_empty_connection); + ADD_FUNC(test_wpa_ap_leap_connection_1); + ADD_FUNC(test_wpa_ap_leap_connection_2); + ADD_FUNC(test_wpa_ap_dynamic_wep_connection); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); + ADD_FUNC(test_ap_wpa_eap_connection_1); + ADD_FUNC(test_ap_wpa_eap_connection_2); + ADD_FUNC(test_ap_wpa_eap_connection_3); + ADD_FUNC(test_ap_wpa_eap_connection_4); + ADD_FUNC(test_ap_wpa_eap_connection_5); } +#undef ADD_FUNC +#define ADD_FUNC(func) do { \ + gchar *name_idx = g_strdup_printf ("/wifi/rsn_psk/" G_STRINGIFY (func) "/%zd", i); \ + g_test_add_data_func (name_idx, (gconstpointer) i, func); \ + g_free (name_idx); \ + } while (0) + /* RSN-PSK tests */ for (i = IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP; i <= IDX_RSN_PSK_PTKIP_PCCMP_GTKIP; i++) { - g_test_add_data_func ("/wifi/rsn_psk/empty_connection", - (gconstpointer) i, - test_wpa_ap_empty_connection); - g_test_add_data_func ("/wifi/rsn_psk/leap_connection/1", - (gconstpointer) i, - test_wpa_ap_leap_connection_1); - g_test_add_data_func ("/wifi/rsn_psk/leap_connection/2", - (gconstpointer) i, - test_wpa_ap_leap_connection_2); - - g_test_add_data_func ("/wifi/rsn_psk/dynamic_wep_connection", - (gconstpointer) i, - test_wpa_ap_dynamic_wep_connection); - - g_test_add_data_func ("/wifi/rsn_psk/wpa_psk_connection/1", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_1); - g_test_add_data_func ("/wifi/rsn_psk/wpa_psk_connection/2", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_2); - g_test_add_data_func ("/wifi/rsn_psk/wpa_psk_connection/3", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_3); - g_test_add_data_func ("/wifi/rsn_psk/wpa_psk_connection/4", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_4); - g_test_add_data_func ("/wifi/rsn_psk/wpa_psk_connection/5", - (gconstpointer) i, - test_wpa_ap_wpa_psk_connection_5); - - g_test_add_data_func ("/wifi/rsn_psk/wpa_eap_connection/1", - (gconstpointer) i, - test_ap_wpa_eap_connection_1); - g_test_add_data_func ("/wifi/rsn_psk/wpa_eap_connection/2", - (gconstpointer) i, - test_ap_wpa_eap_connection_2); - g_test_add_data_func ("/wifi/rsn_psk/wpa_eap_connection/3", - (gconstpointer) i, - test_ap_wpa_eap_connection_3); - g_test_add_data_func ("/wifi/rsn_psk/wpa_eap_connection/4", - (gconstpointer) i, - test_ap_wpa_eap_connection_4); - g_test_add_data_func ("/wifi/rsn_psk/wpa_eap_connection/5", - (gconstpointer) i, - test_ap_wpa_eap_connection_5); + ADD_FUNC(test_wpa_ap_empty_connection); + ADD_FUNC(test_wpa_ap_leap_connection_1); + ADD_FUNC(test_wpa_ap_leap_connection_2); + ADD_FUNC(test_wpa_ap_dynamic_wep_connection); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); + ADD_FUNC(test_ap_wpa_eap_connection_1); + ADD_FUNC(test_ap_wpa_eap_connection_2); + ADD_FUNC(test_ap_wpa_eap_connection_3); + ADD_FUNC(test_ap_wpa_eap_connection_4); + ADD_FUNC(test_ap_wpa_eap_connection_5); } +#undef ADD_FUNC + /* Scanned signal strength conversion tests */ g_test_add_func ("/wifi/strength/dbm", test_strength_dbm); diff --git a/src/devices/wimax/Makefile.am b/src/devices/wimax/Makefile.am index 555b5ff2..0ecd1158 100644 --- a/src/devices/wimax/Makefile.am +++ b/src/devices/wimax/Makefile.am @@ -4,6 +4,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ diff --git a/src/devices/wimax/Makefile.in b/src/devices/wimax/Makefile.in index 8ad4b4e2..b1b57a79 100644 --- a/src/devices/wimax/Makefile.in +++ b/src/devices/wimax/Makefile.in @@ -339,6 +339,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -485,6 +486,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ + -I${top_builddir}/include \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 7e5b190b..055b07b9 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -9,12 +9,14 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-core \ + -I$(top_builddir)/include \ -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index 227c622f..571b1b7d 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -350,6 +350,7 @@ LOG_DRIVER = @LOG_DRIVER@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -497,12 +498,14 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-core \ + -I$(top_builddir)/include \ -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) nm-device-modem-glue.h diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 4bb72fd1..ec4f4a2f 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -1146,6 +1146,19 @@ sim_changed (MMModem *modem, GParamSpec *pspec, gpointer user_data) } static void +supported_ip_families_changed (MMModem *modem, GParamSpec *pspec, gpointer user_data) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (user_data); + + g_return_if_fail (modem == self->priv->modem_iface); + + g_object_set (G_OBJECT (self), + NM_MODEM_IP_TYPES, + mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem)), + NULL); +} + +static void nm_modem_broadband_init (NMModemBroadband *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, @@ -1176,6 +1189,10 @@ set_property (GObject *object, G_CALLBACK (sim_changed), self); sim_changed (self->priv->modem_iface, NULL, self); + g_signal_connect (self->priv->modem_iface, + "notify::supported-ip-families", + G_CALLBACK (supported_ip_families_changed), + self); /* Note: don't grab the Simple iface here; the Modem interface is the * only one assumed to be always valid and available */ |