aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-06 14:41:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:12:46 -0400
commite21546a2a3953a7d4b9d5c9b1cf12184ffceab96 (patch)
tree2810351a0fd6f7db3d83e077ad8418f4cacfea44
parent30d742d5468c954969766bb0e809f218abc73af7 (diff)
mac80211: stay authenticated after disassoc
After being disassociated by the AP, mac80211 currently reports this to cfg80211, and then goes to delete the association. That's fine, but cfg80211 assumes that it's still authenticated, however, mac80211 throws away all state. This fixes mac80211 to keep track of the authentication in that case so that cfg80211 can request a deauth or new association properly. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c31
2 files changed, 23 insertions, 9 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 630a438180fd..989591787aee 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -284,6 +284,7 @@ struct ieee80211_if_managed {
284 284
285 struct mutex mtx; 285 struct mutex mtx;
286 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
287 struct ieee80211_mgd_work *old_associate_work;
287 struct list_head work_list; 288 struct list_head work_list;
288 289
289 u8 bssid[ETH_ALEN]; 290 u8 bssid[ETH_ALEN];
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6d5a1ee0445f..c374d2d73fa4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -880,10 +880,11 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
880} 880}
881 881
882static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 882static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
883 struct ieee80211_bss *bss, 883 struct ieee80211_mgd_work *wk,
884 u32 bss_info_changed) 884 u32 bss_info_changed)
885{ 885{
886 struct ieee80211_local *local = sdata->local; 886 struct ieee80211_local *local = sdata->local;
887 struct ieee80211_bss *bss = wk->bss;
887 888
888 bss_info_changed |= BSS_CHANGED_ASSOC; 889 bss_info_changed |= BSS_CHANGED_ASSOC;
889 /* set timing information */ 890 /* set timing information */
@@ -896,6 +897,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
896 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 897 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
897 898
898 sdata->u.mgd.associated = bss; 899 sdata->u.mgd.associated = bss;
900 sdata->u.mgd.old_associate_work = wk;
899 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN); 901 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
900 902
901 /* just to be sure */ 903 /* just to be sure */
@@ -1010,7 +1012,8 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1010 return RX_MGMT_NONE; 1012 return RX_MGMT_NONE;
1011} 1013}
1012 1014
1013static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 1015static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1016 bool deauth)
1014{ 1017{
1015 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1018 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1016 struct ieee80211_local *local = sdata->local; 1019 struct ieee80211_local *local = sdata->local;
@@ -1028,6 +1031,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
1028 ifmgd->associated = NULL; 1031 ifmgd->associated = NULL;
1029 memset(ifmgd->bssid, 0, ETH_ALEN); 1032 memset(ifmgd->bssid, 0, ETH_ALEN);
1030 1033
1034 if (deauth) {
1035 kfree(ifmgd->old_associate_work);
1036 ifmgd->old_associate_work = NULL;
1037 } else {
1038 struct ieee80211_mgd_work *wk = ifmgd->old_associate_work;
1039
1040 wk->state = IEEE80211_MGD_STATE_IDLE;
1041 list_add(&wk->list, &ifmgd->work_list);
1042 }
1043
1031 /* 1044 /*
1032 * we need to commit the associated = NULL change because the 1045 * we need to commit the associated = NULL change because the
1033 * scan code uses that to determine whether this iface should 1046 * scan code uses that to determine whether this iface should
@@ -1345,7 +1358,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1345 sdata->dev->name, bssid, reason_code); 1358 sdata->dev->name, bssid, reason_code);
1346 1359
1347 if (!wk) { 1360 if (!wk) {
1348 ieee80211_set_disassoc(sdata); 1361 ieee80211_set_disassoc(sdata, true);
1349 } else { 1362 } else {
1350 list_del(&wk->list); 1363 list_del(&wk->list);
1351 kfree(wk); 1364 kfree(wk);
@@ -1378,7 +1391,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1378 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1391 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1379 sdata->dev->name, reason_code); 1392 sdata->dev->name, reason_code);
1380 1393
1381 ieee80211_set_disassoc(sdata); 1394 ieee80211_set_disassoc(sdata, false);
1382 return RX_MGMT_CFG80211_DISASSOC; 1395 return RX_MGMT_CFG80211_DISASSOC;
1383} 1396}
1384 1397
@@ -1581,7 +1594,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1581 * ieee80211_set_associated() will tell the driver */ 1594 * ieee80211_set_associated() will tell the driver */
1582 bss_conf->aid = aid; 1595 bss_conf->aid = aid;
1583 bss_conf->assoc_capability = capab_info; 1596 bss_conf->assoc_capability = capab_info;
1584 ieee80211_set_associated(sdata, wk->bss, changed); 1597 /* this will take ownership of wk */
1598 ieee80211_set_associated(sdata, wk, changed);
1585 1599
1586 /* 1600 /*
1587 * Start timer to probe the connection to the AP now. 1601 * Start timer to probe the connection to the AP now.
@@ -1590,7 +1604,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1590 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1604 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1591 mod_beacon_timer(sdata); 1605 mod_beacon_timer(sdata);
1592 1606
1593 kfree(wk);
1594 return RX_MGMT_CFG80211_ASSOC; 1607 return RX_MGMT_CFG80211_ASSOC;
1595} 1608}
1596 1609
@@ -2096,7 +2109,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2096 printk(KERN_DEBUG "No probe response from AP %pM" 2109 printk(KERN_DEBUG "No probe response from AP %pM"
2097 " after %dms, disconnecting.\n", 2110 " after %dms, disconnecting.\n",
2098 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2111 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2099 ieee80211_set_disassoc(sdata); 2112 ieee80211_set_disassoc(sdata, true);
2100 mutex_unlock(&ifmgd->mtx); 2113 mutex_unlock(&ifmgd->mtx);
2101 /* 2114 /*
2102 * must be outside lock due to cfg80211, 2115 * must be outside lock due to cfg80211,
@@ -2500,7 +2513,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2500 2513
2501 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 2514 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2502 bssid = req->bss->bssid; 2515 bssid = req->bss->bssid;
2503 ieee80211_set_disassoc(sdata); 2516 ieee80211_set_disassoc(sdata, true);
2504 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 2517 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2505 if (&wk->bss->cbss == req->bss) { 2518 if (&wk->bss->cbss == req->bss) {
2506 bssid = req->bss->bssid; 2519 bssid = req->bss->bssid;
@@ -2552,7 +2565,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2552 return -ENOLINK; 2565 return -ENOLINK;
2553 } 2566 }
2554 2567
2555 ieee80211_set_disassoc(sdata); 2568 ieee80211_set_disassoc(sdata, false);
2556 2569
2557 mutex_unlock(&ifmgd->mtx); 2570 mutex_unlock(&ifmgd->mtx);
2558 2571