diff options
author | Daniel Drake <dsd@gentoo.org> | 2006-05-01 17:23:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-05-05 17:10:39 -0400 |
commit | 6d92f83ffafe8e2ce105c3ec5696c62d6fcebcee (patch) | |
tree | 7d82f1380f10ac3b4f042f4953c65e5e284e5acf | |
parent | 0c6157a371f72b91bd9d2f72c2e65e2bde4cdf39 (diff) |
[PATCH] softmac: deauthentication implies deassociation
The 802.11 specs state that deauthenticating also implies
disassociating. This patch implements that, which improve the behaviour
of SIOCSIWMLME.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 53 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_auth.c | 3 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_priv.h | 3 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 2 |
4 files changed, 37 insertions, 24 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index d4c79ce16871..01f21334767c 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -82,28 +82,37 @@ ieee80211softmac_assoc_timeout(void *d) | |||
82 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL); | 82 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL); |
83 | } | 83 | } |
84 | 84 | ||
85 | /* Sends out a disassociation request to the desired AP */ | ||
86 | void | 85 | void |
87 | ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason) | 86 | ieee80211softmac_disassoc(struct ieee80211softmac_device *mac) |
88 | { | 87 | { |
89 | unsigned long flags; | 88 | unsigned long flags; |
89 | |||
90 | spin_lock_irqsave(&mac->lock, flags); | ||
91 | if (mac->associnfo.associating) | ||
92 | cancel_delayed_work(&mac->associnfo.timeout); | ||
93 | |||
94 | netif_carrier_off(mac->dev); | ||
95 | |||
96 | mac->associated = 0; | ||
97 | mac->associnfo.bssvalid = 0; | ||
98 | mac->associnfo.associating = 0; | ||
99 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); | ||
100 | spin_unlock_irqrestore(&mac->lock, flags); | ||
101 | } | ||
102 | |||
103 | /* Sends out a disassociation request to the desired AP */ | ||
104 | void | ||
105 | ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason) | ||
106 | { | ||
90 | struct ieee80211softmac_network *found; | 107 | struct ieee80211softmac_network *found; |
91 | 108 | ||
92 | if (mac->associnfo.bssvalid && mac->associated) { | 109 | if (mac->associnfo.bssvalid && mac->associated) { |
93 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 110 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
94 | if (found) | 111 | if (found) |
95 | ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); | 112 | ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); |
96 | } else if (mac->associnfo.associating) { | ||
97 | cancel_delayed_work(&mac->associnfo.timeout); | ||
98 | } | 113 | } |
99 | 114 | ||
100 | /* Change our state */ | 115 | ieee80211softmac_disassoc(mac); |
101 | spin_lock_irqsave(&mac->lock, flags); | ||
102 | /* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */ | ||
103 | mac->associated = 0; | ||
104 | mac->associnfo.associating = 0; | ||
105 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); | ||
106 | spin_unlock_irqrestore(&mac->lock, flags); | ||
107 | } | 116 | } |
108 | 117 | ||
109 | static inline int | 118 | static inline int |
@@ -176,14 +185,18 @@ ieee80211softmac_assoc_work(void *d) | |||
176 | struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; | 185 | struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; |
177 | struct ieee80211softmac_network *found = NULL; | 186 | struct ieee80211softmac_network *found = NULL; |
178 | struct ieee80211_network *net = NULL, *best = NULL; | 187 | struct ieee80211_network *net = NULL, *best = NULL; |
188 | int bssvalid; | ||
179 | unsigned long flags; | 189 | unsigned long flags; |
180 | 190 | ||
191 | /* ieee80211_disassoc might clear this */ | ||
192 | bssvalid = mac->associnfo.bssvalid; | ||
193 | |||
181 | /* meh */ | 194 | /* meh */ |
182 | if (mac->associated) | 195 | if (mac->associated) |
183 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); | 196 | ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
184 | 197 | ||
185 | /* try to find the requested network in our list, if we found one already */ | 198 | /* try to find the requested network in our list, if we found one already */ |
186 | if (mac->associnfo.bssvalid || mac->associnfo.bssfixed) | 199 | if (bssvalid || mac->associnfo.bssfixed) |
187 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 200 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
188 | 201 | ||
189 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, | 202 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, |
@@ -380,7 +393,6 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, | |||
380 | struct ieee80211_disassoc *disassoc) | 393 | struct ieee80211_disassoc *disassoc) |
381 | { | 394 | { |
382 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | 395 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); |
383 | unsigned long flags; | ||
384 | 396 | ||
385 | if (unlikely(!mac->running)) | 397 | if (unlikely(!mac->running)) |
386 | return -ENODEV; | 398 | return -ENODEV; |
@@ -392,14 +404,11 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, | |||
392 | return 0; | 404 | return 0; |
393 | 405 | ||
394 | dprintk(KERN_INFO PFX "got disassoc frame\n"); | 406 | dprintk(KERN_INFO PFX "got disassoc frame\n"); |
395 | netif_carrier_off(dev); | 407 | ieee80211softmac_disassoc(mac); |
396 | spin_lock_irqsave(&mac->lock, flags); | 408 | |
397 | mac->associnfo.bssvalid = 0; | 409 | /* try to reassociate */ |
398 | mac->associated = 0; | ||
399 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); | ||
400 | schedule_work(&mac->associnfo.work); | 410 | schedule_work(&mac->associnfo.work); |
401 | spin_unlock_irqrestore(&mac->lock, flags); | 411 | |
402 | |||
403 | return 0; | 412 | return 0; |
404 | } | 413 | } |
405 | 414 | ||
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c index 06e332624665..084b6211f293 100644 --- a/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/net/ieee80211/softmac/ieee80211softmac_auth.c | |||
@@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac, | |||
279 | struct list_head *list_ptr; | 279 | struct list_head *list_ptr; |
280 | unsigned long flags; | 280 | unsigned long flags; |
281 | 281 | ||
282 | /* deauthentication implies disassociation */ | ||
283 | ieee80211softmac_disassoc(mac); | ||
284 | |||
282 | /* Lock and reset status flags */ | 285 | /* Lock and reset status flags */ |
283 | spin_lock_irqsave(&mac->lock, flags); | 286 | spin_lock_irqsave(&mac->lock, flags); |
284 | net->authenticating = 0; | 287 | net->authenticating = 0; |
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h index 8c95b3abe0cc..5de0abf157e3 100644 --- a/net/ieee80211/softmac/ieee80211softmac_priv.h +++ b/net/ieee80211/softmac/ieee80211softmac_priv.h | |||
@@ -150,7 +150,8 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev, | |||
150 | int ieee80211softmac_handle_reassoc_req(struct net_device * dev, | 150 | int ieee80211softmac_handle_reassoc_req(struct net_device * dev, |
151 | struct ieee80211_reassoc_request * reassoc); | 151 | struct ieee80211_reassoc_request * reassoc); |
152 | void ieee80211softmac_assoc_timeout(void *d); | 152 | void ieee80211softmac_assoc_timeout(void *d); |
153 | void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason); | 153 | void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason); |
154 | void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac); | ||
154 | 155 | ||
155 | /* some helper functions */ | 156 | /* some helper functions */ |
156 | static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm) | 157 | static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm) |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 8d0c22641ca8..b7d83cd4d56c 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, | |||
456 | } | 456 | } |
457 | return ieee80211softmac_deauth_req(mac, net, reason); | 457 | return ieee80211softmac_deauth_req(mac, net, reason); |
458 | case IW_MLME_DISASSOC: | 458 | case IW_MLME_DISASSOC: |
459 | ieee80211softmac_disassoc(mac, reason); | 459 | ieee80211softmac_send_disassoc_req(mac, reason); |
460 | return 0; | 460 | return 0; |
461 | default: | 461 | default: |
462 | return -EOPNOTSUPP; | 462 | return -EOPNOTSUPP; |