aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch313
1 files changed, 0 insertions, 313 deletions
diff --git a/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch b/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch
deleted file mode 100644
index b536126d38..0000000000
--- a/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch
+++ /dev/null
@@ -1,313 +0,0 @@
-From: Johannes Berg <johannes.berg@intel.com>
-Date: Tue, 11 May 2021 20:02:47 +0200
-Subject: [PATCH] mac80211: add fragment cache to sta_info
-
-Prior patches protected against fragmentation cache attacks
-by coloring keys, but this shows that it can lead to issues
-when multiple stations use the same sequence number. Add a
-fragment cache to struct sta_info (in addition to the one in
-the interface) to separate fragments for different stations
-properly.
-
-This then automatically clear most of the fragment cache when a
-station disconnects (or reassociates) from an AP, or when client
-interfaces disconnect from the network, etc.
-
-On the way, also fix the comment there since this brings us in line
-with the recommendation in 802.11-2016 ("An AP should support ...").
-Additionally, remove a useless condition (since there's no problem
-purging an already empty list).
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -50,12 +50,6 @@ struct ieee80211_local;
- #define IEEE80211_ENCRYPT_HEADROOM 8
- #define IEEE80211_ENCRYPT_TAILROOM 18
-
--/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent
-- * reception of at least three fragmented frames. This limit can be increased
-- * by changing this define, at the cost of slower frame reassembly and
-- * increased memory use (about 2 kB of RAM per entry). */
--#define IEEE80211_FRAGMENT_MAX 4
--
- /* power level hasn't been configured (or set to automatic) */
- #define IEEE80211_UNSET_POWER_LEVEL INT_MIN
-
-@@ -88,19 +82,6 @@ extern const u8 ieee80211_ac_to_qos_mask
-
- #define IEEE80211_MAX_NAN_INSTANCE_ID 255
-
--struct ieee80211_fragment_entry {
-- struct sk_buff_head skb_list;
-- unsigned long first_frag_time;
-- u16 seq;
-- u16 extra_len;
-- u16 last_frag;
-- u8 rx_queue;
-- bool check_sequential_pn; /* needed for CCMP/GCMP */
-- u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
-- unsigned int key_color;
--};
--
--
- struct ieee80211_bss {
- u32 device_ts_beacon, device_ts_presp;
-
-@@ -912,9 +893,7 @@ struct ieee80211_sub_if_data {
-
- char name[IFNAMSIZ];
-
-- /* Fragment table for host-based reassembly */
-- struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
-- unsigned int fragment_next;
-+ struct ieee80211_fragment_cache frags;
-
- /* TID bitmap for NoAck policy */
- u16 noack_map;
-@@ -2329,4 +2308,7 @@ u32 ieee80211_calc_expected_tx_airtime(s
- #define debug_noinline
- #endif
-
-+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache);
-+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache);
-+
- #endif /* IEEE80211_I_H */
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -8,7 +8,7 @@
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright (c) 2016 Intel Deutschland GmbH
-- * Copyright (C) 2018-2020 Intel Corporation
-+ * Copyright (C) 2018-2021 Intel Corporation
- */
- #include <linux/slab.h>
- #include <linux/kernel.h>
-@@ -679,16 +679,12 @@ static void ieee80211_set_multicast_list
- */
- static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
- {
-- int i;
--
- /* free extra data */
- ieee80211_free_keys(sdata, false);
-
- ieee80211_debugfs_remove_netdev(sdata);
-
-- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
-- __skb_queue_purge(&sdata->fragments[i].skb_list);
-- sdata->fragment_next = 0;
-+ ieee80211_destroy_frag_cache(&sdata->frags);
-
- if (ieee80211_vif_is_mesh(&sdata->vif))
- ieee80211_mesh_teardown_sdata(sdata);
-@@ -2038,8 +2034,7 @@ int ieee80211_if_add(struct ieee80211_lo
- sdata->wdev.wiphy = local->hw.wiphy;
- sdata->local = local;
-
-- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
-- skb_queue_head_init(&sdata->fragments[i].skb_list);
-+ ieee80211_init_frag_cache(&sdata->frags);
-
- INIT_LIST_HEAD(&sdata->key_list);
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2133,19 +2133,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_
- return result;
- }
-
-+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
-+ skb_queue_head_init(&cache->entries[i].skb_list);
-+}
-+
-+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
-+ __skb_queue_purge(&cache->entries[i].skb_list);
-+}
-+
- static inline struct ieee80211_fragment_entry *
--ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
-+ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache,
- unsigned int frag, unsigned int seq, int rx_queue,
- struct sk_buff **skb)
- {
- struct ieee80211_fragment_entry *entry;
-
-- entry = &sdata->fragments[sdata->fragment_next++];
-- if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX)
-- sdata->fragment_next = 0;
-+ entry = &cache->entries[cache->next++];
-+ if (cache->next >= IEEE80211_FRAGMENT_MAX)
-+ cache->next = 0;
-
-- if (!skb_queue_empty(&entry->skb_list))
-- __skb_queue_purge(&entry->skb_list);
-+ __skb_queue_purge(&entry->skb_list);
-
- __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */
- *skb = NULL;
-@@ -2160,14 +2175,14 @@ ieee80211_reassemble_add(struct ieee8021
- }
-
- static inline struct ieee80211_fragment_entry *
--ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
-+ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache,
- unsigned int frag, unsigned int seq,
- int rx_queue, struct ieee80211_hdr *hdr)
- {
- struct ieee80211_fragment_entry *entry;
- int i, idx;
-
-- idx = sdata->fragment_next;
-+ idx = cache->next;
- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) {
- struct ieee80211_hdr *f_hdr;
- struct sk_buff *f_skb;
-@@ -2176,7 +2191,7 @@ ieee80211_reassemble_find(struct ieee802
- if (idx < 0)
- idx = IEEE80211_FRAGMENT_MAX - 1;
-
-- entry = &sdata->fragments[idx];
-+ entry = &cache->entries[idx];
- if (skb_queue_empty(&entry->skb_list) || entry->seq != seq ||
- entry->rx_queue != rx_queue ||
- entry->last_frag + 1 != frag)
-@@ -2217,6 +2232,7 @@ static bool requires_sequential_pn(struc
- static ieee80211_rx_result debug_noinline
- ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
- {
-+ struct ieee80211_fragment_cache *cache = &rx->sdata->frags;
- struct ieee80211_hdr *hdr;
- u16 sc;
- __le16 fc;
-@@ -2238,6 +2254,9 @@ ieee80211_rx_h_defragment(struct ieee802
- goto out_no_led;
- }
-
-+ if (rx->sta)
-+ cache = &rx->sta->frags;
-+
- if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
- goto out;
-
-@@ -2256,7 +2275,7 @@ ieee80211_rx_h_defragment(struct ieee802
-
- if (frag == 0) {
- /* This is the first fragment of a new frame. */
-- entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
-+ entry = ieee80211_reassemble_add(cache, frag, seq,
- rx->seqno_idx, &(rx->skb));
- if (requires_sequential_pn(rx, fc)) {
- int queue = rx->security_idx;
-@@ -2284,7 +2303,7 @@ ieee80211_rx_h_defragment(struct ieee802
- /* This is a fragment for a frame that should already be pending in
- * fragment cache. Add this fragment to the end of the pending entry.
- */
-- entry = ieee80211_reassemble_find(rx->sdata, frag, seq,
-+ entry = ieee80211_reassemble_find(cache, frag, seq,
- rx->seqno_idx, hdr);
- if (!entry) {
- I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -4,7 +4,7 @@
- * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
- * Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
-- * Copyright (C) 2018-2020 Intel Corporation
-+ * Copyright (C) 2018-2021 Intel Corporation
- */
-
- #include <linux/module.h>
-@@ -393,6 +393,8 @@ struct sta_info *sta_info_alloc(struct i
-
- u64_stats_init(&sta->rx_stats.syncp);
-
-+ ieee80211_init_frag_cache(&sta->frags);
-+
- sta->sta_state = IEEE80211_STA_NONE;
-
- /* Mark TID as unreserved */
-@@ -1103,6 +1105,8 @@ static void __sta_info_destroy_part2(str
-
- ieee80211_sta_debugfs_remove(sta);
-
-+ ieee80211_destroy_frag_cache(&sta->frags);
-+
- cleanup_single_sta(sta);
- }
-
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -3,7 +3,7 @@
- * Copyright 2002-2005, Devicescape Software, Inc.
- * Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright(c) 2015-2017 Intel Deutschland GmbH
-- * Copyright(c) 2020 Intel Corporation
-+ * Copyright(c) 2020-2021 Intel Corporation
- */
-
- #ifndef STA_INFO_H
-@@ -439,6 +439,33 @@ struct ieee80211_sta_rx_stats {
- };
-
- /*
-+ * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent
-+ * reception of at least one MSDU per access category per associated STA"
-+ * on APs, or "at least one MSDU per access category" on other interface types.
-+ *
-+ * This limit can be increased by changing this define, at the cost of slower
-+ * frame reassembly and increased memory use while fragments are pending.
-+ */
-+#define IEEE80211_FRAGMENT_MAX 4
-+
-+struct ieee80211_fragment_entry {
-+ struct sk_buff_head skb_list;
-+ unsigned long first_frag_time;
-+ u16 seq;
-+ u16 extra_len;
-+ u16 last_frag;
-+ u8 rx_queue;
-+ bool check_sequential_pn; /* needed for CCMP/GCMP */
-+ u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
-+ unsigned int key_color;
-+};
-+
-+struct ieee80211_fragment_cache {
-+ struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX];
-+ unsigned int next;
-+};
-+
-+/*
- * The bandwidth threshold below which the per-station CoDel parameters will be
- * scaled to be more lenient (to prevent starvation of slow stations). This
- * value will be scaled by the number of active stations when it is being
-@@ -531,6 +558,7 @@ struct ieee80211_sta_rx_stats {
- * @status_stats.last_ack_signal: last ACK signal
- * @status_stats.ack_signal_filled: last ACK signal validity
- * @status_stats.avg_ack_signal: average ACK signal
-+ * @frags: fragment cache
- */
- struct sta_info {
- /* General information, mostly static */
-@@ -639,6 +667,8 @@ struct sta_info {
-
- struct cfg80211_chan_def tdls_chandef;
-
-+ struct ieee80211_fragment_cache frags;
-+
- /* keep last! */
- struct ieee80211_sta sta;
- };