aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-21 08:51:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:31 -0400
commit3d54d25515838543e56889aa7e48f40d00719368 (patch)
treeac8e7ab50b5fa9e9be64885f86c99a0b6c71892c /net/wireless/nl80211.c
parentf7969969f416e593bcc7dc24abf3f9fd6c27136d (diff)
cfg80211: clean up properly on interface type change
When the interface type changes while connected, and the driver does not require the interface to be down for a type change, it is currently possible to get very strange results unless the driver takes special care, which it shouldn't have to. To fix this, take care to disconnect/leave IBSS when changing the interface type -- even if the driver may fail the call. Also process all events that may be pending to avoid running into a situation where an event is reported but only processed after the type has already changed, which would lead to missing events and warnings. A side effect of this is that you will have disconnected or left the IBSS even if the mode change ultimately fails, but since the intention was to change it and thus leave or disconnect, this is not a problem. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c16
1 files changed, 1 insertions, 15 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a8aaadeb6773..71bfc044a939 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -977,12 +977,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
977 } 977 }
978 } 978 }
979 979
980 if (!rdev->ops->change_virtual_intf ||
981 !(rdev->wiphy.interface_modes & (1 << ntype))) {
982 err = -EOPNOTSUPP;
983 goto unlock;
984 }
985
986 if (info->attrs[NL80211_ATTR_MESH_ID]) { 980 if (info->attrs[NL80211_ATTR_MESH_ID]) {
987 if (ntype != NL80211_IFTYPE_MESH_POINT) { 981 if (ntype != NL80211_IFTYPE_MESH_POINT) {
988 err = -EINVAL; 982 err = -EINVAL;
@@ -1008,18 +1002,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1008 } 1002 }
1009 1003
1010 if (change) 1004 if (change)
1011 err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, 1005 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
1012 ntype, flags, &params);
1013 else 1006 else
1014 err = 0; 1007 err = 0;
1015 1008
1016 WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
1017
1018 if (!err && (ntype != otype)) {
1019 if (otype == NL80211_IFTYPE_ADHOC)
1020 cfg80211_clear_ibss(dev, false);
1021 }
1022
1023 unlock: 1009 unlock:
1024 dev_put(dev); 1010 dev_put(dev);
1025 cfg80211_unlock_rdev(rdev); 1011 cfg80211_unlock_rdev(rdev);