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