diff options
-rw-r--r-- | include/net/mac80211.h | 23 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/key.h | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 32 | ||||
-rw-r--r-- | net/mac80211/rx.c | 3 | ||||
-rw-r--r-- | net/mac80211/tx.c | 3 | ||||
-rw-r--r-- | net/mac80211/util.c | 27 |
7 files changed, 86 insertions, 6 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8ff3d8a1377c..ea2c8c36477c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -3024,6 +3024,29 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); | |||
3024 | void ieee80211_connection_loss(struct ieee80211_vif *vif); | 3024 | void ieee80211_connection_loss(struct ieee80211_vif *vif); |
3025 | 3025 | ||
3026 | /** | 3026 | /** |
3027 | * ieee80211_resume_disconnect - disconnect from AP after resume | ||
3028 | * | ||
3029 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
3030 | * | ||
3031 | * Instructs mac80211 to disconnect from the AP after resume. | ||
3032 | * Drivers can use this after WoWLAN if they know that the | ||
3033 | * connection cannot be kept up, for example because keys were | ||
3034 | * used while the device was asleep but the replay counters or | ||
3035 | * similar cannot be retrieved from the device during resume. | ||
3036 | * | ||
3037 | * Note that due to implementation issues, if the driver uses | ||
3038 | * the reconfiguration functionality during resume the interface | ||
3039 | * will still be added as associated first during resume and then | ||
3040 | * disconnect normally later. | ||
3041 | * | ||
3042 | * This function can only be called from the resume callback and | ||
3043 | * the driver must not be holding any of its own locks while it | ||
3044 | * calls this function, or at least not any locks it needs in the | ||
3045 | * key configuration paths (if it supports HW crypto). | ||
3046 | */ | ||
3047 | void ieee80211_resume_disconnect(struct ieee80211_vif *vif); | ||
3048 | |||
3049 | /** | ||
3027 | * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm | 3050 | * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm |
3028 | * | 3051 | * |
3029 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | 3052 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 96600bec44c5..dda0d1ab34f3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -538,12 +538,14 @@ struct ieee80211_if_mesh { | |||
538 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between | 538 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between |
539 | * associated stations and deliver multicast frames both | 539 | * associated stations and deliver multicast frames both |
540 | * back to wireless media and to the local net stack. | 540 | * back to wireless media and to the local net stack. |
541 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. | ||
541 | */ | 542 | */ |
542 | enum ieee80211_sub_if_data_flags { | 543 | enum ieee80211_sub_if_data_flags { |
543 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 544 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
544 | IEEE80211_SDATA_PROMISC = BIT(1), | 545 | IEEE80211_SDATA_PROMISC = BIT(1), |
545 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 546 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
546 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 547 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
548 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), | ||
547 | }; | 549 | }; |
548 | 550 | ||
549 | /** | 551 | /** |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 86b216b01415..7d4e31f037d7 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -41,9 +41,11 @@ struct sta_info; | |||
41 | * | 41 | * |
42 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present | 42 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present |
43 | * in the hardware for TX crypto hardware acceleration. | 43 | * in the hardware for TX crypto hardware acceleration. |
44 | * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. | ||
44 | */ | 45 | */ |
45 | enum ieee80211_internal_key_flags { | 46 | enum ieee80211_internal_key_flags { |
46 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), | 47 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), |
48 | KEY_FLAG_TAINTED = BIT(1), | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | enum ieee80211_internal_tkip_state { | 51 | enum ieee80211_internal_tkip_state { |
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 | ||
2054 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 2054 | static 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)) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e6dccc70931d..fe2c2a717793 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1019,6 +1019,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | if (rx->key) { | 1021 | if (rx->key) { |
1022 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1023 | return RX_DROP_MONITOR; | ||
1024 | |||
1022 | rx->key->tx_rx_count++; | 1025 | rx->key->tx_rx_count++; |
1023 | /* TODO: add threshold stuff again */ | 1026 | /* TODO: add threshold stuff again */ |
1024 | } else { | 1027 | } else { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e8d0d2d22665..8cb0d2d0ac69 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -589,6 +589,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
589 | break; | 589 | break; |
590 | } | 590 | } |
591 | 591 | ||
592 | if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED)) | ||
593 | return TX_DROP; | ||
594 | |||
592 | if (!skip_hw && tx->key && | 595 | if (!skip_hw && tx->key && |
593 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 596 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
594 | info->control.hw_key = &tx->key->conf; | 597 | info->control.hw_key = &tx->key->conf; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 190132063c99..5bfb80cba634 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1334,6 +1334,33 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1334 | return 0; | 1334 | return 0; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | void ieee80211_resume_disconnect(struct ieee80211_vif *vif) | ||
1338 | { | ||
1339 | struct ieee80211_sub_if_data *sdata; | ||
1340 | struct ieee80211_local *local; | ||
1341 | struct ieee80211_key *key; | ||
1342 | |||
1343 | if (WARN_ON(!vif)) | ||
1344 | return; | ||
1345 | |||
1346 | sdata = vif_to_sdata(vif); | ||
1347 | local = sdata->local; | ||
1348 | |||
1349 | if (WARN_ON(!local->resuming)) | ||
1350 | return; | ||
1351 | |||
1352 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
1353 | return; | ||
1354 | |||
1355 | sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME; | ||
1356 | |||
1357 | mutex_lock(&local->key_mtx); | ||
1358 | list_for_each_entry(key, &sdata->key_list, list) | ||
1359 | key->flags |= KEY_FLAG_TAINTED; | ||
1360 | mutex_unlock(&local->key_mtx); | ||
1361 | } | ||
1362 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); | ||
1363 | |||
1337 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | 1364 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, |
1338 | enum ieee80211_smps_mode *smps_mode) | 1365 | enum ieee80211_smps_mode *smps_mode) |
1339 | { | 1366 | { |