diff options
Diffstat (limited to 'wext-fix-message-delay-ordering.patch')
-rw-r--r-- | wext-fix-message-delay-ordering.patch | 122 |
1 files changed, 0 insertions, 122 deletions
diff --git a/wext-fix-message-delay-ordering.patch b/wext-fix-message-delay-ordering.patch deleted file mode 100644 index 109b68da3..000000000 --- a/wext-fix-message-delay-ordering.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 8bf862739a7786ae72409220914df960a0aa80d8 Mon Sep 17 00:00:00 2001 -From: Johannes Berg <johannes.berg@intel.com> -Date: Wed, 27 Jan 2016 12:37:52 +0100 -Subject: wext: fix message delay/ordering - -Beniamino reported that he was getting an RTM_NEWLINK message for a -given interface, after the RTM_DELLINK for it. It turns out that the -message is a wireless extensions message, which was sent because the -interface had been connected and disconnection while it was deleted -caused a wext message. - -For its netlink messages, wext uses RTM_NEWLINK, but the message is -without all the regular rtnetlink attributes, so "ip monitor link" -prints just rudimentary information: - -5: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default - link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff -Deleted 5: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default - link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff -5: wlan1: <BROADCAST,MULTICAST,UP> - link/ether -(from my hwsim reproduction) - -This can cause userspace to get confused since it doesn't expect an -RTM_NEWLINK message after RTM_DELLINK. - -The reason for this is that wext schedules a worker to send out the -messages, and the scheduling delay can cause the messages to get out -to userspace in different order. - -To fix this, have wext register a netdevice notifier and flush out -any pending messages when netdevice state changes. This fixes any -ordering whenever the original message wasn't sent by a notifier -itself. - -Cc: stable@vger.kernel.org -Reported-by: Beniamino Galvani <bgalvani@redhat.com> -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - net/wireless/wext-core.c | 51 +++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 40 insertions(+), 11 deletions(-) - -diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c -index c8717c1..87dd619 100644 ---- a/net/wireless/wext-core.c -+++ b/net/wireless/wext-core.c -@@ -342,6 +342,39 @@ static const int compat_event_type_size[] = { - - /* IW event code */ - -+static void wireless_nlevent_flush(void) -+{ -+ struct sk_buff *skb; -+ struct net *net; -+ -+ ASSERT_RTNL(); -+ -+ for_each_net(net) { -+ while ((skb = skb_dequeue(&net->wext_nlevents))) -+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, -+ GFP_KERNEL); -+ } -+} -+ -+static int wext_netdev_notifier_call(struct notifier_block *nb, -+ unsigned long state, void *ptr) -+{ -+ /* -+ * When a netdev changes state in any way, flush all pending messages -+ * to avoid them going out in a strange order, e.g. RTM_NEWLINK after -+ * RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close() -+ * or similar - all of which could otherwise happen due to delays from -+ * schedule_work(). -+ */ -+ wireless_nlevent_flush(); -+ -+ return NOTIFY_OK; -+} -+ -+static struct notifier_block wext_netdev_notifier = { -+ .notifier_call = wext_netdev_notifier_call, -+}; -+ - static int __net_init wext_pernet_init(struct net *net) - { - skb_queue_head_init(&net->wext_nlevents); -@@ -360,7 +393,12 @@ static struct pernet_operations wext_pernet_ops = { - - static int __init wireless_nlevent_init(void) - { -- return register_pernet_subsys(&wext_pernet_ops); -+ int err = register_pernet_subsys(&wext_pernet_ops); -+ -+ if (err) -+ return err; -+ -+ return register_netdevice_notifier(&wext_netdev_notifier); - } - - subsys_initcall(wireless_nlevent_init); -@@ -368,17 +406,8 @@ subsys_initcall(wireless_nlevent_init); - /* Process events generated by the wireless layer or the driver. */ - static void wireless_nlevent_process(struct work_struct *work) - { -- struct sk_buff *skb; -- struct net *net; -- - rtnl_lock(); -- -- for_each_net(net) { -- while ((skb = skb_dequeue(&net->wext_nlevents))) -- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, -- GFP_KERNEL); -- } -- -+ wireless_nlevent_flush(); - rtnl_unlock(); - } - --- -cgit v0.12 - |