aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-07-12 06:30:59 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-13 14:49:43 -0400
commit95acac61ba66c4abd40e038dae8c1ed2e176c7b1 (patch)
tree8a1737bc3a2ca8af0031e1c2cda07608965ad282 /net/mac80211/mlme.c
parent2fcf282471f04f465d0368e46e973e01504292b3 (diff)
mac80211: allow driver to disconnect after resume
In WoWLAN, devices may use crypto keys for TX/RX and could also implement GTK rekeying. If the driver isn't able to retrieve replay counters and similar information from the device upon resume, or if the device isn't responsive due to platform issues, it isn't safe to keep the connection up as GTK rekey messages from during the sleep time could be replayed against it. The only protection against that is disconnecting from the AP. Modifying mac80211 to do that while it is resuming would be very complex and invasive in the case that the driver requires a reconfig, so do it after it has resumed completely. In that case, however, packets might be replayed since it can then only happen after TX/RX are up again, so mark keys for interfaces that need to disconnect as "tainted" and drop all packets that are sent or received with those keys. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4b0460ad8c8f..c99237cd4b98 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2052,7 +2052,7 @@ static void ieee80211_sta_timer(unsigned long data)
2052} 2052}
2053 2053
2054static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 2054static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2055 u8 *bssid) 2055 u8 *bssid, u8 reason)
2056{ 2056{
2057 struct ieee80211_local *local = sdata->local; 2057 struct ieee80211_local *local = sdata->local;
2058 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2058 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -2070,8 +2070,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2070 * but that's not a problem. 2070 * but that's not a problem.
2071 */ 2071 */
2072 ieee80211_send_deauth_disassoc(sdata, bssid, 2072 ieee80211_send_deauth_disassoc(sdata, bssid,
2073 IEEE80211_STYPE_DEAUTH, 2073 IEEE80211_STYPE_DEAUTH, reason,
2074 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2075 NULL, true); 2074 NULL, true);
2076 mutex_lock(&ifmgd->mtx); 2075 mutex_lock(&ifmgd->mtx);
2077} 2076}
@@ -2117,7 +2116,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2117 " AP %pM, disconnecting.\n", 2116 " AP %pM, disconnecting.\n",
2118 sdata->name, bssid); 2117 sdata->name, bssid);
2119#endif 2118#endif
2120 ieee80211_sta_connection_lost(sdata, bssid); 2119 ieee80211_sta_connection_lost(sdata, bssid,
2120 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2121 } 2121 }
2122 } else if (time_is_after_jiffies(ifmgd->probe_timeout)) 2122 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
2123 run_again(ifmgd, ifmgd->probe_timeout); 2123 run_again(ifmgd, ifmgd->probe_timeout);
@@ -2129,7 +2129,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2129 sdata->name, 2129 sdata->name,
2130 bssid, probe_wait_ms); 2130 bssid, probe_wait_ms);
2131#endif 2131#endif
2132 ieee80211_sta_connection_lost(sdata, bssid); 2132 ieee80211_sta_connection_lost(sdata, bssid,
2133 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2133 } else if (ifmgd->probe_send_count < max_tries) { 2134 } else if (ifmgd->probe_send_count < max_tries) {
2134#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2135#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2135 wiphy_debug(local->hw.wiphy, 2136 wiphy_debug(local->hw.wiphy,
@@ -2151,7 +2152,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2151 sdata->name, 2152 sdata->name,
2152 bssid, probe_wait_ms); 2153 bssid, probe_wait_ms);
2153 2154
2154 ieee80211_sta_connection_lost(sdata, bssid); 2155 ieee80211_sta_connection_lost(sdata, bssid,
2156 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2155 } 2157 }
2156 } 2158 }
2157 2159
@@ -2241,6 +2243,24 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
2241 if (!ifmgd->associated) 2243 if (!ifmgd->associated)
2242 return; 2244 return;
2243 2245
2246 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
2247 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
2248 mutex_lock(&ifmgd->mtx);
2249 if (ifmgd->associated) {
2250#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2251 wiphy_debug(sdata->local->hw.wiphy,
2252 "%s: driver requested disconnect after resume.\n",
2253 sdata->name);
2254#endif
2255 ieee80211_sta_connection_lost(sdata,
2256 ifmgd->associated->bssid,
2257 WLAN_REASON_UNSPECIFIED);
2258 mutex_unlock(&ifmgd->mtx);
2259 return;
2260 }
2261 mutex_unlock(&ifmgd->mtx);
2262 }
2263
2244 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) 2264 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
2245 add_timer(&ifmgd->timer); 2265 add_timer(&ifmgd->timer);
2246 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) 2266 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))