Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194208
b: refs/heads/master
c: d5cdfac
h: refs/heads/master
v: v3
  • Loading branch information
Jouni Malinen authored and John W. Linville committed Apr 7, 2010
1 parent e05edfa commit c1ce7b5
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7590a550b88b8c3cb025f0a8ed58e279ad62e4c1
refs/heads/master: d5cdfacb35ed886271d1ccfffbded98d3447da17
8 changes: 8 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,12 @@ enum nl80211_commands {
* @NL80211_ATTR_CQM: connection quality monitor configuration in a
* nested attribute with %NL80211_ATTR_CQM_* sub-attributes.
*
* @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command
* is requesting a local authentication/association state change without
* invoking actual management frame exchange. This can be used with
* NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE,
* NL80211_CMD_DISASSOCIATE.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -856,6 +862,8 @@ enum nl80211_attrs {

NL80211_ATTR_CQM,

NL80211_ATTR_LOCAL_STATE_CHANGE,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down
11 changes: 11 additions & 0 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,10 @@ struct cfg80211_crypto_settings {
* @key_len: length of WEP key for shared key authentication
* @key_idx: index of WEP key for shared key authentication
* @key: WEP key for shared key authentication
* @local_state_change: This is a request for a local state only, i.e., no
* Authentication frame is to be transmitted and authentication state is
* to be changed without having to wait for a response from the peer STA
* (AP).
*/
struct cfg80211_auth_request {
struct cfg80211_bss *bss;
Expand All @@ -712,6 +716,7 @@ struct cfg80211_auth_request {
enum nl80211_auth_type auth_type;
const u8 *key;
u8 key_len, key_idx;
bool local_state_change;
};

/**
Expand Down Expand Up @@ -744,12 +749,15 @@ struct cfg80211_assoc_request {
* @ie: Extra IEs to add to Deauthentication frame or %NULL
* @ie_len: Length of ie buffer in octets
* @reason_code: The reason code for the deauthentication
* @local_state_change: This is a request for a local state only, i.e., no
* Deauthentication frame is to be transmitted.
*/
struct cfg80211_deauth_request {
struct cfg80211_bss *bss;
const u8 *ie;
size_t ie_len;
u16 reason_code;
bool local_state_change;
};

/**
Expand All @@ -762,12 +770,15 @@ struct cfg80211_deauth_request {
* @ie: Extra IEs to add to Disassociation frame or %NULL
* @ie_len: Length of ie buffer in octets
* @reason_code: The reason code for the disassociation
* @local_state_change: This is a request for a local state only, i.e., no
* Disassociation frame is to be transmitted.
*/
struct cfg80211_disassoc_request {
struct cfg80211_bss *bss;
const u8 *ie;
size_t ie_len;
u16 reason_code;
bool local_state_change;
};

/**
Expand Down
23 changes: 15 additions & 8 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,

static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
const u8 *bssid, u16 stype, u16 reason,
void *cookie)
void *cookie, bool send_frame)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
Expand Down Expand Up @@ -247,7 +247,11 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
ieee80211_tx_skb(sdata, skb);

if (send_frame)
ieee80211_tx_skb(sdata, skb);
else
kfree_skb(skb);
}

void ieee80211_send_pspoll(struct ieee80211_local *local,
Expand Down Expand Up @@ -980,7 +984,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
ieee80211_send_deauth_disassoc(sdata, bssid,
IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
NULL);
NULL, true);
}

void ieee80211_beacon_connection_loss_work(struct work_struct *work)
Expand Down Expand Up @@ -1724,7 +1728,7 @@ static void ieee80211_sta_work(struct work_struct *work)
ieee80211_send_deauth_disassoc(sdata, bssid,
IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
NULL);
NULL, true);
mutex_lock(&ifmgd->mtx);
}
}
Expand Down Expand Up @@ -1908,6 +1912,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_work *wk;
u16 auth_alg;

if (req->local_state_change)
return 0; /* no need to update mac80211 state */

switch (req->auth_type) {
case NL80211_AUTHTYPE_OPEN_SYSTEM:
auth_alg = WLAN_AUTH_OPEN;
Expand Down Expand Up @@ -2163,9 +2170,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
sdata->name, bssid, req->reason_code);

ieee80211_send_deauth_disassoc(sdata, bssid,
IEEE80211_STYPE_DEAUTH, req->reason_code,
cookie);
ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
req->reason_code, cookie,
!req->local_state_change);

ieee80211_recalc_idle(sdata->local);

Expand Down Expand Up @@ -2202,7 +2209,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,

ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
IEEE80211_STYPE_DISASSOC, req->reason_code,
cookie);
cookie, !req->local_state_change);
sta_info_destroy_addr(sdata, bssid);

ieee80211_recalc_idle(sdata->local);
Expand Down
15 changes: 10 additions & 5 deletions trunk/net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
const u8 *key, int key_len, int key_idx);
const u8 *key, int key_len, int key_idx,
bool local_state_change);
int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct ieee80211_channel *chan,
enum nl80211_auth_type auth_type, const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
const u8 *key, int key_len, int key_idx);
const u8 *key, int key_len, int key_idx,
bool local_state_change);
int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct ieee80211_channel *chan,
Expand All @@ -315,13 +317,16 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct cfg80211_crypto_settings *crypt);
int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason);
const u8 *ie, int ie_len, u16 reason,
bool local_state_change);
int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason);
const u8 *ie, int ie_len, u16 reason,
bool local_state_change);
int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason);
const u8 *ie, int ie_len, u16 reason,
bool local_state_change);
void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
struct net_device *dev);
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
Expand Down
39 changes: 28 additions & 11 deletions trunk/net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
const u8 *key, int key_len, int key_idx)
const u8 *key, int key_len, int key_idx,
bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_auth_request req;
Expand Down Expand Up @@ -407,6 +408,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,

memset(&req, 0, sizeof(req));

req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
req.auth_type = auth_type;
Expand All @@ -433,12 +435,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
goto out;
}

wdev->authtry_bsses[slot] = bss;
if (local_state_change)
wdev->auth_bsses[slot] = bss;
else
wdev->authtry_bsses[slot] = bss;
cfg80211_hold_bss(bss);

err = rdev->ops->auth(&rdev->wiphy, dev, &req);
if (err) {
wdev->authtry_bsses[slot] = NULL;
if (local_state_change)
wdev->auth_bsses[slot] = NULL;
else
wdev->authtry_bsses[slot] = NULL;
cfg80211_unhold_bss(bss);
}

Expand All @@ -453,14 +461,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
enum nl80211_auth_type auth_type, const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
const u8 *key, int key_len, int key_idx)
const u8 *key, int key_len, int key_idx,
bool local_state_change)
{
int err;

wdev_lock(dev->ieee80211_ptr);
err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
ssid, ssid_len, ie, ie_len,
key, key_len, key_idx);
key, key_len, key_idx, local_state_change);
wdev_unlock(dev->ieee80211_ptr);

return err;
Expand Down Expand Up @@ -554,7 +563,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,

int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason)
const u8 *ie, int ie_len, u16 reason,
bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_deauth_request req;
Expand All @@ -564,6 +574,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,

memset(&req, 0, sizeof(req));
req.reason_code = reason;
req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
if (wdev->current_bss &&
Expand All @@ -590,21 +601,24 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,

int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason)
const u8 *ie, int ie_len, u16 reason,
bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;

wdev_lock(wdev);
err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason);
err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
local_state_change);
wdev_unlock(wdev);

return err;
}

static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason)
const u8 *ie, int ie_len, u16 reason,
bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_disassoc_request req;
Expand All @@ -619,6 +633,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,

memset(&req, 0, sizeof(req));
req.reason_code = reason;
req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
Expand All @@ -631,13 +646,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,

int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
const u8 *ie, int ie_len, u16 reason)
const u8 *ie, int ie_len, u16 reason,
bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;

wdev_lock(wdev);
err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason);
err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
local_state_change);
wdev_unlock(wdev);

return err;
Expand Down
19 changes: 16 additions & 3 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
[NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
};

/* policy for the attributes */
Expand Down Expand Up @@ -3393,6 +3394,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
int err, ssid_len, ie_len = 0;
enum nl80211_auth_type auth_type;
struct key_parse key;
bool local_state_change;

if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
Expand Down Expand Up @@ -3471,9 +3473,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
goto out;
}

local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];

err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
ssid, ssid_len, ie, ie_len,
key.p.key, key.p.key_len, key.idx);
key.p.key, key.p.key_len, key.idx,
local_state_change);

out:
cfg80211_unlock_rdev(rdev);
Expand Down Expand Up @@ -3650,6 +3655,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
const u8 *ie = NULL, *bssid;
int err, ie_len = 0;
u16 reason_code;
bool local_state_change;

if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
Expand Down Expand Up @@ -3695,7 +3701,10 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}

err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code);
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];

err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
local_state_change);

out:
cfg80211_unlock_rdev(rdev);
Expand All @@ -3712,6 +3721,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
const u8 *ie = NULL, *bssid;
int err, ie_len = 0;
u16 reason_code;
bool local_state_change;

if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
Expand Down Expand Up @@ -3757,7 +3767,10 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}

err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code);
local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];

err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
local_state_change);

out:
cfg80211_unlock_rdev(rdev);
Expand Down
Loading

0 comments on commit c1ce7b5

Please sign in to comment.