Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d92f83f authored by Daniel Drake's avatar Daniel Drake Committed by John W. Linville
Browse files

[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: default avatarDaniel Drake <dsd@gentoo.org>
Acked-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0c6157a3
Loading
Loading
Loading
Loading
+31 −22
Original line number Original line Diff line number Diff line
@@ -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)
	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,
				 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,13 +404,10 @@ 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;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -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;
+2 −1
Original line number Original line Diff line number Diff line
@@ -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)
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;