提交 6d92f83f 编写于 作者: D Daniel Drake 提交者: John W. Linville

[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: NDaniel Drake <dsd@gentoo.org>
Acked-by: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 0c6157a3
...@@ -82,28 +82,37 @@ ieee80211softmac_assoc_timeout(void *d) ...@@ -82,28 +82,37 @@ ieee80211softmac_assoc_timeout(void *d)
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
} }
/* Sends out a disassociation request to the desired AP */
void void
ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason) ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&mac->lock, flags);
if (mac->associnfo.associating)
cancel_delayed_work(&mac->associnfo.timeout);
netif_carrier_off(mac->dev);
mac->associated = 0;
mac->associnfo.bssvalid = 0;
mac->associnfo.associating = 0;
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
spin_unlock_irqrestore(&mac->lock, flags);
}
/* Sends out a disassociation request to the desired AP */
void
ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
{
struct ieee80211softmac_network *found; struct ieee80211softmac_network *found;
if (mac->associnfo.bssvalid && mac->associated) { if (mac->associnfo.bssvalid && mac->associated) {
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
if (found) if (found)
ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
} else if (mac->associnfo.associating) {
cancel_delayed_work(&mac->associnfo.timeout);
} }
/* Change our state */ ieee80211softmac_disassoc(mac);
spin_lock_irqsave(&mac->lock, flags);
/* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
mac->associated = 0;
mac->associnfo.associating = 0;
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
spin_unlock_irqrestore(&mac->lock, flags);
} }
static inline int static inline int
...@@ -176,14 +185,18 @@ ieee80211softmac_assoc_work(void *d) ...@@ -176,14 +185,18 @@ ieee80211softmac_assoc_work(void *d)
struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
struct ieee80211softmac_network *found = NULL; struct ieee80211softmac_network *found = NULL;
struct ieee80211_network *net = NULL, *best = NULL; struct ieee80211_network *net = NULL, *best = NULL;
int bssvalid;
unsigned long flags; unsigned long flags;
/* ieee80211_disassoc might clear this */
bssvalid = mac->associnfo.bssvalid;
/* meh */ /* meh */
if (mac->associated) if (mac->associated)
ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
/* try to find the requested network in our list, if we found one already */ /* try to find the requested network in our list, if we found one already */
if (mac->associnfo.bssvalid || mac->associnfo.bssfixed) if (bssvalid || mac->associnfo.bssfixed)
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
/* Search the ieee80211 networks for this network if we didn't find it by bssid, /* 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,7 +393,6 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
struct ieee80211_disassoc *disassoc) struct ieee80211_disassoc *disassoc)
{ {
struct ieee80211softmac_device *mac = ieee80211_priv(dev); struct ieee80211softmac_device *mac = ieee80211_priv(dev);
unsigned long flags;
if (unlikely(!mac->running)) if (unlikely(!mac->running))
return -ENODEV; return -ENODEV;
...@@ -392,14 +404,11 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, ...@@ -392,14 +404,11 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
return 0; return 0;
dprintk(KERN_INFO PFX "got disassoc frame\n"); dprintk(KERN_INFO PFX "got disassoc frame\n");
netif_carrier_off(dev); ieee80211softmac_disassoc(mac);
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.bssvalid = 0; /* try to reassociate */
mac->associated = 0;
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
schedule_work(&mac->associnfo.work); schedule_work(&mac->associnfo.work);
spin_unlock_irqrestore(&mac->lock, flags);
return 0; return 0;
} }
......
...@@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac, ...@@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
struct list_head *list_ptr; struct list_head *list_ptr;
unsigned long flags; unsigned long flags;
/* deauthentication implies disassociation */
ieee80211softmac_disassoc(mac);
/* Lock and reset status flags */ /* Lock and reset status flags */
spin_lock_irqsave(&mac->lock, flags); spin_lock_irqsave(&mac->lock, flags);
net->authenticating = 0; net->authenticating = 0;
......
...@@ -150,7 +150,8 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev, ...@@ -150,7 +150,8 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev,
int ieee80211softmac_handle_reassoc_req(struct net_device * dev, int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
struct ieee80211_reassoc_request * reassoc); struct ieee80211_reassoc_request * reassoc);
void ieee80211softmac_assoc_timeout(void *d); void ieee80211softmac_assoc_timeout(void *d);
void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason); void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
/* some helper functions */ /* some helper functions */
static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm) static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm)
......
...@@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, ...@@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
} }
return ieee80211softmac_deauth_req(mac, net, reason); return ieee80211softmac_deauth_req(mac, net, reason);
case IW_MLME_DISASSOC: case IW_MLME_DISASSOC:
ieee80211softmac_disassoc(mac, reason); ieee80211softmac_send_disassoc_req(mac, reason);
return 0; return 0;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册