fix crash on device deactivate (rh 1253949)

Also:
  - backport new wifi scan options from nm-1-0 upstream branch.
  - update the URI for connectivty checking
This commit is contained in:
Thomas Haller 2015-08-18 10:56:07 +02:00
parent 82c263b833
commit 5af6ac65a3
4 changed files with 945 additions and 2 deletions

View File

@ -0,0 +1,54 @@
From a2acfba3a88b5673f55400aee061861291ccc2d4 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Wed, 12 Aug 2015 16:03:12 +0200
Subject: [PATCH 1/1] device: avoid a crash during destruction
The ipv4_config might be gone already, _cleanup_generic_post() sets it to NULL.
NetworkManager[30564]: <info> caught SIGINT, shutting down normally.
(NetworkManager:30564): GLib-GObject-CRITICAL **: g_type_instance_get_private: assertion 'instance != NULL && instance->g_class != NULL' failed
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x7ffff4d92f64 "GLib-GObject", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd5e0) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4a738c3 in g_logv (log_domain=0x7ffff4d92f64 "GLib-GObject", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd5e0) at gmessages.c:1046
#1 0x00007ffff4a73a3f in g_log (log_domain=log_domain@entry=0x7ffff4d92f64 "GLib-GObject", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff4ae173d "%s: assertion '%s' failed")
at gmessages.c:1079
#2 0x00007ffff4a73a79 in g_return_if_fail_warning (log_domain=log_domain@entry=0x7ffff4d92f64 "GLib-GObject", pretty_function=pretty_function@entry=0x7ffff4d9aad0 <__FUNCTION__.13620> "g_type_instance_get_private", expression=expression@entry=0x7ffff4d99db8 "instance != NULL && instance->g_class != NULL") at gmessages.c:1088
#3 0x00007ffff4d8d2ba in g_type_instance_get_private (instance=instance@entry=0x0, private_type=<optimized out>) at gtype.c:4632
#4 0x00000000004bf774 in nm_ip4_config_get_num_addresses (config=0x0) at nm-ip4-config.c:1418
#5 0x0000000000458834 in _update_ip4_address (self=self@entry=0xa8a490 [NMDeviceBridge]) at devices/nm-device.c:6069
#6 0x000000000045e740 in nm_device_set_ip4_config (self=self@entry=0xa8a490 [NMDeviceBridge], new_config=new_config@entry=0x0, default_route_metric=default_route_metric@entry=0, commit=commit@entry=1, routes_full_sync=routes_full_sync@entry=1, reason=reason@entry=0x7fffffffd7cc) at devices/nm-device.c:6558
#7 0x0000000000466c56 in _cleanup_generic_post (self=self@entry=0xa8a490 [NMDeviceBridge], cleanup_type=cleanup_type@entry=CLEANUP_TYPE_KEEP) at devices/nm-device.c:8108
#8 0x00000000004671af in dispose (object=0xa8a490 [NMDeviceBridge]) at devices/nm-device.c:9128
#9 0x00007ffff4d6ea82 in g_object_unref (_object=0xa8a490) at gobject.c:3133
#10 0x00000000004d1a53 in remove_device (manager=manager@entry=0x8822b0 [NMManager], device=0xa8a490 [NMDeviceBridge], quitting=quitting@entry=1, allow_unmanage=allow_unmanage@entry=1) at nm-manager.c:780
#11 0x00000000004d7db1 in nm_manager_stop (self=self@entry=0x8822b0 [NMManager]) at nm-manager.c:4199
#12 0x0000000000445aa9 in main (argc=1, argv=0x7fffffffda88) at main.c:465
(gdb)
(cherry picked from commit 688e93fb2a3b93f422be69f3dda2f9e4148d4690)
(cherry picked from commit 4956ac647519c86a94595a834356aad2dba5c6e3)
---
src/devices/nm-device.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 294456d..7fab927 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -5945,7 +5945,8 @@ _update_ip4_address (NMDevice *self)
g_return_if_fail (NM_IS_DEVICE (self));
- if ( ip_config_valid (priv->state)
+ if ( priv->ip4_config
+ && ip_config_valid (priv->state)
&& nm_ip4_config_get_num_addresses (priv->ip4_config)) {
addr = nm_ip4_config_get_address (priv->ip4_config, 0)->address;
if (addr != priv->ip4_address) {
--
2.4.3

View File

@ -0,0 +1,880 @@
From 3ddaaa05b1aa22df2b23cf9b0593057a46716e6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Tue, 14 Jul 2015 09:16:35 +0200
Subject: [PATCH 1/5] core: accept 'ssids':aay option in RequestScan()
dictionary parameter
It allows specifying SSIDs that should be probe-scanned, which is useful
for APs with hidden SSID, for example.
(cherry picked from commit 87b2d783b6c732ab9cf3ad8ef0cdaec8d971c74a)
(cherry picked from commit 7706b99250efecdd1fb6f519034ef48407713005)
---
introspection/nm-device-wifi.xml | 3 ++-
src/devices/wifi/nm-device-wifi.c | 39 +++++++++++++++++++++++++++------------
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/introspection/nm-device-wifi.xml b/introspection/nm-device-wifi.xml
index d1c5313..b94aae8 100644
--- a/introspection/nm-device-wifi.xml
+++ b/introspection/nm-device-wifi.xml
@@ -37,7 +37,8 @@
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="options" type="a{sv}" direction="in">
<tp:docstring>
- Options of scan (currently unused argument).
+ Options of scan.
+ Currently 'ssids' option with value of "aay" type is supported.
</tp:docstring>
</arg>
<tp:docstring>
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 2e116f8..dde743b 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -55,6 +55,7 @@
#include "nm-dbus-glib-types.h"
#include "nm-wifi-enum-types.h"
#include "nm-connection-provider.h"
+#include "gsystem-local-alloc.h"
static gboolean impl_device_get_access_points (NMDeviceWifi *device,
@@ -178,7 +179,7 @@ static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
static void schedule_scanlist_cull (NMDeviceWifi *self);
-static gboolean request_wireless_scan (gpointer user_data);
+static void request_wireless_scan (NMDeviceWifi *self, GHashTable *scan_options);
static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap);
@@ -753,7 +754,7 @@ deactivate (NMDevice *device)
/* Ensure we trigger a scan after deactivating a Hotspot */
if (old_mode == NM_802_11_MODE_AP) {
cancel_pending_scan (self);
- request_wireless_scan (self);
+ request_wireless_scan (self, NULL);
}
}
@@ -1253,6 +1254,7 @@ request_scan_cb (NMDevice *device,
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
GError *local = NULL;
+ gs_unref_hashtable GHashTable *new_scan_options = user_data;
if (error) {
dbus_g_method_return_error (context, error);
@@ -1269,7 +1271,7 @@ request_scan_cb (NMDevice *device,
}
cancel_pending_scan (self);
- request_wireless_scan (self);
+ request_wireless_scan (self, new_scan_options);
dbus_g_method_return (context);
}
@@ -1316,7 +1318,7 @@ impl_device_request_scan (NMDeviceWifi *self,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
request_scan_cb,
- NULL);
+ options ? g_hash_table_ref (options) : NULL);
return;
error:
@@ -1482,23 +1484,31 @@ build_hidden_probe_list (NMDeviceWifi *self)
return ssids;
}
-static gboolean
-request_wireless_scan (gpointer user_data)
+static void
+request_wireless_scan (NMDeviceWifi *self, GHashTable *scan_options)
{
- NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
gboolean backoff = FALSE;
GPtrArray *ssids = NULL;
if (priv->requested_scan) {
/* There's already a scan in progress */
- return FALSE;
+ return;
}
if (check_scanning_allowed (self)) {
_LOGD (LOGD_WIFI_SCAN, "scanning requested");
- ssids = build_hidden_probe_list (self);
+ if (scan_options && g_hash_table_size (scan_options)) {
+ GValue *val = g_hash_table_lookup (scan_options, "ssids");
+
+ if (val && G_VALUE_HOLDS (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR))
+ ssids = g_ptr_array_ref (g_value_get_boxed (val));
+ else
+ _LOGD (LOGD_WIFI_SCAN, "ignoring invalid scan options");
+ }
+ if (!ssids)
+ ssids = build_hidden_probe_list (self);
if (nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN)) {
if (ssids) {
@@ -1533,9 +1543,14 @@ request_wireless_scan (gpointer user_data)
priv->pending_scan_id = 0;
schedule_scan (self, backoff);
- return FALSE;
}
+static gboolean
+request_wireless_scan_periodic (gpointer user_data)
+{
+ request_wireless_scan (user_data, NULL);
+ return FALSE;
+}
/*
* schedule_scan
@@ -1563,7 +1578,7 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
factor = 1;
priv->pending_scan_id = g_timeout_add_seconds (next_scan,
- request_wireless_scan,
+ request_wireless_scan_periodic,
self);
priv->scheduled_scan_time = now + priv->scan_interval;
@@ -3072,7 +3087,7 @@ device_state_changed (NMDevice *device,
/* Kick off a scan to get latest results */
priv->scan_interval = SCAN_INTERVAL_MIN;
cancel_pending_scan (self);
- request_wireless_scan (self);
+ request_wireless_scan (self, NULL);
break;
default:
break;
--
2.4.3
From 24da200883fdf8569231ac5d7e2cc2571d84a733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Tue, 14 Jul 2015 09:46:55 +0200
Subject: [PATCH 2/5] libnm: add new functions allowing passing options to
RequestScan() D-Bus call
nm_device_wifi_request_scan_options()
nm_device_wifi_request_scan_options_async()
(cherry picked from commit 7691fe575377b5383d4cd6dd62e01ed4f6cafa93)
(cherry picked from commit 91c0555afaac57234744f42024d95bde46ba170e)
---
libnm/libnm.ver | 2 +
libnm/nm-device-wifi.c | 154 +++++++++++++++++++++++++++++++++++++++++--------
libnm/nm-device-wifi.h | 12 +++-
3 files changed, 143 insertions(+), 25 deletions(-)
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 63289a0..9d20ebb 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -855,6 +855,8 @@ libnm_1_0_6 {
global:
nm_access_point_get_last_seen;
nm_device_get_metered;
+ nm_device_wifi_request_scan_options;
+ nm_device_wifi_request_scan_options_async;
nm_metered_get_type;
nm_setting_connection_get_metered;
} libnm_1_0_4;
diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c
index 4a19f2e..536f308 100644
--- a/libnm/nm-device-wifi.c
+++ b/libnm/nm-device-wifi.c
@@ -271,6 +271,52 @@ nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device,
return ap;
}
+static GVariant *
+prepare_scan_options (GVariant *options)
+{
+
+ GVariant *variant;
+ GVariantIter iter;
+ GVariantBuilder builder;
+ char *key;
+ GVariant *value;
+
+ if (!options)
+ variant = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+ else {
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_iter_init (&iter, options);
+ while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
+ {
+ // FIXME: verify options here?
+ g_variant_builder_add (&builder, "{sv}", key, value);
+ }
+ variant = g_variant_builder_end (&builder);
+ }
+ return variant;
+}
+
+static gboolean
+_device_wifi_request_scan (NMDeviceWifi *device,
+ GVariant *options,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret;
+ GVariant *variant;
+
+ g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), FALSE);
+
+ variant = prepare_scan_options (options);
+
+ ret = nmdbus_device_wifi_call_request_scan_sync (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy,
+ variant,
+ cancellable, error);
+ if (error && *error)
+ g_dbus_error_strip_remote_error (*error);
+ return ret;
+}
+
/**
* nm_device_wifi_request_scan:
* @device: a #NMDeviceWifi
@@ -289,17 +335,36 @@ nm_device_wifi_request_scan (NMDeviceWifi *device,
GCancellable *cancellable,
GError **error)
{
- gboolean ret;
-
- g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), FALSE);
+ return _device_wifi_request_scan (device, NULL, cancellable, error);
+}
- ret = nmdbus_device_wifi_call_request_scan_sync (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy,
- g_variant_new_array (G_VARIANT_TYPE ("{sv}"),
- NULL, 0),
- cancellable, error);
- if (error && *error)
- g_dbus_error_strip_remote_error (*error);
- return ret;
+/**
+ * nm_device_wifi_request_scan_options:
+ * @device: a #NMDeviceWifi
+ * @options: dictionary with options for RequestScan(), or %NULL
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: location for a #GError, or %NULL
+ *
+ * Request NM to scan for access points on @device. Note that the function
+ * returns immediately after requesting the scan, and it may take some time
+ * after that for the scan to complete.
+ * This is the same as @nm_device_wifi_request_scan except it accepts @options
+ * for the scanning. The argument is the dictionary passed to RequestScan()
+ * D-Bus call. Valid otions inside the dictionary are:
+ * 'ssids' => array of SSIDs (saay)
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be
+ * set.
+ *
+ * Since: 1.0.6
+ **/
+gboolean
+nm_device_wifi_request_scan_options (NMDeviceWifi *device,
+ GVariant *options,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return _device_wifi_request_scan (device, options, cancellable, error);
}
static void
@@ -326,19 +391,9 @@ request_scan_cb (GObject *source,
g_slice_free (RequestScanInfo, info);
}
-/**
- * nm_device_wifi_request_scan_async:
- * @device: a #NMDeviceWifi
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to be called when the scan has been requested
- * @user_data: caller-specific data passed to @callback
- *
- * Request NM to scan for access points on @device. Note that @callback will be
- * called immediately after requesting the scan, and it may take some time after
- * that for the scan to complete.
- **/
-void
-nm_device_wifi_request_scan_async (NMDeviceWifi *device,
+static void
+_device_wifi_request_scan_async (NMDeviceWifi *device,
+ GVariant *options,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -346,6 +401,7 @@ nm_device_wifi_request_scan_async (NMDeviceWifi *device,
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
RequestScanInfo *info;
GSimpleAsyncResult *simple;
+ GVariant *variant;
g_return_if_fail (NM_IS_DEVICE_WIFI (device));
@@ -364,13 +420,63 @@ nm_device_wifi_request_scan_async (NMDeviceWifi *device,
info->device = device;
info->simple = simple;
+ variant = prepare_scan_options (options);
+
priv->scan_info = info;
nmdbus_device_wifi_call_request_scan (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy,
- g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
+ variant,
cancellable, request_scan_cb, info);
}
/**
+ * nm_device_wifi_request_scan_async:
+ * @device: a #NMDeviceWifi
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the scan has been requested
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Request NM to scan for access points on @device. Note that @callback will be
+ * called immediately after requesting the scan, and it may take some time after
+ * that for the scan to complete.
+ **/
+void
+nm_device_wifi_request_scan_async (NMDeviceWifi *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ _device_wifi_request_scan_async (device, NULL, cancellable, callback, user_data);
+}
+
+/**
+ * nm_device_wifi_request_scan_options_async:
+ * @device: a #NMDeviceWifi
+ * @options: dictionary with options for RequestScan(), or %NULL
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the scan has been requested
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Request NM to scan for access points on @device. Note that @callback will be
+ * called immediately after requesting the scan, and it may take some time after
+ * that for the scan to complete.
+ * This is the same as @nm_device_wifi_request_scan_async except it accepts @options
+ * for the scanning. The argument is the dictionary passed to RequestScan()
+ * D-Bus call. Valid otions inside the dictionary are:
+ * 'ssids' => array of SSIDs (saay)
+ *
+ * Since: 1.0.6
+ **/
+void
+nm_device_wifi_request_scan_options_async (NMDeviceWifi *device,
+ GVariant *options,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ _device_wifi_request_scan_async (device, options, cancellable, callback, user_data);
+}
+
+/**
* nm_device_wifi_request_scan_finish:
* @device: a #NMDeviceWifi
* @result: the result passed to the #GAsyncReadyCallback
diff --git a/libnm/nm-device-wifi.h b/libnm/nm-device-wifi.h
index 24339fd..b5a5698 100644
--- a/libnm/nm-device-wifi.h
+++ b/libnm/nm-device-wifi.h
@@ -77,11 +77,21 @@ const GPtrArray * nm_device_wifi_get_access_points (NMDeviceWifi *
gboolean nm_device_wifi_request_scan (NMDeviceWifi *device,
GCancellable *cancellable,
GError **error);
-
+NM_AVAILABLE_IN_1_0_6
+gboolean nm_device_wifi_request_scan_options (NMDeviceWifi *device,
+ GVariant *options,
+ GCancellable *cancellable,
+ GError **error);
void nm_device_wifi_request_scan_async (NMDeviceWifi *device,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
+NM_AVAILABLE_IN_1_0_6
+void nm_device_wifi_request_scan_options_async (NMDeviceWifi *device,
+ GVariant *options,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
gboolean nm_device_wifi_request_scan_finish (NMDeviceWifi *device,
GAsyncResult *result,
GError **error);
--
2.4.3
From 952647582265333a8b8bfc37f3936ff76a2da92e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Tue, 14 Jul 2015 09:50:56 +0200
Subject: [PATCH 3/5] cli: add 'ssid' parameter for 'nmcli device wifi rescan'
'ssid' can repeat when more SSIDs should be scanned, e.g.
$ nmcli dev wifi rescan ssid "hidden cafe" ssid AP12 ssid "my home Wi-Fi"
Bash completion fixed by thaller@redhat.com
(cherry picked from commit e247567d879b314598efc2fe46f2bc8cd309250d)
(cherry picked from commit b1f62ce2cd2689da4a9ced04f555779c321eb191)
---
clients/cli/devices.c | 62 +++++++++++++++++++++++++++++++++++++-------
clients/cli/nmcli-completion | 9 ++++---
man/nmcli.1.in | 10 ++++---
3 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index cac615c..88a7336 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -277,7 +277,7 @@ usage (void)
" wifi [list [ifname <ifname>] [bssid <BSSID>]]\n\n"
" wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [ifname <ifname>]\n"
" [bssid <BSSID>] [name <name>] [private yes|no]\n\n"
- " wifi rescan [[ifname] <ifname>]\n\n"
+ " wifi rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n\n"
#if WITH_WIMAX
" wimax [list [ifname <ifname>] [nsp <name>]]\n\n"
#endif
@@ -371,12 +371,14 @@ usage_device_wifi (void)
"only open, WEP and WPA-PSK networks are supported at the moment. It is also\n"
"assumed that IP configuration is obtained via DHCP.\n"
"\n"
- "ARGUMENTS := rescan [[ifname] <ifname>]\n"
+ "ARGUMENTS := rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n"
"\n"
"Request that NetworkManager immediately re-scan for available access points.\n"
"NetworkManager scans Wi-Fi networks periodically, but in some cases it might\n"
- "be useful to start scanning manually. Note that this command does not show\n"
- "the APs, use 'nmcli device wifi list' for that.\n\n"));
+ "be useful to start scanning manually. 'ssid' allows scanning for a specific\n"
+ "SSID, which is useful for APs with hidden SSIDs. More 'ssid' parameters can be\n"
+ "given. Note that this command does not show the APs,\n"
+ "use 'nmcli device wifi list' for that.\n\n"));
}
#if WITH_WIMAX
@@ -2585,21 +2587,44 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv)
{
NMDevice *device;
const char *ifname = NULL;
+ GPtrArray *ssids;
const GPtrArray *devices;
int devices_idx;
+ GVariantBuilder builder, array_builder;
+ GVariant *options;
+ const char *ssid;
+ int i;
nmc->should_wait = TRUE;
+ ssids = g_ptr_array_new ();
+
/* Get the parameters */
- if (argc > 0) {
+ while (argc > 0) {
if (strcmp (*argv, "ifname") == 0) {
+ if (ifname) {
+ g_string_printf (nmc->return_text, _("Error: '%s' cannot repeat."), *(argv-1));
+ nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+ goto error;
+ }
if (next_arg (&argc, &argv) != 0) {
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1));
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
goto error;
}
- }
- ifname = *argv;
+ ifname = *argv;
+ } else if (strcmp (*argv, "ssid") == 0) {
+ if (next_arg (&argc, &argv) != 0) {
+ g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1));
+ nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+ goto error;
+ }
+ g_ptr_array_add (ssids, *argv);
+ } else
+ g_printerr (_("Unknown parameter: %s\n"), *argv);
+
+ argc--;
+ argv++;
}
/* Find Wi-Fi device to scan on. When no ifname is provided, the first Wi-Fi is used. */
@@ -2616,12 +2641,31 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv)
goto error;
}
- nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (device), NULL,
- request_rescan_cb, nmc);
+ if (ssids->len) {
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aay"));
+
+ for (i = 0; i < ssids->len; i++) {
+ ssid = g_ptr_array_index (ssids, i);
+ g_variant_builder_add (&array_builder, "@ay",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ssid, strlen (ssid), 1));
+ }
+
+ g_variant_builder_add (&builder, "{sv}", "ssids", g_variant_builder_end (&array_builder));
+ options = g_variant_builder_end (&builder);
+
+ nm_device_wifi_request_scan_options_async (NM_DEVICE_WIFI (device), options,
+ NULL, request_rescan_cb, nmc);
+ } else
+ nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (device),
+ NULL, request_rescan_cb, nmc);
+
+ g_ptr_array_free (ssids, FALSE);
return nmc->return_value;
error:
nmc->should_wait = FALSE;
+ g_ptr_array_free (ssids, FALSE);
return nmc->return_value;
}
diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion
index 38d7e58..02b236f 100644
--- a/clients/cli/nmcli-completion
+++ b/clients/cli/nmcli-completion
@@ -539,7 +539,9 @@ _nmcli_compl_ARGS()
# remove the options already seen.
for i in ${!OPTIONS[*]}; do
if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then
- unset OPTIONS[$i]
+ if ! _nmcli_array_has_value OPTIONS_REPEATABLE "${OPTIONS[$i]}" ; then
+ unset OPTIONS[$i]
+ fi
fi
done
for i in ${!OPTIONS_MANDATORY[*]}; do
@@ -678,7 +680,7 @@ _nmcli()
cur=''
fi
- local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP
+ local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP OPTIONS_REPEATABLE
local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME HELP_ONLY_AS_FIRST
local COMMAND_CONNECTION_ACTIVE=""
@@ -1254,7 +1256,8 @@ _nmcli()
;;
r|re|res|resc|resca|rescan)
_nmcli_array_delete_at words 0 2
- OPTIONS=(ifname)
+ OPTIONS_REPEATABLE=(ssid)
+ OPTIONS=(ifname ssid)
_nmcli_compl_ARGS
;;
esac
diff --git a/man/nmcli.1.in b/man/nmcli.1.in
index 335b651..dccdfc0 100644
--- a/man/nmcli.1.in
+++ b/man/nmcli.1.in
@@ -21,7 +21,7 @@
.\"
.\" Copyright 2010 - 2014 Red Hat, Inc.
.\"
-.TH NMCLI "1" "3 December 2014"
+.TH NMCLI "1" "12 August 2015"
.SH NAME
nmcli \- command\(hyline tool for controlling NetworkManager
@@ -786,11 +786,15 @@ Available options are:
Otherwise the connection is system\(hywide, which is the default.
.RE
.TP
-.B wifi rescan [[ifname] <ifname>]
+.B wifi rescan [ifname <ifname>] [[ssid <SSID>] ...]
.br
Request that \fINetworkManager\fP immediately re-scan for available access points.
NetworkManager scans Wi\(hyFi networks periodically, but in some cases it can be
-useful to start scanning manually (e.g. after resuming the computer).
+useful to start scanning manually (e.g. after resuming the computer). By using
+\fIssid\fP, it is possible to scan for a specific SSID, which is useful for APs
+with hidden SSIDs. You can provide multiple \fIssid\fP parameters in order to
+scan more SSIDs.
+.br
This command does not show the APs, use 'nmcli device wifi list' for that.
.TP
.B wimax [list [ifname <ifname>] [nsp <name>]]
--
2.4.3
From 0daacf99564462f01ff138af1ac038968519e6e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
Date: Fri, 10 Jul 2015 13:16:21 +0200
Subject: [PATCH 4/5] cli: fix connecting to a hidden SSID with 'nmcli dev wifi
connect' (bgo #752173)
We have to set 802-11-wireless.hidden=true to be able to connect to hidden SSIDs.
nmcli user indicates hidden SSID with 'hidden yes' parameter.
https://bugzilla.gnome.org/show_bug.cgi?id=752173
(cherry picked from commit 5955a66e0904403ff93e75deaaff173d95b6cac4)
(cherry picked from commit e0762f4f2233a37e661158d78a938e01d794b0ab)
---
clients/cli/devices.c | 79 ++++++++++++++++++++++++++++++++++++--------
clients/cli/nmcli-completion | 3 +-
man/nmcli.1.in | 6 +++-
3 files changed, 73 insertions(+), 15 deletions(-)
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index 88a7336..c9ff897 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -276,7 +276,7 @@ usage (void)
" delete <ifname> ...\n\n"
" wifi [list [ifname <ifname>] [bssid <BSSID>]]\n\n"
" wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [ifname <ifname>]\n"
- " [bssid <BSSID>] [name <name>] [private yes|no]\n\n"
+ " [bssid <BSSID>] [name <name>] [private yes|no] [hidden yes|no]\n\n"
" wifi rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n\n"
#if WITH_WIMAX
" wimax [list [ifname <ifname>] [nsp <name>]]\n\n"
@@ -360,7 +360,7 @@ usage_device_wifi (void)
"used to list APs for a particular interface, or with a specific BSSID.\n"
"\n"
"ARGUMENTS := connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [ifname <ifname>]\n"
- " [bssid <BSSID>] [name <name>] [private yes|no]\n"
+ " [bssid <BSSID>] [name <name>] [private yes|no] [hidden yes|no]\n"
"\n"
"Connect to a Wi-Fi network specified by SSID or BSSID. The command creates\n"
"a new connection and then activates it on a device. This is a command-line\n"
@@ -2305,9 +2305,9 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
{
NMDevice *device = NULL;
NMAccessPoint *ap = NULL;
- NM80211ApFlags ap_flags;
- NM80211ApSecurityFlags ap_wpa_flags;
- NM80211ApSecurityFlags ap_rsn_flags;
+ NM80211ApFlags ap_flags = NM_802_11_AP_FLAGS_NONE;
+ NM80211ApSecurityFlags ap_wpa_flags = NM_802_11_AP_SEC_NONE;
+ NM80211ApSecurityFlags ap_rsn_flags = NM_802_11_AP_SEC_NONE;
NMConnection *connection = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
@@ -2319,6 +2319,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
const char *password = NULL;
const char *con_name = NULL;
gboolean private = FALSE;
+ gboolean hidden = FALSE;
gboolean wep_passphrase = FALSE;
GByteArray *bssid1_arr = NULL;
GByteArray *bssid2_arr = NULL;
@@ -2418,6 +2419,19 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
g_clear_error (&err_tmp);
goto error;
}
+ } else if (strcmp (*argv, "hidden") == 0) {
+ GError *err_tmp = NULL;
+ if (next_arg (&argc, &argv) != 0) {
+ g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1));
+ nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+ goto error;
+ }
+ if (!nmc_string_to_bool (*argv, &hidden, &err_tmp)) {
+ g_string_printf (nmc->return_text, _("Error: %s: %s."), *(argv-1), err_tmp->message);
+ nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+ g_clear_error (&err_tmp);
+ goto error;
+ }
} else {
g_printerr (_("Unknown parameter: %s\n"), *argv);
}
@@ -2454,14 +2468,41 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
goto error;
}
+ /* For hidden SSID first scan it so that NM learns about the AP */
+ if (hidden) {
+ GVariantBuilder builder, array_builder;
+ GVariant *options;
+ GError *scan_err = NULL;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aay"));
+ g_variant_builder_add (&array_builder, "@ay",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, param_user, strlen (param_user), 1));
+ g_variant_builder_add (&builder, "{sv}", "ssids", g_variant_builder_end (&array_builder));
+ options = g_variant_builder_end (&builder);
+
+ nm_device_wifi_request_scan_options (NM_DEVICE_WIFI (device), options, NULL, &scan_err);
+ if (scan_err) {
+ g_string_printf (nmc->return_text, _("Error: Failed to scan hidden SSID: %s."),
+ scan_err->message);
+ g_clear_error (&scan_err);
+ nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
+ goto error;
+ }
+ }
+
/* Find an AP to connect to */
ap = find_ap_on_device (device, bssid1_arr, bssid1_arr ? NULL : param_user);
if (!ap && !ifname) {
- /* AP not found. ifname was not specified, so try finding the AP on another device. */
- while ((device = find_wifi_device_by_iface (devices, NULL, &devices_idx)) != NULL) {
- ap = find_ap_on_device (device, bssid1_arr, bssid1_arr ? NULL : param_user);
- if (ap)
+ NMDevice *dev;
+
+ /* AP not found, ifname was not specified, so try finding the AP on another device. */
+ while ((dev = find_wifi_device_by_iface (devices, NULL, &devices_idx)) != NULL) {
+ ap = find_ap_on_device (dev, bssid1_arr, bssid1_arr ? NULL : param_user);
+ if (ap) {
+ device = dev;
break;
+ }
}
}
@@ -2476,7 +2517,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
/* If there are some connection data from user, create a connection and
* fill them into proper settings. */
- if (con_name || private || bssid2_arr || password)
+ if (con_name || private || bssid2_arr || password || hidden)
connection = nm_simple_connection_new ();
if (con_name || private) {
@@ -2491,12 +2532,24 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
if (private)
nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL);
}
- if (bssid2_arr) {
+ if (bssid2_arr || hidden) {
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
- /* 'bssid' parameter is used to restrict the conenction only to the BSSID */
- g_object_set (s_wifi, NM_SETTING_WIRELESS_BSSID, bssid2_arr, NULL);
+ /* 'bssid' parameter is used to restrict the connection only to the BSSID */
+ if (bssid2_arr)
+ g_object_set (s_wifi, NM_SETTING_WIRELESS_BSSID, bssid2_arr, NULL);
+
+ /* 'hidden' parameter is used to indicate that SSID is not broadcasted */
+ if (hidden) {
+ GBytes *ssid = g_bytes_new (param_user, strlen (param_user));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_HIDDEN, hidden,
+ NULL);
+ g_bytes_unref (ssid);
+ }
}
/* handle password */
diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion
index 02b236f..4146eae 100644
--- a/clients/cli/nmcli-completion
+++ b/clients/cli/nmcli-completion
@@ -455,6 +455,7 @@ _nmcli_compl_ARGS()
stp| \
hairpin| \
save| \
+ hidden| \
private)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "yes no"
@@ -1250,7 +1251,7 @@ _nmcli()
fi
else
_nmcli_array_delete_at words 0 3
- local OPTIONS=(password wep-key-type ifname bssid name private)
+ local OPTIONS=(password wep-key-type ifname bssid name private hidden)
_nmcli_compl_ARGS
fi
;;
diff --git a/man/nmcli.1.in b/man/nmcli.1.in
index dccdfc0..6df844d 100644
--- a/man/nmcli.1.in
+++ b/man/nmcli.1.in
@@ -756,7 +756,8 @@ List available Wi\(hyFi access points. The \fIifname\fP and \fIbssid\fP options
can be used to list APs for a particular interface or with a specific BSSID,
respectively.
.TP
-.B wifi connect <(B)SSID> [password <password>] [wep\-key\-type key|phrase] [ifname <ifname>] [bssid <BSSID>] [name <name>] [private yes|no]
+.B wifi connect <(B)SSID> [password <password>] [wep\-key\-type key|phrase] [ifname <ifname>] [bssid <BSSID>] [name <name>]
+.B [private yes|no] [hidden yes|no]
.br
Connect to a Wi\(hyFi network specified by SSID or BSSID. The command creates a new
connection and then activates it on a device. This is a command\(hyline counterpart
@@ -784,6 +785,9 @@ Available options are:
.IP \fIprivate\fP 13
\(en if set to \fByes\fP, the connection will only be visible to the user who created it.
Otherwise the connection is system\(hywide, which is the default.
+.IP \fIhidden\fP 13
+\(en set to \fByes\fP when connecting for the first time to an AP not broadcasting its SSID.
+Otherwise the SSID would not be found and the connection attempt would fail.
.RE
.TP
.B wifi rescan [ifname <ifname>] [[ssid <SSID>] ...]
--
2.4.3
From 2b8867573bb6dc779b0e478e5b426a3b363815ff Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 17 Aug 2015 10:51:52 +0200
Subject: [PATCH 5/5] tests: raise the mock service startup timeout
Python is just too slow on some machines. Needed around twice the previous
limit on BCM2835 with Pidora 20, let's add some safety margin too.
(cherry picked from commit 81cc4d27b117d3d41947d1c974cc03ec521cb83b)
(cherry picked from commit 502b45f0d41c5d7e5a45cc250d9ae6cc5022a23b)
---
libnm-glib/tests/common.c | 2 +-
libnm/tests/common.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libnm-glib/tests/common.c b/libnm-glib/tests/common.c
index 540d43a..f071fb5 100644
--- a/libnm-glib/tests/common.c
+++ b/libnm-glib/tests/common.c
@@ -75,7 +75,7 @@ nm_test_service_init (void)
g_assert_no_error (error);
/* Wait until the service is registered on the bus */
- for (i = 100; i > 0; i--) {
+ for (i = 1000; i > 0; i--) {
if (name_exists (info->bus, "org.freedesktop.NetworkManager"))
break;
g_usleep (G_USEC_PER_SEC / 50);
diff --git a/libnm/tests/common.c b/libnm/tests/common.c
index a28e511..8c1b83a 100644
--- a/libnm/tests/common.c
+++ b/libnm/tests/common.c
@@ -74,7 +74,7 @@ nm_test_service_init (void)
g_assert_no_error (error);
/* Wait until the service is registered on the bus */
- for (i = 100; i > 0; i--) {
+ for (i = 1000; i > 0; i--) {
if (name_exists (info->bus, "org.freedesktop.NetworkManager"))
break;
g_usleep (G_USEC_PER_SEC / 50);
--
2.4.3

View File

@ -1,4 +1,4 @@
[connectivity]
uri=https://fedoraproject.org/static/hotspot.txt
uri=http://fedoraproject.org/static/hotspot.txt
response=OK
interval=300

View File

@ -8,7 +8,7 @@
%define ppp_version %(rpm -q ppp-devel >/dev/null && rpm -q --qf '%%{version}' ppp-devel || echo -n bad)
%define snapshot 20150813git7e2caa2
%define release_version 0.1
%define release_version 0.2
%define realversion 1.0.6
%define epoch_version 1
@ -85,6 +85,8 @@ Source4: 20-connectivity-fedora.conf
# Not upstream.
Patch0: 0000-explain-dns1-dns2.patch
Patch1: 0001-rh1253949-crash-device-deactivate.patch
Patch2: 0002-wifi-ssid-scan-option.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@ -363,6 +365,8 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
%setup -q -n NetworkManager-%{realversion}
%patch0 -p1 -b .0000-explain-dns1-dns2.orig
%patch1 -p1 -b .0001-rh1253949-crash-device-deactivate.orig
%patch2 -p1 -b .0002-wifi-ssid-scan-option.orig
%build
@ -681,6 +685,11 @@ fi
%endif
%changelog
* Tue Aug 18 2015 Thomas Haller <thaller@redhat.com> - 1:1.0.6-0.2.20150813git7e2caa2
- fix crash when deactivating assumed device (rh #1253949)
- backport wifi scan options for ssid
- use plain HTTP URI for connectivity check
* Thu Aug 13 2015 Lubomir Rintel <lkundrak@v3.sk> - 1:1.0.6-0.1.20150813git7e2caa2
- Update to a Git snapshot