aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/sme.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-04-04 02:37:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-07 14:37:56 -0400
commitd5cdfacb35ed886271d1ccfffbded98d3447da17 (patch)
tree8233a713949c4c8da8c98e75868efc74d5613c3d /net/wireless/sme.c
parent7590a550b88b8c3cb025f0a8ed58e279ad62e4c1 (diff)
cfg80211: Add local-state-change-only auth/deauth/disassoc
cfg80211 is quite strict on allowing authentication and association commands only in certain states. In order to meet these requirements, user space applications may need to clear authentication or association state in some cases. Currently, this can be done with deauth/disassoc command, but that ends up sending out Deauthentication or Disassociation frame unnecessarily. Add a new nl80211 attribute to allow this sending of the frame be skipped, but with all other deauth/disassoc operations being completed. Similar state change is also needed for IEEE 802.11r FT protocol in the FT-over-DS case which does not use Authentication frame exchange in a transition to another BSS. For this to work with cfg80211, an authentication entry needs to be created for the target BSS without sending out an Authentication frame. The nl80211 authentication command can be used for this purpose, too, with the new attribute to indicate that the command is only for changing local state. This enables wpa_supplicant to complete FT-over-DS transition successfully. Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r--net/wireless/sme.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 17fde0da1b08..17465777eb47 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -170,7 +170,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
170 params->ssid, params->ssid_len, 170 params->ssid, params->ssid_len,
171 NULL, 0, 171 NULL, 0,
172 params->key, params->key_len, 172 params->key, params->key_len,
173 params->key_idx); 173 params->key_idx, false);
174 case CFG80211_CONN_ASSOCIATE_NEXT: 174 case CFG80211_CONN_ASSOCIATE_NEXT:
175 BUG_ON(!rdev->ops->assoc); 175 BUG_ON(!rdev->ops->assoc);
176 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 176 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -185,12 +185,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
185 if (err) 185 if (err)
186 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 186 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
187 NULL, 0, 187 NULL, 0,
188 WLAN_REASON_DEAUTH_LEAVING); 188 WLAN_REASON_DEAUTH_LEAVING,
189 false);
189 return err; 190 return err;
190 case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 191 case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
191 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 192 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
192 NULL, 0, 193 NULL, 0,
193 WLAN_REASON_DEAUTH_LEAVING); 194 WLAN_REASON_DEAUTH_LEAVING, false);
194 /* return an error so that we call __cfg80211_connect_result() */ 195 /* return an error so that we call __cfg80211_connect_result() */
195 return -EINVAL; 196 return -EINVAL;
196 default: 197 default:
@@ -675,7 +676,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
675 continue; 676 continue;
676 bssid = wdev->auth_bsses[i]->pub.bssid; 677 bssid = wdev->auth_bsses[i]->pub.bssid;
677 ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 678 ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
678 WLAN_REASON_DEAUTH_LEAVING); 679 WLAN_REASON_DEAUTH_LEAVING,
680 false);
679 WARN(ret, "deauth failed: %d\n", ret); 681 WARN(ret, "deauth failed: %d\n", ret);
680 } 682 }
681 } 683 }
@@ -934,7 +936,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
934 /* wdev->conn->params.bssid must be set if > SCANNING */ 936 /* wdev->conn->params.bssid must be set if > SCANNING */
935 err = __cfg80211_mlme_deauth(rdev, dev, 937 err = __cfg80211_mlme_deauth(rdev, dev,
936 wdev->conn->params.bssid, 938 wdev->conn->params.bssid,
937 NULL, 0, reason); 939 NULL, 0, reason, false);
938 if (err) 940 if (err)
939 return err; 941 return err;
940 } else { 942 } else {
@@ -990,7 +992,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
990 992
991 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); 993 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
992 if (__cfg80211_mlme_deauth(rdev, dev, bssid, 994 if (__cfg80211_mlme_deauth(rdev, dev, bssid,
993 NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) { 995 NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
996 false)) {
994 /* whatever -- assume gone anyway */ 997 /* whatever -- assume gone anyway */
995 cfg80211_unhold_bss(wdev->auth_bsses[idx]); 998 cfg80211_unhold_bss(wdev->auth_bsses[idx]);
996 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); 999 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);