summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/mlme.c83
-rw-r--r--net/mac80211/parse.c4
3 files changed, 75 insertions, 21 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 18a101710432..339faa7a0a0e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1898,6 +1898,15 @@ struct ieee802_11_elems {
struct ieee80211_mle_per_sta_profile *prof;
size_t sta_prof_len;
+ /*
+ * When parsing the beacon with MBSSID (from a transmitted BSS), this
+ * indicates that the profile the parser was instructed to look for
+ * (via the bss value in &struct ieee80211_elems_parse_params) couldn't
+ * be found (due to EMA, or perhaps broken AP) and the result cannot be
+ * considered complete.
+ */
+ bool mbssid_nontx_profile_missing;
+
/* whether/which parse error occurred while retrieving these elements */
u8 parse_error;
};
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f55cb376cbd5..2888a382677d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -7666,8 +7666,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
struct link_sta_info *link_sta;
struct sta_info *sta;
u64 changed = 0;
- bool erp_valid;
- u8 erp_value = 0;
u32 ncrc = 0;
u8 *bssid, *variable = mgmt->u.beacon.variable;
u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
@@ -7788,6 +7786,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
if (!elems)
return;
+ /*
+ * Note: with MBSSID and an EMA (or broken) AP, we could fail to find
+ * the correct multi-BSSID profile for the non-transmitting AP we're
+ * connected to. The result's elems->mbssid_nontx_profile_missing is
+ * indicating that, but some things must happen regardless.
+ */
+
if (rx_status->flag & RX_FLAG_DECRYPTED &&
ieee80211_mgd_ssid_mismatch(sdata, elems)) {
sdata_info(sdata, "SSID mismatch for AP %pM, disconnect\n",
@@ -7823,6 +7828,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
}
}
+ /*
+ * P2P will almost certainly not have MBSSID, but this just
+ * assumes that it would at least always inherit NoA anyway
+ * since it's absent from the channel.
+ */
if (sdata->vif.p2p ||
sdata->vif.driver_flags & IEEE80211_VIF_GET_NOA_UPDATE) {
struct ieee80211_p2p_noa_attr noa = {};
@@ -7880,23 +7890,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
ieee80211_rx_bss_info(link, mgmt, len, rx_status);
+ /*
+ * This assumes that all members of a multiple BSS set must be
+ * switching together, so we can parse channel switch elements
+ * from the transmitted BSS even if our non-transmitted one is
+ * not present in this beacon (due to EMA.)
+ */
ieee80211_sta_process_chanswitch(link, rx_status->mactime,
rx_status->device_timestamp,
elems, elems,
IEEE80211_CSA_SOURCE_BEACON);
- /* note that after this elems->ml_basic can no longer be used fully */
- ieee80211_mgd_check_cross_link_csa(sdata, rx_status->link_id, elems);
-
- ieee80211_mgd_update_bss_param_ch_cnt(sdata, bss_conf, elems);
-
- if (!sdata->u.mgd.epcs.enabled &&
- !link->u.mgd.disable_wmm_tracking &&
- ieee80211_sta_wmm_params(local, link, elems->wmm_param,
- elems->wmm_param_len,
- elems->mu_edca_param_set))
- changed |= BSS_CHANGED_QOS;
-
/*
* If we haven't had a beacon before, tell the driver about the
* DTIM period (and beacon timing if desired) now.
@@ -7913,17 +7917,53 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
ieee80211_recalc_ps_vif(sdata);
}
- if (elems->erp_info) {
- erp_valid = true;
- erp_value = elems->erp_info[0];
- } else {
- erp_valid = false;
- }
+ /* RNR isn't inside an MBSSID profile */
+ ieee80211_mgd_update_bss_param_ch_cnt(sdata, bss_conf, elems);
+
+ /* assume ERP would be inherited anyway */
+ if (!ieee80211_is_s1g_beacon(hdr->frame_control)) {
+ u8 erp_value = 0;
+ bool erp_valid;
+
+ if (elems->erp_info) {
+ erp_valid = true;
+ erp_value = elems->erp_info[0];
+ } else {
+ erp_valid = false;
+ }
- if (!ieee80211_is_s1g_beacon(hdr->frame_control))
changed |= ieee80211_handle_bss_capability(link,
le16_to_cpu(mgmt->u.beacon.capab_info),
erp_valid, erp_value);
+ }
+
+ /*
+ * There are some other things that we can only do when the
+ * real non-transmitted profile was actually parsed, so exit
+ * here before doing those.
+ */
+ if (elems->mbssid_nontx_profile_missing)
+ goto apply;
+
+ /*
+ * This requires multi-link element, which is from the MBSSID profile.
+ * Note that after this elems->ml_basic can no longer be used fully.
+ *
+ * Note also that currently the parsing is incorrect, so this will
+ * never actually do anything.
+ */
+ ieee80211_mgd_check_cross_link_csa(sdata, rx_status->link_id, elems);
+
+ /*
+ * EDCA parameters should be the same, but perhaps ACM can differ
+ * between BSSes in an MBSSID set.
+ */
+ if (!sdata->u.mgd.epcs.enabled &&
+ !link->u.mgd.disable_wmm_tracking &&
+ ieee80211_sta_wmm_params(local, link, elems->wmm_param,
+ elems->wmm_param_len,
+ elems->mu_edca_param_set))
+ changed |= BSS_CHANGED_QOS;
sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
if (WARN_ON(!sta)) {
@@ -7969,6 +8009,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
ieee80211_process_adv_ttlm(sdata, elems,
le64_to_cpu(mgmt->u.beacon.timestamp));
+apply:
ieee80211_link_info_change_notify(sdata, link, changed);
free:
kfree(elems);
diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c
index 2587284fa67b..c7d882ccc4c6 100644
--- a/net/mac80211/parse.c
+++ b/net/mac80211/parse.c
@@ -1109,6 +1109,10 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
sub.type = params->type;
sub.link_id = params->link_id;
+ /* indicate to consumer whether or not profile was found */
+ if (params->bss->transmitted_bss && !nontx_len)
+ elems->mbssid_nontx_profile_missing = true;
+
/* consume the space used for non-transmitted profile */
elems_parse->scratch_pos += nontx_len;