summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/ieee80211-uhr.h44
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/parse.c4
-rw-r--r--net/wireless/nl80211.c2
4 files changed, 25 insertions, 28 deletions
diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h
index 597c9e559261..665d4b3a5b41 100644
--- a/include/linux/ieee80211-uhr.h
+++ b/include/linux/ieee80211-uhr.h
@@ -17,6 +17,11 @@
#define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004
#define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008
#define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070
+#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0080
+#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0100
+#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0200
+#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0400
+#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x0800
struct ieee80211_uhr_operation {
__le16 params;
@@ -265,8 +270,7 @@ struct ieee80211_uhr_p_edca_info {
__le16 params;
} __packed;
-static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
- bool beacon)
+static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len)
{
const struct ieee80211_uhr_operation *oper = (const void *)data;
u8 needed = sizeof(*oper);
@@ -274,19 +278,15 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
if (len < needed)
return false;
- /* nothing else present in beacons */
- if (beacon)
- return true;
-
/* DPS Operation Parameters (fixed 4 bytes) */
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) {
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) {
needed += sizeof(struct ieee80211_uhr_dps_info);
if (len < needed)
return false;
}
/* NPCA Operation Parameters (fixed 4 bytes + optional 2 bytes) */
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) {
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) {
const struct ieee80211_uhr_npca_info *npca =
(const void *)(data + needed);
@@ -303,14 +303,14 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
}
/* P-EDCA Operation Parameters (fixed 3 bytes) */
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) {
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) {
needed += sizeof(struct ieee80211_uhr_p_edca_info);
if (len < needed)
return false;
}
/* DBE Operation Parameters (fixed 1 byte + optional 2 bytes) */
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA)) {
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES)) {
const struct ieee80211_uhr_dbe_info *dbe =
(const void *)(data + needed);
@@ -329,19 +329,19 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len,
return len >= needed;
}
-/*
- * Note: cannot call this on the element coming from a beacon,
- * must ensure ieee80211_uhr_oper_size_ok(..., false) first
- */
+/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */
static inline const struct ieee80211_uhr_npca_info *
ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper)
{
const u8 *pos = oper->variable;
+ if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)))
+ return NULL;
+
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)))
return NULL;
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA))
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES))
pos += sizeof(struct ieee80211_uhr_dps_info);
return (const void *)pos;
@@ -360,22 +360,22 @@ ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper)
return npca->dis_subch_bmap;
}
-/*
- * Note: cannot call this on the element coming from a beacon,
- * must ensure ieee80211_uhr_oper_size_ok(..., false) first
- */
+/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */
static inline const struct ieee80211_uhr_dbe_info *
ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper)
{
const u8 *pos = oper->variable;
+ if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES)))
+ return NULL;
+
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA)))
return NULL;
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA))
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES))
pos += sizeof(struct ieee80211_uhr_dps_info);
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) {
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) {
const struct ieee80211_uhr_npca_info *npca = (const void *)pos;
pos += sizeof(*npca);
@@ -383,7 +383,7 @@ ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper)
pos += sizeof(npca->dis_subch_bmap[0]);
}
- if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA))
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES))
pos += sizeof(struct ieee80211_uhr_p_edca_info);
return (const void *)pos;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1afdb610dff2..c4590c4a56b0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1701,8 +1701,7 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
if (stype != IEEE80211_STYPE_BEACON &&
chanreq.oper.npca_chan && elems->uhr_operation &&
ieee80211_uhr_oper_size_ok((const void *)elems->uhr_operation,
- elems->uhr_operation_len,
- false)) {
+ elems->uhr_operation_len)) {
const struct ieee80211_uhr_npca_info *npca;
struct ieee80211_bss_npca_params params = {};
diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c
index c2f2f78f2b4f..cb2be167cde7 100644
--- a/net/mac80211/parse.c
+++ b/net/mac80211/parse.c
@@ -209,9 +209,7 @@ ieee80211_parse_extension_element(u32 *crc,
if (params->mode < IEEE80211_CONN_MODE_UHR)
break;
calc_crc = true;
- if (ieee80211_uhr_oper_size_ok(data, len,
- params->type == (IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_BEACON))) {
+ if (ieee80211_uhr_oper_size_ok(data, len)) {
elems->uhr_operation = data;
elems->uhr_operation_len = len;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 242071ad10d6..5fa70974d57c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -441,7 +441,7 @@ static int validate_uhr_operation(const struct nlattr *attr,
const u8 *data = nla_data(attr);
unsigned int len = nla_len(attr);
- if (!ieee80211_uhr_oper_size_ok(data, len, false))
+ if (!ieee80211_uhr_oper_size_ok(data, len))
return -EINVAL;
return 0;
}