diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-07 08:37:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:02:30 -0400 |
commit | 3e5d7649a64e558e4146ddfad4dfcf13fc65dd47 (patch) | |
tree | fa51725ca07cf682e6694ba5f107d8614d9f0972 /net | |
parent | 2ffa5fede379091bf62a732462b829e4b51af054 (diff) |
cfg80211: let SME control reassociation vs. association
Since we don't really know that well in the kernel,
let's let the SME control whether it wants to use
reassociation or not, by allowing it to give the
previous BSSID in the associate() parameters.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 7 | ||||
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/mlme.c | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 10 | ||||
-rw-r--r-- | net/wireless/sme.c | 8 |
6 files changed, 25 insertions, 13 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0f29cd0580c9..e6d8860f26f2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1256,6 +1256,12 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | |||
1256 | sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED; | 1256 | sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED; |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | if (req->prev_bssid) { | ||
1260 | sdata->u.mgd.flags |= IEEE80211_STA_PREV_BSSID_SET; | ||
1261 | memcpy(sdata->u.mgd.prev_bssid, req->prev_bssid, ETH_ALEN); | ||
1262 | } else | ||
1263 | sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
1264 | |||
1259 | if (req->crypto.control_port) | 1265 | if (req->crypto.control_port) |
1260 | sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT; | 1266 | sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT; |
1261 | else | 1267 | else |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index aa1829ae431d..24486455e505 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -879,9 +879,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
879 | ieee80211_rx_bss_put(local, bss); | 879 | ieee80211_rx_bss_put(local, bss); |
880 | } | 880 | } |
881 | 881 | ||
882 | ifmgd->flags |= IEEE80211_STA_PREV_BSSID_SET; | ||
883 | memcpy(ifmgd->prev_bssid, sdata->u.mgd.bssid, ETH_ALEN); | ||
884 | |||
885 | ifmgd->last_probe = jiffies; | 882 | ifmgd->last_probe = jiffies; |
886 | ieee80211_led_assoc(local, 1); | 883 | ieee80211_led_assoc(local, 1); |
887 | 884 | ||
@@ -1470,10 +1467,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1470 | if (status_code != WLAN_STATUS_SUCCESS) { | 1467 | if (status_code != WLAN_STATUS_SUCCESS) { |
1471 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", | 1468 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", |
1472 | sdata->dev->name, status_code); | 1469 | sdata->dev->name, status_code); |
1473 | /* if this was a reassociation, ensure we try a "full" | ||
1474 | * association next time. This works around some broken APs | ||
1475 | * which do not correctly reject reassociation requests. */ | ||
1476 | ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
1477 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len, | 1470 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len, |
1478 | GFP_KERNEL); | 1471 | GFP_KERNEL); |
1479 | /* Wait for SME to decide what to do next */ | 1472 | /* Wait for SME to decide what to do next */ |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 82918f5896a5..4554453c116a 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -202,7 +202,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
202 | const u8 *ie, int ie_len); | 202 | const u8 *ie, int ie_len); |
203 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 203 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
204 | struct net_device *dev, struct ieee80211_channel *chan, | 204 | struct net_device *dev, struct ieee80211_channel *chan, |
205 | const u8 *bssid, const u8 *ssid, int ssid_len, | 205 | const u8 *bssid, const u8 *prev_bssid, |
206 | const u8 *ssid, int ssid_len, | ||
206 | const u8 *ie, int ie_len, bool use_mfp, | 207 | const u8 *ie, int ie_len, bool use_mfp, |
207 | struct cfg80211_crypto_settings *crypt); | 208 | struct cfg80211_crypto_settings *crypt); |
208 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 209 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 020f33b38467..087d3377958f 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -335,7 +335,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
335 | 335 | ||
336 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 336 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
337 | struct net_device *dev, struct ieee80211_channel *chan, | 337 | struct net_device *dev, struct ieee80211_channel *chan, |
338 | const u8 *bssid, const u8 *ssid, int ssid_len, | 338 | const u8 *bssid, const u8 *prev_bssid, |
339 | const u8 *ssid, int ssid_len, | ||
339 | const u8 *ie, int ie_len, bool use_mfp, | 340 | const u8 *ie, int ie_len, bool use_mfp, |
340 | struct cfg80211_crypto_settings *crypt) | 341 | struct cfg80211_crypto_settings *crypt) |
341 | { | 342 | { |
@@ -353,6 +354,7 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
353 | req.ie_len = ie_len; | 354 | req.ie_len = ie_len; |
354 | memcpy(&req.crypto, crypt, sizeof(req.crypto)); | 355 | memcpy(&req.crypto, crypt, sizeof(req.crypto)); |
355 | req.use_mfp = use_mfp; | 356 | req.use_mfp = use_mfp; |
357 | req.prev_bssid = prev_bssid; | ||
356 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 358 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
357 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 359 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
358 | if (!req.bss) | 360 | if (!req.bss) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 723512b48f2e..44c520c264fc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -71,6 +71,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
71 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, | 71 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, |
72 | 72 | ||
73 | [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, | 73 | [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, |
74 | [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, | ||
74 | 75 | ||
75 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, | 76 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, |
76 | .len = WLAN_MAX_KEY_LEN }, | 77 | .len = WLAN_MAX_KEY_LEN }, |
@@ -3187,7 +3188,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
3187 | struct net_device *dev; | 3188 | struct net_device *dev; |
3188 | struct cfg80211_crypto_settings crypto; | 3189 | struct cfg80211_crypto_settings crypto; |
3189 | struct ieee80211_channel *chan; | 3190 | struct ieee80211_channel *chan; |
3190 | const u8 *bssid, *ssid, *ie = NULL; | 3191 | const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; |
3191 | int err, ssid_len, ie_len = 0; | 3192 | int err, ssid_len, ie_len = 0; |
3192 | bool use_mfp = false; | 3193 | bool use_mfp = false; |
3193 | 3194 | ||
@@ -3248,10 +3249,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
3248 | } | 3249 | } |
3249 | } | 3250 | } |
3250 | 3251 | ||
3252 | if (info->attrs[NL80211_ATTR_PREV_BSSID]) | ||
3253 | prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); | ||
3254 | |||
3251 | err = nl80211_crypto_settings(info, &crypto, 1); | 3255 | err = nl80211_crypto_settings(info, &crypto, 1); |
3252 | if (!err) | 3256 | if (!err) |
3253 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, ssid, | 3257 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, |
3254 | ssid_len, ie, ie_len, use_mfp, | 3258 | ssid, ssid_len, ie, ie_len, use_mfp, |
3255 | &crypto); | 3259 | &crypto); |
3256 | 3260 | ||
3257 | out: | 3261 | out: |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 412161f7b08e..066a19ef9d73 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -125,8 +125,14 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
125 | case CFG80211_CONN_ASSOCIATE_NEXT: | 125 | case CFG80211_CONN_ASSOCIATE_NEXT: |
126 | BUG_ON(!drv->ops->assoc); | 126 | BUG_ON(!drv->ops->assoc); |
127 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; | 127 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; |
128 | /* | ||
129 | * We could, later, implement roaming here and then actually | ||
130 | * set prev_bssid to non-NULL. But then we need to be aware | ||
131 | * that some APs don't like that -- so we'd need to retry | ||
132 | * the association. | ||
133 | */ | ||
128 | err = cfg80211_mlme_assoc(drv, wdev->netdev, | 134 | err = cfg80211_mlme_assoc(drv, wdev->netdev, |
129 | params->channel, params->bssid, | 135 | params->channel, params->bssid, NULL, |
130 | params->ssid, params->ssid_len, | 136 | params->ssid, params->ssid_len, |
131 | params->ie, params->ie_len, | 137 | params->ie, params->ie_len, |
132 | false, ¶ms->crypto); | 138 | false, ¶ms->crypto); |