Merge ~alfonsosanchezbeato/network-manager:backport-bionic into network-manager:bionic

Proposed by Alfonso Sanchez-Beato
Status: Approved
Approved by: Tony Espy
Approved revision: da2569073d4f86a2334488b4c843cd25f623363b
Proposed branch: ~alfonsosanchezbeato/network-manager:backport-bionic
Merge into: network-manager:bionic
Diff against target: 932 lines (+903/-2)
3 files modified
debian/changelog (+7/-2)
debian/patches/Support-for-WoWLAN.patch (+895/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
System Enablement Bot continuous-integration Needs Fixing
Tony Espy Approve
Review via email: mp+349465@code.launchpad.net

Description of the change

debian/patches/Support-for-WoWLAN.patch: backport WoWLAN support

Backport WoWLAN support from NM upstream 1.12/1.14 (LP: #1781597)

To post a comment you must log in.
Revision history for this message
Tony Espy (awe) wrote :

I've compared this to upstream, and the only thing that seems odd is that the last four commits you list are not part of any 1.12.x branch, but only exist in master:

ac1302793 platform: add methods to retrieve current WoWLAN state
c6e40215e devices: restore past WoWLAN when disconnecting wifi
a3289400d wifi: ensure wake-on-wlan restore only acts once
2c3a14fed platform/wifi: drop *_get_wowlan()

Looking closer, the last two are a bug fix and cleanup of unused code submitted by upstream developers, whereas the first two are commits from you. Why didn't these land in 1.12?

Given these differences, your MP description and debian/changelog aren't accurate, as in addition to backporting from 1.12, you've also pulled from master too. I'm not as concerned about the MP description (although it would've been helpful in advance), but you should mention this in the changelog, and maybe in the patch too.

Can you also please update the dates in your debian/changelog and .patch file to be current?

Also have you pushed versions to a PPA anywhere that can be tested, or do you want to just wait and test the version that gets pushed to bionic-proposed?

review: Needs Fixing
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Hm, not sure why they did not include those commits, I thought they had. I think they just took the minimum changes to get working WoWLAN in. Of those 4 commits, 3 are for restoring previous WoWLAN settings if, say, we had some WoWLAN setting set with "iw", then used NM to set something different. The patches make sure we put the original WoWLAN settings when we unset WoWLAN from NM instead of just disabling it. As you see, is quite a corner case and we can live without those patches. The 4th patch is just some clean-up.

No, I do not have a PPA, but I tested this building from sources in the 1.10 branch. We can test on bionic-proposed when the package is ready.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

@Tony, MP refreshed after updating changelog/comments.

Revision history for this message
Tony Espy (awe) wrote :

LGTM

review: Approve
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)

Unmerged commits

da25690... by Alfonso Sanchez-Beato

debian/patches/Support-for-WoWLAN.patch: backport WoWLAN support

Backport WoWLAN support from NM upstream 1.12/1.14

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index f38eacf..c9a9d48 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,10 +1,15 @@
6-network-manager (1.10.6-2ubuntu1.1) UNRELEASED; urgency=medium
7+network-manager (1.10.6-2ubuntu1.2) UNRELEASED; urgency=medium
8
9+ [ Mathieu Trudel-Lapierre ]
10 * debian/10-globally-managed-devices.conf: adjust exception for wwan to
11 specify cdma and gsm, since those are the actual types handled by NM/MM.
12 (LP: #1780606)
13
14- -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Tue, 10 Jul 2018 08:13:52 -0400
15+ [ Alfonso Sanchez-Beato (email Canonical) ]
16+ * debian/patches/Support-for-WoWLAN.patch: backport WoWLAN support from NM
17+ upstream 1.12, plus some patches from 1.14 (LP: #1781597)
18+
19+ -- Alfonso Sanchez-Beato (email Canonical) <alfonso.sanchez-beato@canonical.com> Thu, 11 Oct 2018 12:33:47 +0200
20
21 network-manager (1.10.6-2ubuntu1) bionic; urgency=medium
22
23diff --git a/debian/patches/Support-for-WoWLAN.patch b/debian/patches/Support-for-WoWLAN.patch
24new file mode 100644
25index 0000000..38f33da
26--- /dev/null
27+++ b/debian/patches/Support-for-WoWLAN.patch
28@@ -0,0 +1,895 @@
29+From: =?utf-8?q?Alfonso_S=C3=A1nchez-Beato?=
30+ <alfonso.sanchez-beato@canonical.com>
31+Date: Fri, 13 Jul 2018 11:54:30 +0200
32+Subject: Support for WoWLAN
33+
34+This add supports for WoWLAN by backporting upstream patches.
35+
36+From NM 1.12:
37+58cdc7b55 libnm-core: add wake-on-wlan configuration items
38+1621c79e7 platform: add support for wake-on-wlan
39+ea10016d2 devices: enable wake-on-wlan when device is enabled
40+ca3bbede7 core: don't shutdown interfaces if they have wowlan enabled
41+cb8003c40 cli: add support for wake-on-wlan properties
42+8cba4d95d device/wifi: use _LOGD() macros in wake_on_wlan_enable()
43+36e9ec055 wifi: fix check for valid NMSettingWirelessWakeOnWLan flag
44+
45+From NM 1.14:
46+ac1302793 platform: add methods to retrieve current WoWLAN state
47+c6e40215e devices: restore past WoWLAN when disconnecting wifi
48+a3289400d wifi: ensure wake-on-wlan restore only acts once
49+2c3a14fed platform/wifi: drop *_get_wowlan()
50+---
51+ clients/common/nm-meta-setting-desc.c | 14 ++++
52+ clients/common/settings-docs.c | 1 +
53+ clients/common/settings-docs.c.in | 1 +
54+ libnm-core/nm-setting-wireless.c | 72 +++++++++++++++++
55+ libnm-core/nm-setting-wireless.h | 46 +++++++++++
56+ libnm/libnm.ver | 2 +
57+ src/devices/wifi/nm-device-wifi.c | 102 +++++++++++++++++++++++-
58+ src/nm-manager.c | 27 ++++---
59+ src/platform/nm-linux-platform.c | 19 ++++-
60+ src/platform/nm-platform.c | 20 +++++
61+ src/platform/nm-platform.h | 5 ++
62+ src/platform/wifi/wifi-utils-nl80211.c | 139 ++++++++++++++++++++++++---------
63+ src/platform/wifi/wifi-utils-private.h | 8 +-
64+ src/platform/wifi/wifi-utils.c | 28 ++++---
65+ src/platform/wifi/wifi-utils.h | 7 +-
66+ 15 files changed, 425 insertions(+), 66 deletions(-)
67+
68+diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
69+index 94404e9..21763a8 100644
70+--- a/clients/common/nm-meta-setting-desc.c
71++++ b/clients/common/nm-meta-setting-desc.c
72+@@ -7271,6 +7271,20 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = {
73+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT,
74+ ),
75+ ),
76++ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_WAKE_ON_WLAN,
77++ .property_type = &_pt_gobject_enum,
78++ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
79++ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
80++ .get_gtype = nm_setting_wireless_wake_on_wlan_get_type,
81++ .value_infos = ENUM_VALUE_INFOS (
82++ {
83++ .value = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE,
84++ .nick = "disabled",
85++ }
86++ ),
87++ ),
88++ ),
89++ ),
90+ NULL
91+ };
92+
93+diff --git a/clients/common/settings-docs.c b/clients/common/settings-docs.c
94+index bf5753c..911164a 100644
95+--- a/clients/common/settings-docs.c
96++++ b/clients/common/settings-docs.c
97+@@ -21,6 +21,7 @@
98+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SEEN_BSSIDS N_("A list of BSSIDs (each BSSID formatted as a MAC address like \"00:11:22:33:44:55\") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved.")
99+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SSID N_("SSID of the Wi-Fi network. Must be specified.")
100+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_TX_POWER N_("If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.")
101++#define DESCRIBE_DOC_NM_SETTING_WIRELESS_WAKE_ON_WLAN N_("The NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY (0x2), NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT (0x4), NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC (0x8), NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE (0x10), NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST (0x20), NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE (0x40), NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE (0x80), NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP (0x100) or the special values NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).")
102+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_AUTH_ALG N_("When WEP is used (ie, key-mgmt = \"none\" or \"ieee8021x\") indicate the 802.11 authentication algorithm required by the AP here. One of \"open\" for Open System, \"shared\" for Shared Key, or \"leap\" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\") the \"leap-username\" and \"leap-password\" properties must be specified.")
103+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_GROUP N_("A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"wep40\", \"wep104\", \"tkip\", or \"ccmp\".")
104+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-none\" (Ad-Hoc WPA-PSK), \"wpa-psk\" (infrastructure WPA-PSK), or \"wpa-eap\" (WPA-Enterprise). This property must be set for any Wi-Fi connection that uses security.")
105+diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in
106+index bf5753c..911164a 100644
107+--- a/clients/common/settings-docs.c.in
108++++ b/clients/common/settings-docs.c.in
109+@@ -21,6 +21,7 @@
110+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SEEN_BSSIDS N_("A list of BSSIDs (each BSSID formatted as a MAC address like \"00:11:22:33:44:55\") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved.")
111+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SSID N_("SSID of the Wi-Fi network. Must be specified.")
112+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_TX_POWER N_("If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.")
113++#define DESCRIBE_DOC_NM_SETTING_WIRELESS_WAKE_ON_WLAN N_("The NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY (0x2), NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT (0x4), NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC (0x8), NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE (0x10), NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST (0x20), NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE (0x40), NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE (0x80), NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP (0x100) or the special values NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).")
114+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_AUTH_ALG N_("When WEP is used (ie, key-mgmt = \"none\" or \"ieee8021x\") indicate the 802.11 authentication algorithm required by the AP here. One of \"open\" for Open System, \"shared\" for Shared Key, or \"leap\" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\") the \"leap-username\" and \"leap-password\" properties must be specified.")
115+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_GROUP N_("A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"wep40\", \"wep104\", \"tkip\", or \"ccmp\".")
116+ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-none\" (Ad-Hoc WPA-PSK), \"wpa-psk\" (infrastructure WPA-PSK), or \"wpa-eap\" (WPA-Enterprise). This property must be set for any Wi-Fi connection that uses security.")
117+diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c
118+index 0a3915b..7500c97 100644
119+--- a/libnm-core/nm-setting-wireless.c
120++++ b/libnm-core/nm-setting-wireless.c
121+@@ -63,6 +63,7 @@ typedef struct {
122+ gboolean hidden;
123+ guint32 powersave;
124+ NMSettingMacRandomization mac_address_randomization;
125++ guint32 wowl;
126+ } NMSettingWirelessPrivate;
127+
128+ enum {
129+@@ -83,6 +84,7 @@ enum {
130+ PROP_HIDDEN,
131+ PROP_POWERSAVE,
132+ PROP_MAC_ADDRESS_RANDOMIZATION,
133++ PROP_WAKE_ON_WLAN,
134+
135+ LAST_PROP
136+ };
137+@@ -885,6 +887,26 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
138+ return FALSE;
139+ }
140+
141++ if (NM_FLAGS_ANY (priv->wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) {
142++ if (!nm_utils_is_power_of_two (priv->wowl)) {
143++ g_set_error_literal (error,
144++ NM_CONNECTION_ERROR,
145++ NM_CONNECTION_ERROR_INVALID_PROPERTY,
146++ _("Wake-on-WLAN mode 'default' and 'ignore' are exclusive flags"));
147++ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME,
148++ NM_SETTING_WIRELESS_WAKE_ON_WLAN);
149++ return FALSE;
150++ }
151++ } else if (NM_FLAGS_ANY (priv->wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) {
152++ g_set_error_literal (error,
153++ NM_CONNECTION_ERROR,
154++ NM_CONNECTION_ERROR_INVALID_PROPERTY,
155++ _("Wake-on-WLAN trying to set unknown flag"));
156++ g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME,
157++ NM_SETTING_WIRELESS_WAKE_ON_WLAN);
158++ return FALSE;
159++ }
160++
161+ /* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */
162+
163+ if (priv->cloned_mac_address) {
164+@@ -939,6 +961,24 @@ nm_setting_wireless_get_security (NMSetting *setting,
165+ return NULL;
166+ }
167+
168++/**
169++ * nm_setting_wireless_get_wake_on_wlan:
170++ * @setting: the #NMSettingWireless
171++ *
172++ * Returns the Wake-on-WLAN options enabled for the connection
173++ *
174++ * Returns: the Wake-on-WLAN options
175++ *
176++ * Since: 1.12
177++ */
178++NMSettingWirelessWakeOnWLan
179++nm_setting_wireless_get_wake_on_wlan (NMSettingWireless *setting)
180++{
181++ g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE);
182++
183++ return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->wowl;
184++}
185++
186+ static void
187+ clear_blacklist_item (char **item_p)
188+ {
189+@@ -1061,6 +1101,9 @@ set_property (GObject *object, guint prop_id,
190+ case PROP_MAC_ADDRESS_RANDOMIZATION:
191+ priv->mac_address_randomization = g_value_get_uint (value);
192+ break;
193++ case PROP_WAKE_ON_WLAN:
194++ priv->wowl = g_value_get_uint (value);
195++ break;
196+ default:
197+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
198+ break;
199+@@ -1123,6 +1166,9 @@ get_property (GObject *object, guint prop_id,
200+ case PROP_MAC_ADDRESS_RANDOMIZATION:
201+ g_value_set_uint (value, nm_setting_wireless_get_mac_address_randomization (setting));
202+ break;
203++ case PROP_WAKE_ON_WLAN:
204++ g_value_set_uint (value, nm_setting_wireless_get_wake_on_wlan (setting));
205++ break;
206+ default:
207+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
208+ break;
209+@@ -1633,4 +1679,30 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_wireless_class)
210+ _nm_setting_class_add_dbus_only_property (setting_class, "security",
211+ G_VARIANT_TYPE_STRING,
212+ nm_setting_wireless_get_security, NULL);
213++
214++ /**
215++ * NMSettingWireless:wake-on-wlan:
216++ *
217++ * The #NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options.
218++ * May be any combination of %NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY,
219++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT,
220++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC,
221++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE,
222++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST,
223++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE,
224++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE,
225++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP or the special values
226++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (to use global settings) and
227++ * %NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (to disable management of Wake-on-LAN in
228++ * NetworkManager).
229++ *
230++ * Since: 1.12
231++ **/
232++ g_object_class_install_property
233++ (object_class, PROP_WAKE_ON_WLAN,
234++ g_param_spec_uint (NM_SETTING_WIRELESS_WAKE_ON_WLAN, "", "",
235++ 0, G_MAXUINT32, NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT,
236++ G_PARAM_CONSTRUCT |
237++ G_PARAM_READWRITE |
238++ G_PARAM_STATIC_STRINGS));
239+ }
240+diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h
241+index b0ef475..4c1850f 100644
242+--- a/libnm-core/nm-setting-wireless.h
243++++ b/libnm-core/nm-setting-wireless.h
244+@@ -41,6 +41,48 @@ G_BEGIN_DECLS
245+
246+ #define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless"
247+
248++/**
249++ * NMSettingWirelessWakeOnWLan:
250++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE: Wake-on-WLAN disabled
251++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY: Wake on any activity
252++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT: Wake on disconnect
253++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC: Wake on magic packet
254++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE: Wake on GTK rekey failure
255++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST: Wake on EAP identity request
256++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE: Wake on 4way hanshake
257++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE: Wake on rfkill release
258++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL: Wake on all events. This does not
259++ * include the exclusive flags @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT or
260++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE.
261++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT: Use the default value
262++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE: Don't change configured settings
263++ * @NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS: Mask of flags that are
264++ * incompatible with other flags
265++ *
266++ * Options for #NMSettingWireless:wake-on-wlan. Note that not all options
267++ * are supported by all devices.
268++ *
269++ * Since: 1.12
270++ */
271++typedef enum { /*< flags >*/
272++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE = 0, /*< skip >*/
273++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY = (1 << 1),
274++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT = (1 << 2),
275++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC = (1 << 3),
276++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE = (1 << 4),
277++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST = (1 << 5),
278++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE = (1 << 6),
279++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE = (1 << 7),
280++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP = (1 << 8),
281++ _NM_SETTING_WIRELESS_WAKE_ON_WLAN_NUM, /*< skip >*/
282++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_LAST = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_NUM - 1, /*< skip >*/
283++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL = ((NM_SETTING_WIRELESS_WAKE_ON_WLAN_LAST << 1) - 1) - (1 << 0 /*DEFAULT*/), /*< skip >*/
284++
285++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT = (1 << 0),
286++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE = (1 << 15),
287++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT | NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE, /*< skip >*/
288++} NMSettingWirelessWakeOnWLan;
289++
290+ #define NM_SETTING_WIRELESS_SSID "ssid"
291+ #define NM_SETTING_WIRELESS_MODE "mode"
292+ #define NM_SETTING_WIRELESS_BAND "band"
293+@@ -57,6 +99,7 @@ G_BEGIN_DECLS
294+ #define NM_SETTING_WIRELESS_HIDDEN "hidden"
295+ #define NM_SETTING_WIRELESS_POWERSAVE "powersave"
296+ #define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization"
297++#define NM_SETTING_WIRELESS_WAKE_ON_WLAN "wake-on-wlan"
298+
299+ /**
300+ * NM_SETTING_WIRELESS_MODE_ADHOC:
301+@@ -166,6 +209,9 @@ gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless
302+ NM80211ApSecurityFlags ap_rsn,
303+ NM80211Mode ap_mode);
304+
305++NM_AVAILABLE_IN_1_10
306++NMSettingWirelessWakeOnWLan nm_setting_wireless_get_wake_on_wlan (NMSettingWireless *setting);
307++
308+ G_END_DECLS
309+
310+ #endif /* __NM_SETTING_WIRELESS_H__ */
311+diff --git a/libnm/libnm.ver b/libnm/libnm.ver
312+index 7646a93..3376848 100644
313+--- a/libnm/libnm.ver
314++++ b/libnm/libnm.ver
315+@@ -1276,6 +1276,8 @@ global:
316+ nm_setting_team_remove_link_watcher_by_value;
317+ nm_setting_team_remove_runner_tx_hash;
318+ nm_setting_team_remove_runner_tx_hash_by_value;
319++ nm_setting_wireless_get_wake_on_wlan;
320++ nm_setting_wireless_wake_on_wlan_get_type;
321+ nm_tc_action_dup;
322+ nm_tc_action_equal;
323+ nm_tc_action_get_attribute;
324+diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
325+index bf02109..e06aa32 100644
326+--- a/src/devices/wifi/nm-device-wifi.c
327++++ b/src/devices/wifi/nm-device-wifi.c
328+@@ -119,6 +119,8 @@ typedef struct {
329+ gint32 hw_addr_scan_expire;
330+
331+ guint wps_timeout_id;
332++
333++ NMSettingWirelessWakeOnWLan wowlan_restore;
334+ } NMDeviceWifiPrivate;
335+
336+ struct _NMDeviceWifi
337+@@ -535,6 +537,22 @@ again:
338+ nm_device_recheck_available_connections (NM_DEVICE (self));
339+ }
340+
341++static gboolean
342++wake_on_wlan_restore (NMDeviceWifi *self)
343++{
344++ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
345++ NMSettingWirelessWakeOnWLan w;
346++
347++ w = priv->wowlan_restore;
348++ if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE)
349++ return TRUE;
350++
351++ priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
352++ return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET,
353++ nm_device_get_ifindex (NM_DEVICE (self)),
354++ w);
355++}
356++
357+ static void
358+ deactivate (NMDevice *device)
359+ {
360+@@ -551,6 +569,9 @@ deactivate (NMDevice *device)
361+
362+ set_current_ap (self, NULL, TRUE);
363+
364++ if (!wake_on_wlan_restore (self))
365++ _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot unconfigure WoWLAN.");
366++
367+ /* Clear any critical protocol notification in the Wi-Fi stack */
368+ nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE);
369+
370+@@ -2593,6 +2614,60 @@ error:
371+
372+ /*****************************************************************************/
373+
374++static gboolean
375++wake_on_wlan_enable (NMDeviceWifi *self)
376++{
377++ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
378++ NMSettingWirelessWakeOnWLan wowl;
379++ NMSettingWireless *s_wireless;
380++ gs_free char *value = NULL;
381++
382++ s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_WIRELESS);
383++ if (s_wireless) {
384++ wowl = nm_setting_wireless_get_wake_on_wlan (s_wireless);
385++ if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT)
386++ goto found;
387++ }
388++
389++ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
390++ "wifi.wake-on-wlan",
391++ NM_DEVICE (self));
392++
393++ if (value) {
394++ wowl = _nm_utils_ascii_str_to_int64 (value, 10,
395++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE,
396++ G_MAXINT32,
397++ NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT);
398++
399++ if (NM_FLAGS_ANY (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) {
400++ if (!nm_utils_is_power_of_two (wowl)) {
401++ _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan: "
402++ "'default' and 'ignore' are exclusive flags", (guint) wowl);
403++ wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT;
404++ }
405++ } else if (NM_FLAGS_ANY (wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) {
406++ _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan", (guint) wowl);
407++ wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT;
408++ }
409++ if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT)
410++ goto found;
411++ }
412++ wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
413++
414++found:
415++ if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) {
416++ priv->wowlan_restore = wowl;
417++ return TRUE;
418++ }
419++
420++ priv->wowlan_restore = nm_platform_wifi_get_wake_on_wlan (NM_PLATFORM_GET,
421++ nm_device_get_ifindex (NM_DEVICE (self)));
422++
423++ return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET,
424++ nm_device_get_ifindex (NM_DEVICE (self)),
425++ wowl);
426++}
427++
428+ static NMActStageReturn
429+ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
430+ {
431+@@ -2802,6 +2877,9 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
432+ goto out;
433+ }
434+
435++ if (!wake_on_wlan_enable (self))
436++ _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN.");
437++
438+ /* have secrets, or no secrets required */
439+ if (nm_connection_get_setting_wireless_security (connection)) {
440+ _LOGI (LOGD_DEVICE | LOGD_WIFI,
441+@@ -2852,8 +2930,10 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
442+ ret = NM_ACT_STAGE_RETURN_POSTPONE;
443+
444+ out:
445+- if (ret == NM_ACT_STAGE_RETURN_FAILURE)
446++ if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
447+ cleanup_association_attempt (self, TRUE);
448++ wake_on_wlan_restore (self);
449++ }
450+
451+ if (config) {
452+ /* Supplicant interface object refs the config; we no longer care about
453+@@ -3257,7 +3337,8 @@ can_reapply_change (NMDevice *device,
454+ return nm_device_hash_check_invalid_keys (diffs,
455+ NM_SETTING_WIRELESS_SETTING_NAME,
456+ error,
457+- NM_SETTING_WIRELESS_MTU); /* reapplied with IP config */
458++ NM_SETTING_WIRELESS_MTU, /* reapplied with IP config */
459++ NM_SETTING_WIRELESS_WAKE_ON_WLAN);
460+ }
461+
462+ device_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class);
463+@@ -3269,6 +3350,21 @@ can_reapply_change (NMDevice *device,
464+ error);
465+ }
466+
467++static void
468++reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_new)
469++{
470++ NMDeviceWifi *self = NM_DEVICE_WIFI (device);
471++
472++ NM_DEVICE_CLASS (nm_device_wifi_parent_class)->reapply_connection (device,
473++ con_old,
474++ con_new);
475++
476++ _LOGD (LOGD_DEVICE, "reapplying wireless settings");
477++
478++ if (!wake_on_wlan_enable (self))
479++ _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN.");
480++}
481++
482+ /*****************************************************************************/
483+
484+ static void
485+@@ -3335,6 +3431,7 @@ nm_device_wifi_init (NMDeviceWifi *self)
486+
487+ priv->mode = NM_802_11_MODE_INFRA;
488+ priv->aps = g_hash_table_new (nm_str_hash, g_str_equal);
489++ priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
490+ }
491+
492+ static void
493+@@ -3433,6 +3530,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
494+ parent_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr;
495+ parent_class->unmanaged_on_quit = unmanaged_on_quit;
496+ parent_class->can_reapply_change = can_reapply_change;
497++ parent_class->reapply_connection = reapply_connection;
498+
499+ parent_class->state_changed = device_state_changed;
500+
501+diff --git a/src/nm-manager.c b/src/nm-manager.c
502+index e60b6c6..fc8a97e 100644
503+--- a/src/nm-manager.c
504++++ b/src/nm-manager.c
505+@@ -1315,6 +1315,12 @@ _parent_notify_changed (NMManager *self,
506+ }
507+ }
508+
509++static gboolean
510++device_is_wake_on_lan (NMPlatform *platform, NMDevice *device)
511++{
512++ return nm_platform_link_get_wake_on_lan (platform, nm_device_get_ip_ifindex (device));
513++}
514++
515+ static void
516+ remove_device (NMManager *self,
517+ NMDevice *device,
518+@@ -1324,14 +1330,19 @@ remove_device (NMManager *self,
519+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
520+ gboolean unmanage = FALSE;
521+
522+- _LOG2D (LOGD_DEVICE, device, "removing device (allow_unmanage %d, managed %d)",
523+- allow_unmanage, nm_device_get_managed (device, FALSE));
524++ _LOG2D (LOGD_DEVICE, device, "removing device (allow_unmanage %d, managed %d, wol %d)",
525++ allow_unmanage, nm_device_get_managed (device, FALSE),
526++ device_is_wake_on_lan (priv->platform, device));
527+
528+ if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
529+
530+- if (quitting)
531+- unmanage = nm_device_unmanage_on_quit (device);
532+- else {
533++ if (quitting) {
534++ /* Leave configured if wo(w)lan and quitting */
535++ if (device_is_wake_on_lan (priv->platform, device))
536++ unmanage = FALSE;
537++ else
538++ unmanage = nm_device_unmanage_on_quit (device);
539++ } else {
540+ /* the device is already gone. Unmanage it. */
541+ unmanage = TRUE;
542+ }
543+@@ -4763,12 +4774,6 @@ done:
544+ g_clear_object (&subject);
545+ }
546+
547+-static gboolean
548+-device_is_wake_on_lan (NMPlatform *platform, NMDevice *device)
549+-{
550+- return nm_platform_link_get_wake_on_lan (platform, nm_device_get_ip_ifindex (device));
551+-}
552+-
553+ static gboolean
554+ sleep_devices_add (NMManager *self, NMDevice *device, gboolean suspending)
555+ {
556+diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
557+index e5961c7..a061fc3 100644
558+--- a/src/platform/nm-linux-platform.c
559++++ b/src/platform/nm-linux-platform.c
560+@@ -6119,6 +6119,21 @@ wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean ru
561+ wifi_utils_indicate_addressing_running (wifi_data, running);
562+ }
563+
564++static NMSettingWirelessWakeOnWLan
565++wifi_get_wake_on_wlan (NMPlatform *platform, int ifindex)
566++{
567++ WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE);
568++ return wifi_utils_get_wake_on_wlan (wifi_data);
569++}
570++
571++static gboolean
572++wifi_set_wake_on_wlan (NMPlatform *platform, int ifindex,
573++ NMSettingWirelessWakeOnWLan wowl)
574++{
575++ WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE);
576++ return wifi_utils_set_wake_on_wlan (wifi_data, wowl);
577++}
578++
579+ /*****************************************************************************/
580+
581+ static gboolean
582+@@ -6203,7 +6218,7 @@ link_get_wake_on_lan (NMPlatform *platform, int ifindex)
583+ if (!wifi_data)
584+ return FALSE;
585+
586+- return wifi_utils_get_wowlan (wifi_data);
587++ return wifi_utils_get_wake_on_wlan (wifi_data) != NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE;
588+ } else
589+ return FALSE;
590+ }
591+@@ -7279,6 +7294,8 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
592+ platform_class->wifi_set_powersave = wifi_set_powersave;
593+ platform_class->wifi_find_frequency = wifi_find_frequency;
594+ platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running;
595++ platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan;
596++ platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan;
597+
598+ platform_class->mesh_get_channel = mesh_get_channel;
599+ platform_class->mesh_set_channel = mesh_set_channel;
600+diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
601+index c7ed90e..7387a1d 100644
602+--- a/src/platform/nm-platform.c
603++++ b/src/platform/nm-platform.c
604+@@ -2767,6 +2767,26 @@ nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gbo
605+ klass->wifi_indicate_addressing_running (self, ifindex, running);
606+ }
607+
608++NMSettingWirelessWakeOnWLan
609++nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex)
610++{
611++ _CHECK_SELF (self, klass, FALSE);
612++
613++ g_return_val_if_fail (ifindex > 0, FALSE);
614++
615++ return klass->wifi_get_wake_on_wlan (self, ifindex);
616++}
617++
618++gboolean
619++nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl)
620++{
621++ _CHECK_SELF (self, klass, FALSE);
622++
623++ g_return_val_if_fail (ifindex > 0, FALSE);
624++
625++ return klass->wifi_set_wake_on_wlan (self, ifindex, wowl);
626++}
627++
628+ guint32
629+ nm_platform_mesh_get_channel (NMPlatform *self, int ifindex)
630+ {
631+diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
632+index f6bf02b..0c167ee 100644
633+--- a/src/platform/nm-platform.h
634++++ b/src/platform/nm-platform.h
635+@@ -32,6 +32,7 @@
636+ #include "nm-core-utils.h"
637+ #include "nm-setting-vlan.h"
638+ #include "nm-setting-wired.h"
639++#include "nm-setting-wireless.h"
640+
641+ #define NM_TYPE_PLATFORM (nm_platform_get_type ())
642+ #define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform))
643+@@ -826,6 +827,8 @@ typedef struct {
644+ void (*wifi_set_powersave) (NMPlatform *, int ifindex, guint32 powersave);
645+ guint32 (*wifi_find_frequency) (NMPlatform *, int ifindex, const guint32 *freqs);
646+ void (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running);
647++ NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex);
648++ gboolean (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl);
649+
650+ guint32 (*mesh_get_channel) (NMPlatform *, int ifindex);
651+ gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel);
652+@@ -1191,6 +1194,8 @@ void nm_platform_wifi_set_mode (NMPlatform *self, int ifindex, NM
653+ void nm_platform_wifi_set_powersave (NMPlatform *self, int ifindex, guint32 powersave);
654+ guint32 nm_platform_wifi_find_frequency (NMPlatform *self, int ifindex, const guint32 *freqs);
655+ void nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running);
656++NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex);
657++gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl);
658+
659+ guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex);
660+ gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel);
661+diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c
662+index a5f25b0..3a09244 100644
663+--- a/src/platform/wifi/wifi-utils-nl80211.c
664++++ b/src/platform/wifi/wifi-utils-nl80211.c
665+@@ -495,6 +495,103 @@ nla_put_failure:
666+ return FALSE;
667+ }
668+
669++static int
670++nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg)
671++{
672++ NMSettingWirelessWakeOnWLan *wowl = arg;
673++ struct nlattr *attrs[NL80211_ATTR_MAX + 1];
674++ struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG];
675++ struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg));
676++
677++ nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
678++ genlmsg_attrlen(gnlh, 0), NULL);
679++
680++ if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
681++ return NL_SKIP;
682++
683++ nla_parse (trig, MAX_NL80211_WOWLAN_TRIG,
684++ nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
685++ nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
686++ NULL);
687++
688++ *wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE;
689++ if (trig[NL80211_WOWLAN_TRIG_ANY])
690++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY;
691++ if (trig[NL80211_WOWLAN_TRIG_DISCONNECT])
692++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT;
693++ if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT])
694++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC;
695++ if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
696++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE;
697++ if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
698++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST;
699++ if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
700++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE;
701++ if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
702++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE;
703++ if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION])
704++ *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP;
705++
706++ return NL_SKIP;
707++}
708++
709++static NMSettingWirelessWakeOnWLan
710++wifi_nl80211_get_wake_on_wlan (WifiData *data)
711++{
712++ WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
713++ NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
714++ struct nl_msg *msg = NULL;
715++
716++ msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0);
717++
718++ nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl);
719++
720++ return wowl;
721++}
722++
723++static gboolean
724++wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
725++{
726++ WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
727++ struct nl_msg *msg = NULL;
728++ struct nlattr *triggers;
729++ int err;
730++
731++ if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE)
732++ return TRUE;
733++
734++ msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0);
735++ if (!msg)
736++ return FALSE;
737++
738++ triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS);
739++
740++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY))
741++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY);
742++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT))
743++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_DISCONNECT);
744++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC))
745++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
746++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE))
747++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
748++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST))
749++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
750++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE))
751++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
752++ if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE))
753++ NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
754++
755++ nla_nest_end(msg, triggers);
756++
757++ err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
758++
759++ return err >= 0;
760++
761++nla_put_failure:
762++ nlmsg_free (msg);
763++ return FALSE;
764++}
765++
766+ /* @divisor: pass what value @xbm should be divided by to get dBm */
767+ static guint32
768+ nl80211_xbm_to_percent (gint32 xbm, guint32 divisor)
769+@@ -820,42 +917,6 @@ nla_put_failure:
770+ }
771+ #endif
772+
773+-struct nl80211_wowlan_info {
774+- gboolean enabled;
775+-};
776+-
777+-static int
778+-nl80211_wowlan_handler (struct nl_msg *msg, void *arg)
779+-{
780+- struct nlattr *tb[NL80211_ATTR_MAX + 1];
781+- struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg));
782+- struct nl80211_wowlan_info *info = arg;
783+-
784+- info->enabled = FALSE;
785+-
786+- if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0),
787+- genlmsg_attrlen (gnlh, 0), NULL) < 0)
788+- return NL_SKIP;
789+-
790+- if (tb[NL80211_ATTR_WOWLAN_TRIGGERS])
791+- info->enabled = TRUE;
792+-
793+- return NL_SKIP;
794+-}
795+-
796+-static gboolean
797+-wifi_nl80211_get_wowlan (WifiData *data)
798+-{
799+- WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
800+- struct nl_msg *msg;
801+- struct nl80211_wowlan_info info;
802+-
803+- msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0);
804+- nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info);
805+-
806+- return info.enabled;
807+-}
808+-
809+ struct nl80211_device_info {
810+ int phy;
811+ guint32 *freqs;
812+@@ -1154,8 +1215,10 @@ wifi_nl80211_init (int ifindex)
813+ nl80211->num_freqs = device_info.num_freqs;
814+ nl80211->parent.caps = device_info.caps;
815+
816+- if (device_info.can_wowlan)
817+- nl80211->parent.get_wowlan = wifi_nl80211_get_wowlan;
818++ if (device_info.can_wowlan) {
819++ nl80211->parent.get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan;
820++ nl80211->parent.set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan;
821++ }
822+
823+ _LOGI (LOGD_PLATFORM | LOGD_WIFI,
824+ "(%s): using nl80211 for WiFi device control",
825+diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h
826+index 11a0f06..18f6131 100644
827+--- a/src/platform/wifi/wifi-utils-private.h
828++++ b/src/platform/wifi/wifi-utils-private.h
829+@@ -35,6 +35,12 @@ struct WifiData {
830+ /* Set power saving mode on an interface */
831+ gboolean (*set_powersave) (WifiData *data, guint32 powersave);
832+
833++ /* Get WakeOnWLAN configuration on an interface */
834++ NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (WifiData *data);
835++
836++ /* Set WakeOnWLAN mode on an interface */
837++ gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl);
838++
839+ /* Return current frequency in MHz (really associated BSS frequency) */
840+ guint32 (*get_freq) (WifiData *data);
841+
842+@@ -53,8 +59,6 @@ struct WifiData {
843+
844+ void (*deinit) (WifiData *data);
845+
846+- gboolean (*get_wowlan) (WifiData *data);
847+-
848+ /* OLPC Mesh-only functions */
849+
850+ guint32 (*get_mesh_channel) (WifiData *data);
851+diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c
852+index d005212..f76bf95 100644
853+--- a/src/platform/wifi/wifi-utils.c
854++++ b/src/platform/wifi/wifi-utils.c
855+@@ -115,6 +115,25 @@ wifi_utils_set_powersave (WifiData *data, guint32 powersave)
856+ return data->set_powersave ? data->set_powersave (data, powersave) : TRUE;
857+ }
858+
859++NMSettingWirelessWakeOnWLan
860++wifi_utils_get_wake_on_wlan (WifiData *data)
861++{
862++ g_return_val_if_fail (data != NULL, FALSE);
863++
864++ return data->get_wake_on_wlan
865++ ? data->get_wake_on_wlan (data)
866++ : NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE;
867++}
868++
869++gboolean
870++wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl)
871++{
872++ g_return_val_if_fail (data != NULL, FALSE);
873++
874++ return data->set_wake_on_wlan ?
875++ data->set_wake_on_wlan (data, wowl) : FALSE;
876++}
877++
878+ guint32
879+ wifi_utils_get_freq (WifiData *data)
880+ {
881+@@ -154,15 +173,6 @@ wifi_utils_get_qual (WifiData *data)
882+ return data->get_qual (data);
883+ }
884+
885+-gboolean
886+-wifi_utils_get_wowlan (WifiData *data)
887+-{
888+- g_return_val_if_fail (data != NULL, 0);
889+- if (!data->get_wowlan)
890+- return FALSE;
891+- return data->get_wowlan (data);
892+-}
893+-
894+ void
895+ wifi_utils_deinit (WifiData *data)
896+ {
897+diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h
898+index 705717b..776b3c9 100644
899+--- a/src/platform/wifi/wifi-utils.h
900++++ b/src/platform/wifi/wifi-utils.h
901+@@ -25,6 +25,7 @@
902+ #include <net/ethernet.h>
903+
904+ #include "nm-dbus-interface.h"
905++#include "nm-setting-wireless.h"
906+
907+ typedef struct WifiData WifiData;
908+
909+@@ -61,11 +62,11 @@ int wifi_utils_get_qual (WifiData *data);
910+ /* Tells the driver DHCP or SLAAC is running */
911+ gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running);
912+
913+-/* Returns true if WoWLAN is enabled on device */
914+-gboolean wifi_utils_get_wowlan (WifiData *data);
915+-
916+ gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave);
917+
918++NMSettingWirelessWakeOnWLan wifi_utils_get_wake_on_wlan (WifiData *data);
919++
920++gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl);
921+
922+ /* OLPC Mesh-only functions */
923+ guint32 wifi_utils_get_mesh_channel (WifiData *data);
924diff --git a/debian/patches/series b/debian/patches/series
925index faca637..80ae3f3 100644
926--- a/debian/patches/series
927+++ b/debian/patches/series
928@@ -11,3 +11,4 @@ libnm-Check-self-still-NMManager-or-not.patch
929 #dns-manager-don-t-merge-split-DNS-search-domains.patch
930 Read-system-connections-from-run.patch
931 e91f1a7d2a6b8400b6b331d5b72287dcb5164a39.patch
932+Support-for-WoWLAN.patch

Subscribers

People subscribed via source and target branches