summaryrefslogtreecommitdiff
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2021-09-20 16:40:10 +0300
committerJohannes Berg <johannes.berg@intel.com>2021-09-23 17:27:07 +0300
commit5d24828d05f37ad770599de00b53d5386e35aa61 (patch)
tree830777beb40a6edffaaca20804e173c85e134b78 /net/mac80211/ibss.c
parent49a765d6785e99157ff5091cc37485732496864e (diff)
downloadlinux-5d24828d05f37ad770599de00b53d5386e35aa61.tar.xz
mac80211: always allocate struct ieee802_11_elems
As the 802.11 spec evolves, we need to parse more and more elements. This is causing the struct to grow, and we can no longer get away with putting it on the stack. Change the API to always dynamically allocate and return an allocated pointer that must be kfree()d later. As an alternative, I contemplated a scheme whereby we'd say in the code which elements we needed, e.g. DECLARE_ELEMENT_PARSER(elems, SUPPORTED_CHANNELS, CHANNEL_SWITCH, EXT(KEY_DELIVERY)); ieee802_11_parse_elems(..., &elems, ...); and while I think this is possible and will save us a lot since most individual places only care about a small subset of the elements, it ended up being a bit more work since a lot of places do the parsing and then pass the struct to other functions, sometimes with multiple levels. Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5d6ca4c3e698..66b00046f0c2 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -9,7 +9,7 @@
* Copyright 2009, 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/delay.h>
@@ -1589,7 +1589,7 @@ void ieee80211_rx_mgmt_probe_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_status *rx_status)
{
size_t baselen;
- struct ieee802_11_elems elems;
+ struct ieee802_11_elems *elems;
BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) !=
offsetof(typeof(mgmt->u.beacon), variable));
@@ -1602,10 +1602,14 @@ void ieee80211_rx_mgmt_probe_beacon(struct ieee80211_sub_if_data *sdata,
if (baselen > len)
return;
- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
- false, &elems, mgmt->bssid, NULL);
+ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
+ len - baselen, false,
+ mgmt->bssid, NULL);
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
+ if (elems) {
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems);
+ kfree(elems);
+ }
}
void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1614,7 +1618,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_status *rx_status;
struct ieee80211_mgmt *mgmt;
u16 fc;
- struct ieee802_11_elems elems;
+ struct ieee802_11_elems *elems;
int ies_len;
rx_status = IEEE80211_SKB_RXCB(skb);
@@ -1651,15 +1655,16 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
if (ies_len < 0)
break;
- ieee802_11_parse_elems(
+ elems = ieee802_11_parse_elems(
mgmt->u.action.u.chan_switch.variable,
- ies_len, true, &elems, mgmt->bssid, NULL);
+ ies_len, true, mgmt->bssid, NULL);
- if (elems.parse_error)
+ if (!elems || elems->parse_error)
break;
ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
- rx_status, &elems);
+ rx_status, elems);
+ kfree(elems);
break;
}
}