summary refs log tree commit diff
path: root/libnm
diff options
context:
space:
mode:
Diffstat (limited to 'libnm')
-rw-r--r--libnm/libnm.ver16
-rw-r--r--libnm/nm-access-point.c43
-rw-r--r--libnm/nm-access-point.h3
-rw-r--r--libnm/nm-client.c18
-rw-r--r--libnm/nm-client.h1
-rw-r--r--libnm/nm-device-wifi.c154
-rw-r--r--libnm/nm-device-wifi.h12
-rw-r--r--libnm/nm-device.c38
-rw-r--r--libnm/nm-device.h3
-rw-r--r--libnm/nm-ifcfg-rh-docs.xml3
-rw-r--r--libnm/nm-manager.c19
-rw-r--r--libnm/nm-manager.h1
-rw-r--r--libnm/nm-property-docs.xml3
-rw-r--r--libnm/nm-setting-docs.xml3
-rw-r--r--libnm/nm-vpn-plugin-old.c93
-rw-r--r--libnm/tests/common.c2
16 files changed, 329 insertions, 83 deletions
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 294bab41..90c5de04 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -851,3 +851,19 @@ global:
 	nm_setting_connection_get_autoconnect_slaves;
 } libnm_1_0_0;
 
+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;
+	nm_setting_wired_get_wake_on_lan;
+	nm_setting_wired_get_wake_on_lan_password;
+	nm_setting_wired_wake_on_lan_get_type;
+	nm_utils_enum_from_str;
+	nm_utils_enum_to_str;
+	nm_utils_wifi_2ghz_freqs;
+	nm_utils_wifi_5ghz_freqs;
+} libnm_1_0_4;
diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c
index e20cd997..c071a927 100644
--- a/libnm/nm-access-point.c
+++ b/libnm/nm-access-point.c
@@ -49,6 +49,7 @@ typedef struct {
 	NM80211Mode mode;
 	guint32 max_bitrate;
 	guint8 strength;
+	gint32 last_seen;
 } NMAccessPointPrivate;
 
 enum {
@@ -63,6 +64,7 @@ enum {
 	PROP_MAX_BITRATE,
 	PROP_STRENGTH,
 	PROP_BSSID,
+	PROP_LAST_SEEN,
 
 	LAST_PROP
 };
@@ -221,6 +223,26 @@ nm_access_point_get_strength (NMAccessPoint *ap)
 }
 
 /**
+ * nm_access_point_get_last_seen:
+ * @ap: a #NMAccessPoint
+ *
+ * Returns the timestamp (in CLOCK_BOOTTIME seconds) for the last time the
+ * access point was found in scan results.  A value of -1 means the access
+ * point has not been found in a scan.
+ *
+ * Returns: the last seen time in seconds
+ *
+ * Since: 1.0.6
+ **/
+gint32
+nm_access_point_get_last_seen (NMAccessPoint *ap)
+{
+	g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), -1);
+
+	return NM_ACCESS_POINT_GET_PRIVATE (ap)->last_seen;
+}
+
+/**
  * nm_access_point_connection_valid:
  * @ap: an #NMAccessPoint to validate @connection against
  * @connection: an #NMConnection to validate against @ap
@@ -364,6 +386,7 @@ nm_access_point_filter_connections (NMAccessPoint *ap, const GPtrArray *connecti
 static void
 nm_access_point_init (NMAccessPoint *ap)
 {
+	NM_ACCESS_POINT_GET_PRIVATE (ap)->last_seen = -1;
 }
 
 static void
@@ -418,6 +441,9 @@ get_property (GObject *object,
 	case PROP_STRENGTH:
 		g_value_set_uchar (value, nm_access_point_get_strength (ap));
 		break;
+	case PROP_LAST_SEEN:
+		g_value_set_int (value, nm_access_point_get_last_seen (ap));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -439,6 +465,7 @@ init_dbus (NMObject *object)
 		{ NM_ACCESS_POINT_MODE,        &priv->mode },
 		{ NM_ACCESS_POINT_MAX_BITRATE, &priv->max_bitrate },
 		{ NM_ACCESS_POINT_STRENGTH,    &priv->strength },
+		{ NM_ACCESS_POINT_LAST_SEEN,   &priv->last_seen },
 		{ NULL },
 	};
 
@@ -595,4 +622,20 @@ nm_access_point_class_init (NMAccessPointClass *ap_class)
 		                     0, G_MAXUINT8, 0,
 		                     G_PARAM_READABLE |
 		                     G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * NMAccessPoint:last-seen:
+	 *
+	 * The timestamp (in CLOCK_BOOTTIME seconds) for the last time the
+	 * access point was found in scan results.  A value of -1 means the
+	 * access point has not been found in a scan.
+	 *
+	 * Since: 1.0.6
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_LAST_SEEN,
+		 g_param_spec_int (NM_ACCESS_POINT_LAST_SEEN, "", "",
+		                   -1, G_MAXINT, -1,
+		                   G_PARAM_READABLE |
+		                   G_PARAM_STATIC_STRINGS));
 }
diff --git a/libnm/nm-access-point.h b/libnm/nm-access-point.h
index 6991c19a..24208fa8 100644
--- a/libnm/nm-access-point.h
+++ b/libnm/nm-access-point.h
@@ -46,6 +46,7 @@ G_BEGIN_DECLS
 #define NM_ACCESS_POINT_MODE        "mode"
 #define NM_ACCESS_POINT_MAX_BITRATE "max-bitrate"
 #define NM_ACCESS_POINT_STRENGTH    "strength"
+#define NM_ACCESS_POINT_LAST_SEEN   "last-seen"
 
 /* DEPRECATED */
 #define NM_ACCESS_POINT_HW_ADDRESS  "hw-address"
@@ -73,6 +74,8 @@ guint32                nm_access_point_get_frequency    (NMAccessPoint *ap);
 NM80211Mode            nm_access_point_get_mode         (NMAccessPoint *ap);
 guint32                nm_access_point_get_max_bitrate  (NMAccessPoint *ap);
 guint8                 nm_access_point_get_strength     (NMAccessPoint *ap);
+NM_AVAILABLE_IN_1_0_6
+gint                   nm_access_point_get_last_seen    (NMAccessPoint *ap);
 
 GPtrArray *            nm_access_point_filter_connections (NMAccessPoint *ap,
                                                            const GPtrArray *connections);
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index e0a2a7b4..982717ce 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -76,6 +76,7 @@ enum {
 	PROP_CONNECTIONS,
 	PROP_HOSTNAME,
 	PROP_CAN_MODIFY,
+	PROP_METERED,
 
 	LAST_PROP
 };
@@ -1288,7 +1289,7 @@ nm_client_add_connection_async (NMClient *client,
 	}
 
 	simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
-	                                    nm_client_deactivate_connection_async);
+	                                    nm_client_add_connection_async);
 	nm_remote_settings_add_connection_async (NM_CLIENT_GET_PRIVATE (client)->settings,
 	                                         connection, save_to_disk,
 	                                         cancellable, add_connection_cb, simple);
@@ -1871,6 +1872,7 @@ get_property (GObject *object, guint prop_id,
 	case PROP_PRIMARY_CONNECTION:
 	case PROP_ACTIVATING_CONNECTION:
 	case PROP_DEVICES:
+	case PROP_METERED:
 		g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
 		                       pspec->name, value);
 		break;
@@ -2143,6 +2145,20 @@ nm_client_class_init (NMClientClass *client_class)
 		                       G_PARAM_READABLE |
 		                       G_PARAM_STATIC_STRINGS));
 
+	/**
+	 * NMClient:metered:
+	 *
+	 * Whether the connectivity is metered.
+	 *
+	 * Since: 1.0.6
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_METERED,
+		 g_param_spec_uint (NM_CLIENT_METERED, "", "",
+		                    0, G_MAXUINT32, NM_METERED_UNKNOWN,
+		                    G_PARAM_READABLE |
+		                    G_PARAM_STATIC_STRINGS));
+
 	/* signals */
 
 	/**
diff --git a/libnm/nm-client.h b/libnm/nm-client.h
index 619ad858..fc309fa1 100644
--- a/libnm/nm-client.h
+++ b/libnm/nm-client.h
@@ -56,6 +56,7 @@ G_BEGIN_DECLS
 #define NM_CLIENT_CONNECTIONS "connections"
 #define NM_CLIENT_HOSTNAME "hostname"
 #define NM_CLIENT_CAN_MODIFY "can-modify"
+#define NM_CLIENT_METERED "metered"
 
 #define NM_CLIENT_DEVICE_ADDED "device-added"
 #define NM_CLIENT_DEVICE_REMOVED "device-removed"
diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c
index 4a19f2e5..536f3082 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 24339fd3..b5a56980 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);
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index cd14c0e9..d3ac705c 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -81,6 +81,7 @@ typedef struct {
 	char *driver_version;
 	char *firmware_version;
 	char *type_description;
+	NMMetered metered;
 	NMDeviceCapabilities capabilities;
 	gboolean managed;
 	gboolean firmware_missing;
@@ -130,6 +131,7 @@ enum {
 	PROP_AVAILABLE_CONNECTIONS,
 	PROP_PHYSICAL_PORT_ID,
 	PROP_MTU,
+	PROP_METERED,
 
 	LAST_PROP
 };
@@ -193,6 +195,7 @@ init_dbus (NMObject *object)
 		{ NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION },
 		{ NM_DEVICE_PHYSICAL_PORT_ID,  &priv->physical_port_id },
 		{ NM_DEVICE_MTU,               &priv->mtu },
+		{ NM_DEVICE_METERED,           &priv->metered },
 
 		/* Properties that exist in D-Bus but that we don't track */
 		{ "ip4-address", NULL },
@@ -449,6 +452,9 @@ get_property (GObject *object,
 	case PROP_MTU:
 		g_value_set_uint (value, nm_device_get_mtu (device));
 		break;
+	case PROP_METERED:
+		g_value_set_uint (value, nm_device_get_metered (device));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -793,6 +799,20 @@ nm_device_class_init (NMDeviceClass *device_class)
 		                    G_PARAM_READABLE |
 		                    G_PARAM_STATIC_STRINGS));
 
+	/**
+	 * NMDevice:metered:
+	 *
+	 * Whether the device is metered.
+	 *
+	 * Since: 1.0.6
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_METERED,
+		 g_param_spec_uint (NM_DEVICE_METERED, "", "",
+		                    0, G_MAXUINT32, NM_METERED_UNKNOWN,
+		                    G_PARAM_READABLE |
+		                    G_PARAM_STATIC_STRINGS));
+
 	/* signals */
 
 	/**
@@ -1884,6 +1904,24 @@ nm_device_get_mtu (NMDevice *device)
 }
 
 /**
+ * nm_device_get_metered:
+ * @device: a #NMDevice
+ *
+ * Gets the metered setting of a #NMDevice.
+ *
+ * Returns: the metered setting.
+ *
+ * Since: 1.0.6
+ **/
+NMMetered
+nm_device_get_metered (NMDevice *device)
+{
+	g_return_val_if_fail (NM_IS_DEVICE (device), NM_METERED_UNKNOWN);
+
+	return NM_DEVICE_GET_PRIVATE (device)->metered;
+}
+
+/**
  * nm_device_is_software:
  * @device: a #NMDevice
  *
diff --git a/libnm/nm-device.h b/libnm/nm-device.h
index 5cc37356..a61dcf32 100644
--- a/libnm/nm-device.h
+++ b/libnm/nm-device.h
@@ -60,6 +60,7 @@ G_BEGIN_DECLS
 #define NM_DEVICE_PRODUCT "product"
 #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
 #define NM_DEVICE_MTU "mtu"
+#define NM_DEVICE_METERED "metered"
 
 struct _NMDevice {
 	NMObject parent;
@@ -119,6 +120,8 @@ gboolean             nm_device_is_software          (NMDevice *device);
 const char *         nm_device_get_product           (NMDevice  *device);
 const char *         nm_device_get_vendor            (NMDevice  *device);
 const char *         nm_device_get_description       (NMDevice  *device);
+NM_AVAILABLE_IN_1_0_6
+NMMetered            nm_device_get_metered           (NMDevice  *device);
 char **              nm_device_disambiguate_names    (NMDevice **devices,
                                                       int        num_devices);
 
diff --git a/libnm/nm-ifcfg-rh-docs.xml b/libnm/nm-ifcfg-rh-docs.xml
index 0c287f26..1ea38141 100644
--- a/libnm/nm-ifcfg-rh-docs.xml
+++ b/libnm/nm-ifcfg-rh-docs.xml
@@ -92,6 +92,7 @@ when this connection is activated."/>
 together with this connection."/>
 <property name="gateway-ping-timeout" variable="GATEWAY_PING_TIMEOUT(+)" format="" values="" default="0" example="GATEWAY_PING_TIMEOUT=5" description="If greater than zero, the IP connectivity will be checked by
 pinging the gateway and waiting for the specified timeout (in seconds)."/>
+<property name="metered" variable="CONNECTION_METERED" format="" values="yes,no,unknown" default="" example="CONNECTION_METERED=yes" description="Whether the device is metered"/>
 </setting>
 <setting name="dcb">
 <property name="app-fcoe-flags" variable="DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING" format="" values="" default="no" example="DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes" description="FCOE flags."/>
@@ -192,7 +193,7 @@ IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no" default="no" example="IPV6_PRIVACY=rfc30
 <setting name="vlan">
 <property name="parent" variable="DEVICE or PHYSDEV" format="" values="" default="" example="" description="Parent interface of the VLAN."/>
 <property name="id" variable="VLAN_ID or DEVICE" format="" values="" default="" example="" description="VLAN identifier."/>
-<property name="flags" variable="VLAN_FLAGS, REORDER_HDR" format="" values="&quot;GVRP&quot;, &quot;LOOSE_BINDING&quot; for VLAN_FLAGS; 0 or 1 for REORDER_HDR" default="" example="" description="Parent interface of the VLAN."/>
+<property name="flags" variable="VLAN_FLAGS, REORDER_HDR" format="" values="&quot;GVRP&quot;, &quot;LOOSE_BINDING&quot; for VLAN_FLAGS; 0 or 1 for REORDER_HDR" default="" example="" description="VLAN flags."/>
 <property name="ingress-property-map" variable="VLAN_INGRESS_PRIORITY_MAP" format="" values="" default="" example="VLAN_INGRESS_PRIORITY_MAP=4:2,3:5" description="Ingress priority mapping."/>
 <property name="egress-property-map" variable="VLAN_EGRESS_PRIORITY_MAP" format="" values="" default="" example="VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7" description="Egress priority mapping."/>
 <property name="interface-name" variable="PHYSDEV and VLAN_ID, or DEVICE" format="" values="" default="" example="PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12" description="VLAN interface name.
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c
index 003d6b87..2a61a010 100644
--- a/libnm/nm-manager.c
+++ b/libnm/nm-manager.c
@@ -64,6 +64,7 @@ typedef struct {
 	NMConnectivityState connectivity;
 	NMActiveConnection *primary_connection;
 	NMActiveConnection *activating_connection;
+	NMMetered metered;
 
 	GCancellable *perm_call_cancellable;
 	GHashTable *permissions;
@@ -102,6 +103,7 @@ enum {
 	PROP_PRIMARY_CONNECTION,
 	PROP_ACTIVATING_CONNECTION,
 	PROP_DEVICES,
+	PROP_METERED,
 
 	LAST_PROP
 };
@@ -179,6 +181,7 @@ init_dbus (NMObject *object)
 		{ NM_MANAGER_PRIMARY_CONNECTION,        &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
 		{ NM_MANAGER_ACTIVATING_CONNECTION,     &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
 		{ NM_MANAGER_DEVICES,                   &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
+		{ NM_MANAGER_METERED,                   &priv->metered },
 		{ NULL },
 	};
 
@@ -1537,6 +1540,9 @@ get_property (GObject *object,
 	case PROP_DEVICES:
 		g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
 		break;
+	case PROP_METERED:
+		g_value_set_uint (value, priv->metered);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1669,6 +1675,19 @@ nm_manager_class_init (NMManagerClass *manager_class)
 		                     G_TYPE_PTR_ARRAY,
 		                     G_PARAM_READABLE |
 		                     G_PARAM_STATIC_STRINGS));
+	/**
+	 * NMManager:metered:
+	 *
+	 * Whether the connectivity is metered.
+	 *
+	 * Since: 1.0.6
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_METERED,
+		 g_param_spec_uint (NM_MANAGER_METERED, "", "",
+		                    0, G_MAXUINT32, NM_METERED_UNKNOWN,
+		                    G_PARAM_READABLE |
+		                    G_PARAM_STATIC_STRINGS));
 
 	/* signals */
 
diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h
index ca9f7dd6..8d04a060 100644
--- a/libnm/nm-manager.h
+++ b/libnm/nm-manager.h
@@ -50,6 +50,7 @@ G_BEGIN_DECLS
 #define NM_MANAGER_PRIMARY_CONNECTION "primary-connection"
 #define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
 #define NM_MANAGER_DEVICES "devices"
+#define NM_MANAGER_METERED "metered"
 
 typedef struct {
 	NMObject parent;
diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml
index 7bbf97a1..e9a58128 100644
--- a/libnm/nm-property-docs.xml
+++ b/libnm/nm-property-docs.xml
@@ -88,6 +88,7 @@
     <property name="id" type="string" description="A human readable unique identifier for the connection, like &quot;Work Wi-Fi&quot; or &quot;T-Mobile 3G&quot;." />
     <property name="interface-name" type="string" description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface." />
     <property name="master" type="string" description="Interface name of the master device or UUID of the master connection." />
+    <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered." />
     <property name="name" type="string" default="connection" description="The setting's name, which uniquely identifies the setting within the connection.  Each setting type has a name unique to that type, for example &quot;ppp&quot; or &quot;wireless&quot; or &quot;wired&quot;." />
     <property name="permissions" type="array of string" default="[]" description="An array of strings defining what access a given user has to this connection.  If this is NULL or empty, all users are allowed to access this connection.  Otherwise a user is allowed to access this connection if and only if they are in this list. Each entry is of the form &quot;[type]:[id]:[reserved]&quot;; for example, &quot;user:dcbw:blah&quot;. At this time only the &quot;user&quot; [type] is allowed.  Any other values are ignored and reserved for future use.  [id] is the username that this permission refers to, which may not contain the &quot;:&quot; character. Any [reserved] information present must be ignored and is reserved for future use.  All of [type], [id], and [reserved] must be valid UTF-8." />
     <property name="read-only" type="boolean" default="FALSE" description="FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified." />
@@ -257,6 +258,8 @@
     <property name="s390-options" type="dict of string to string" default="{}" description="Dictionary of key/value pairs of s390-specific device options.  Both keys and values must be strings.  Allowed keys include &quot;portno&quot;, &quot;layer2&quot;, &quot;portname&quot;, &quot;protocol&quot;, among others.  Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9])." />
     <property name="s390-subchannels" type="array of string" default="[]" description="Identifies specific subchannels that this network device uses for communication with z/VM or s390 host.  Like the &quot;mac-address&quot; property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels.  The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character." />
     <property name="speed" type="uint32" default="0" description="If non-zero, request that the device use only the specified speed.  In Mbit/s, ie 100 == 100Mbit/s." />
+    <property name="wake-on-lan" type="uint32" default="1" description="The NMSettingWiredWakeOnLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRED_WAKE_ON_LAN_PHY (0x2), NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST (0x4), NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST (0x8), NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST (0x10), NM_SETTING_WIRED_WAKE_ON_LAN_ARP (0x20), NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC (0x40)." />
+    <property name="wake-on-lan-password" type="string" description="If specified, the password used with magic-packet-based Wake-on-LAN, represented as an Ethernet MAC address.  If NULL, no password will be required." />
   </setting>
   <setting name="802-11-wireless">
     <property name="band" type="string" description="802.11 frequency band of the network.  One of &quot;a&quot; for 5GHz 802.11a or &quot;bg&quot; for 2.4GHz 802.11.  This will lock associations to the Wi-Fi network to the specific band, i.e. if &quot;a&quot; is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible.  This setting depends on specific driver capability and may not work with all drivers." />
diff --git a/libnm/nm-setting-docs.xml b/libnm/nm-setting-docs.xml
index c2cb80ed..8338fbca 100644
--- a/libnm/nm-setting-docs.xml
+++ b/libnm/nm-setting-docs.xml
@@ -90,6 +90,7 @@
     <property name="id" type="string" description="A human readable unique identifier for the connection, like &quot;Work Wi-Fi&quot; or &quot;T-Mobile 3G&quot;." />
     <property name="interface-name" type="string" description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface." />
     <property name="master" type="string" description="Interface name of the master device or UUID of the master connection." />
+    <property name="metered" type="NMMetered (int32)" description="Whether the connection is metered." />
     <property name="name" type="string" default="connection" description="The setting's name, which uniquely identifies the setting within the connection.  Each setting type has a name unique to that type, for example &quot;ppp&quot; or &quot;wireless&quot; or &quot;wired&quot;." />
     <property name="permissions" type="array of string" default="[]" description="An array of strings defining what access a given user has to this connection.  If this is NULL or empty, all users are allowed to access this connection.  Otherwise a user is allowed to access this connection if and only if they are in this list. Each entry is of the form &quot;[type]:[id]:[reserved]&quot;; for example, &quot;user:dcbw:blah&quot;. At this time only the &quot;user&quot; [type] is allowed.  Any other values are ignored and reserved for future use.  [id] is the username that this permission refers to, which may not contain the &quot;:&quot; character. Any [reserved] information present must be ignored and is reserved for future use.  All of [type], [id], and [reserved] must be valid UTF-8." />
     <property name="read-only" type="boolean" default="FALSE" description="FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified." />
@@ -265,6 +266,8 @@
     <property name="s390-options" type="dict of string to string" default="{}" description="Dictionary of key/value pairs of s390-specific device options.  Both keys and values must be strings.  Allowed keys include &quot;portno&quot;, &quot;layer2&quot;, &quot;portname&quot;, &quot;protocol&quot;, among others.  Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9])." />
     <property name="s390-subchannels" type="array of string" default="[]" description="Identifies specific subchannels that this network device uses for communication with z/VM or s390 host.  Like the &quot;mac-address&quot; property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels.  The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character." />
     <property name="speed" type="uint32" default="0" description="If non-zero, request that the device use only the specified speed.  In Mbit/s, ie 100 == 100Mbit/s." />
+    <property name="wake-on-lan" type="uint32" default="1" description="The NMSettingWiredWakeOnLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRED_WAKE_ON_LAN_PHY (0x2), NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST (0x4), NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST (0x8), NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST (0x10), NM_SETTING_WIRED_WAKE_ON_LAN_ARP (0x20), NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC (0x40)." />
+    <property name="wake-on-lan-password" type="string" description="If specified, the password used with magic-packet-based Wake-on-LAN, represented as an Ethernet MAC address.  If NULL, no password will be required." />
   </setting>
   <setting name="802-11-wireless">
     <property name="band" type="string" description="802.11 frequency band of the network.  One of &quot;a&quot; for 5GHz 802.11a or &quot;bg&quot; for 2.4GHz 802.11.  This will lock associations to the Wi-Fi network to the specific band, i.e. if &quot;a&quot; is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible.  This setting depends on specific driver capability and may not work with all drivers." />
diff --git a/libnm/nm-vpn-plugin-old.c b/libnm/nm-vpn-plugin-old.c
index b43c481c..24d8e401 100644
--- a/libnm/nm-vpn-plugin-old.c
+++ b/libnm/nm-vpn-plugin-old.c
@@ -40,6 +40,7 @@
 #include "nm-dbus-helpers.h"
 #include "nm-core-internal.h"
 #include "nm-simple-connection.h"
+#include "nm-macros-internal.h"
 
 #include "nmdbus-vpn-plugin.h"
 
@@ -229,6 +230,7 @@ connect_timer_expired (gpointer data)
 	NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data);
 	GError *err = NULL;
 
+	NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->connect_timer = 0;
 	g_message ("Connect timer expired, disconnecting.");
 	nm_vpn_plugin_old_disconnect (plugin, &err);
 	if (err) {
@@ -236,26 +238,38 @@ connect_timer_expired (gpointer data)
 		g_error_free (err);
 	}
 
-	return FALSE;
+	return G_SOURCE_REMOVE;
 }
 
 static gboolean
 quit_timer_expired (gpointer data)
 {
-	NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data);
+	NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD (data);
+
+	NM_VPN_PLUGIN_OLD_GET_PRIVATE (self)->quit_timer = 0;
+	nm_vpn_plugin_old_emit_quit (self);
+	return G_SOURCE_REMOVE;
+}
 
-	nm_vpn_plugin_old_emit_quit (plugin);
+static void
+schedule_quit_timer (NMVpnPluginOld *self)
+{
+	NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (self);
 
-	return FALSE;
+	nm_clear_g_source (&priv->quit_timer);
+	priv->quit_timer = g_timeout_add_seconds (NM_VPN_PLUGIN_OLD_QUIT_TIMER,
+	                                          quit_timer_expired,
+	                                          self);
 }
 
 static gboolean
 fail_stop (gpointer data)
 {
-	NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data);
+	NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD (data);
 
-	nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
-	return FALSE;
+	NM_VPN_PLUGIN_OLD_GET_PRIVATE (self)->fail_stop_id = 0;
+	nm_vpn_plugin_old_set_state (self, NM_VPN_SERVICE_STATE_STOPPED);
+	return G_SOURCE_REMOVE;
 }
 
 static void
@@ -263,8 +277,7 @@ schedule_fail_stop (NMVpnPluginOld *plugin)
 {
 	NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
 
-	if (priv->fail_stop_id)
-		g_source_remove (priv->fail_stop_id);
+	nm_clear_g_source (&priv->fail_stop_id);
 	priv->fail_stop_id = g_idle_add (fail_stop, plugin);
 }
 
@@ -369,21 +382,11 @@ nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin,
 }
 
 static void
-connect_timer_removed (gpointer data)
-{
-	NM_VPN_PLUGIN_OLD_GET_PRIVATE (data)->connect_timer = 0;
-}
-
-static void
 connect_timer_start (NMVpnPluginOld *plugin)
 {
 	NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
 
-	priv->connect_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
-	                                                  60,
-	                                                  connect_timer_expired,
-	                                                  plugin,
-	                                                  connect_timer_removed);
+	priv->connect_timer = g_timeout_add_seconds (60, connect_timer_expired, plugin);
 }
 
 static void
@@ -508,6 +511,11 @@ impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin,
 	}
 
 	if (needed) {
+		/* Push back the quit timer so the VPN plugin doesn't quit in the
+		 * middle of asking the user for secrets.
+		 */
+		schedule_quit_timer (plugin);
+
 		g_assert (setting_name);
 		g_dbus_method_invocation_return_value (context,
 		                                       g_variant_new ("(s)", setting_name));
@@ -607,8 +615,7 @@ nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin,
 	/* Cancel the connect timer since secrets might take a while.  It'll
 	 * get restarted when the secrets come back via NewSecrets().
 	 */
-	if (priv->connect_timer)
-		g_source_remove (priv->connect_timer);
+	nm_clear_g_source (&priv->connect_timer);
 
 	g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints);
 }
@@ -993,10 +1000,9 @@ dispose (GObject *object)
 	NMVpnServiceState state;
 	GError *err = NULL;
 
-	if (priv->fail_stop_id) {
-		g_source_remove (priv->fail_stop_id);
-		priv->fail_stop_id = 0;
-	}
+	nm_clear_g_source (&priv->fail_stop_id);
+	nm_clear_g_source (&priv->quit_timer);
+	nm_clear_g_source (&priv->connect_timer);
 
 	state = nm_vpn_plugin_old_get_state (plugin);
 
@@ -1030,46 +1036,23 @@ finalize (GObject *object)
 }
 
 static void
-quit_timer_removed (gpointer data)
-{
-	NM_VPN_PLUGIN_OLD_GET_PRIVATE (data)->quit_timer = 0;
-}
-
-static void
 state_changed (NMVpnPluginOld *plugin, NMVpnServiceState state)
 {
 	NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
 
 	switch (state) {
 	case NM_VPN_SERVICE_STATE_STARTING:
-		/* Remove the quit timer. */
-		if (priv->quit_timer)
-			g_source_remove (priv->quit_timer);
-
-		if (priv->fail_stop_id) {
-			g_source_remove (priv->fail_stop_id);
-			priv->fail_stop_id = 0;
-		}
+		nm_clear_g_source (&priv->quit_timer);
+		nm_clear_g_source (&priv->fail_stop_id);
 		break;
 	case NM_VPN_SERVICE_STATE_STOPPED:
-		priv->quit_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
-		                                               NM_VPN_PLUGIN_OLD_QUIT_TIMER,
-		                                               quit_timer_expired,
-		                                               plugin,
-		                                               quit_timer_removed);
+		schedule_quit_timer (plugin);
 		break;
 	default:
 		/* Clean up all timers we might have set up. */
-		if (priv->connect_timer)
-			g_source_remove (priv->connect_timer);
-
-		if (priv->quit_timer)
-			g_source_remove (priv->quit_timer);
-
-		if (priv->fail_stop_id) {
-			g_source_remove (priv->fail_stop_id);
-			priv->fail_stop_id = 0;
-		}
+		nm_clear_g_source (&priv->connect_timer);
+		nm_clear_g_source (&priv->quit_timer);
+		nm_clear_g_source (&priv->fail_stop_id);
 		break;
 	}
 }
diff --git a/libnm/tests/common.c b/libnm/tests/common.c
index a28e5112..8c1b83a8 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);