From: Johannes Berg As previously defined in the header file, this element has a different layout depending on the action frame it's carried in, so the 'type' is no longer sufficient. Add a new enum indicating which 'action_frame' we're parsing to allow for this, and parse the element accordingly in SMD Transition preparation and execution responses, in preparation for ST implementation. Assisted-by: LLM Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 26 ++++++++++++++++++++++++++ net/mac80211/parse.c | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eb31691c89d5..7e6e87ccce08 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1916,6 +1916,8 @@ struct ieee802_11_elems { const struct ieee80211_uhr_operation *uhr_operation; const struct ieee80211_cip_cap *cip_cap; const struct ieee80211_uhr_parameters_update *uhr_param_upd; + const struct ieee80211_smd_bss_trans_params_prep_resp *smd_prep_resp; + const struct ieee80211_smd_bss_trans_params_exec_resp *smd_exec_resp; /* not the order in the psd values is per element, not per chandef */ struct ieee80211_parsed_tpe tpe; @@ -2553,6 +2555,26 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb_tid(sdata, skb, NULL, 7, -1); } +/** + * enum ieee80211_parse_action_frame - action frame context for element parsing + * + * Some elements reuse the same element ID for different structures depending + * on which action frame they appear in. This selects the action frame the + * elements came from so the parser can extract the correct variant. + * + * @IEEE80211_PARSE_ACTION_FRAME_UNSPECIFIED: not one of the action frames that + * need such disambiguation - parse elements normally + * @IEEE80211_PARSE_ACTION_FRAME_ST_PREP_RESP: SMD transition preparation + * response + * @IEEE80211_PARSE_ACTION_FRAME_ST_EXEC_RESP: SMD transition execution + * response + */ +enum ieee80211_parse_action_frame { + IEEE80211_PARSE_ACTION_FRAME_UNSPECIFIED = 0, + IEEE80211_PARSE_ACTION_FRAME_ST_PREP_RESP, + IEEE80211_PARSE_ACTION_FRAME_ST_EXEC_RESP, +}; + /** * struct ieee80211_elems_parse_params - element parsing parameters * @mode: connection mode for parsing @@ -2572,6 +2594,9 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, * (or re-association) response frame if this is given * @from_ap: frame is received from an AP (currently used only * for EHT capabilities parsing) + * @action_frame: which action frame the elements came from, to + * disambiguate elements that reuse the same element ID across different + * action frames, or %IEEE80211_PARSE_ACTION_FRAME_UNSPECIFIED */ struct ieee80211_elems_parse_params { enum ieee80211_conn_mode mode; @@ -2583,6 +2608,7 @@ struct ieee80211_elems_parse_params { struct cfg80211_bss *bss; int link_id; bool from_ap; + enum ieee80211_parse_action_frame action_frame; }; struct ieee802_11_elems * diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c index 22bba5adef26..c392ecf58b0c 100644 --- a/net/mac80211/parse.c +++ b/net/mac80211/parse.c @@ -236,6 +236,20 @@ ieee80211_parse_extension_element(u32 *crc, elems_parse->uhr_param_upd.start = params->start; elems_parse->uhr_param_upd.len = params->len; break; + case WLAN_EID_EXT_BSS_SMD_TRANS_PARAMS: + switch (params->action_frame) { + case IEEE80211_PARSE_ACTION_FRAME_ST_PREP_RESP: + if (ieee80211_smd_prep_resp_size_ok(data, len)) + elems->smd_prep_resp = data; + break; + case IEEE80211_PARSE_ACTION_FRAME_ST_EXEC_RESP: + if (ieee80211_smd_exec_resp_size_ok(data, len)) + elems->smd_exec_resp = data; + break; + default: + break; + } + break; } if (crc && calc_crc) @@ -351,6 +365,10 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, break; } + WARN(params->type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION) && + params->action_frame != IEEE80211_PARSE_ACTION_FRAME_UNSPECIFIED, + "action frame type specified for non-action frame\n"); + for_each_element(elem, params->start, params->len) { const struct element *subelem; u8 elem_parse_failed; -- 2.56.0