aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h23
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/key.h2
-rw-r--r--net/mac80211/mlme.c32
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/mac80211/util.c27
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);
3024void ieee80211_connection_loss(struct ieee80211_vif *vif); 3024void 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 */
3047void 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 */
542enum ieee80211_sub_if_data_flags { 543enum 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 */
45enum ieee80211_internal_key_flags { 46enum 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
49enum ieee80211_internal_tkip_state { 51enum 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
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))
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
1337void 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}
1362EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
1363
1337static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, 1364static 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{