df43314
From cb150b9d23be6ee7f3a0fff29784f1c5b5ac514d Mon Sep 17 00:00:00 2001
785c5f0
From: Johannes Berg <johannes.berg@intel.com>
df43314
Date: Wed, 27 Jan 2016 13:29:34 +0100
df43314
Subject: cfg80211/wext: fix message ordering
785c5f0
785c5f0
Since cfg80211 frequently takes actions from its netdev notifier
785c5f0
call, wireless extensions messages could still be ordered badly
785c5f0
since the wext netdev notifier, since wext is built into the
785c5f0
kernel, runs before the cfg80211 netdev notifier. For example,
785c5f0
the following can happen:
785c5f0
785c5f0
5: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default
785c5f0
    link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff
785c5f0
5: wlan1: <BROADCAST,MULTICAST,UP>
785c5f0
    link/ether
785c5f0
785c5f0
when setting the interface down causes the wext message.
785c5f0
785c5f0
To also fix this, export the wireless_nlevent_flush() function
785c5f0
and also call it from the cfg80211 notifier.
785c5f0
785c5f0
Cc: stable@vger.kernel.org
785c5f0
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
785c5f0
---
785c5f0
 include/net/iw_handler.h | 6 ++++++
785c5f0
 net/wireless/core.c      | 2 ++
785c5f0
 net/wireless/wext-core.c | 3 ++-
785c5f0
 3 files changed, 10 insertions(+), 1 deletion(-)
785c5f0
785c5f0
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
df43314
index 8f81bbb..e0f4109 100644
785c5f0
--- a/include/net/iw_handler.h
785c5f0
+++ b/include/net/iw_handler.h
785c5f0
@@ -439,6 +439,12 @@ int dev_get_wireless_info(char *buffer, char **start, off_t offset, int length);
785c5f0
 /* Send a single event to user space */
785c5f0
 void wireless_send_event(struct net_device *dev, unsigned int cmd,
785c5f0
 			 union iwreq_data *wrqu, const char *extra);
785c5f0
+#ifdef CONFIG_WEXT_CORE
785c5f0
+/* flush all previous wext events - if work is done from netdev notifiers */
785c5f0
+void wireless_nlevent_flush(void);
785c5f0
+#else
df43314
+static inline void wireless_nlevent_flush(void) {}
785c5f0
+#endif
785c5f0
 
785c5f0
 /* We may need a function to send a stream of events to user space.
785c5f0
  * More on that later... */
785c5f0
diff --git a/net/wireless/core.c b/net/wireless/core.c
df43314
index b091551..8f0bac7 100644
785c5f0
--- a/net/wireless/core.c
785c5f0
+++ b/net/wireless/core.c
df43314
@@ -1147,6 +1147,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
785c5f0
 		return NOTIFY_DONE;
785c5f0
 	}
785c5f0
 
785c5f0
+	wireless_nlevent_flush();
785c5f0
+
785c5f0
 	return NOTIFY_OK;
785c5f0
 }
785c5f0
 
785c5f0
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
df43314
index 87dd619..b50ee5d 100644
785c5f0
--- a/net/wireless/wext-core.c
785c5f0
+++ b/net/wireless/wext-core.c
785c5f0
@@ -342,7 +342,7 @@ static const int compat_event_type_size[] = {
785c5f0
 
785c5f0
 /* IW event code */
785c5f0
 
785c5f0
-static void wireless_nlevent_flush(void)
785c5f0
+void wireless_nlevent_flush(void)
785c5f0
 {
785c5f0
 	struct sk_buff *skb;
785c5f0
 	struct net *net;
785c5f0
@@ -355,6 +355,7 @@ static void wireless_nlevent_flush(void)
785c5f0
 				    GFP_KERNEL);
785c5f0
 	}
785c5f0
 }
785c5f0
+EXPORT_SYMBOL_GPL(wireless_nlevent_flush);
785c5f0
 
785c5f0
 static int wext_netdev_notifier_call(struct notifier_block *nb,
785c5f0
 				     unsigned long state, void *ptr)
785c5f0
-- 
df43314
cgit v0.12
785c5f0