Commit 4d70e9c5 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: defragment reconfiguration MLE when parsing



Using the scratch buffer (without advancing it) here in the
mlme.c code seems somewhat wrong, defragment the reconfig
multi-link element already when parsing. This might be a bit
more work in certain cases, but makes the whole thing more
regular.

Reviewed-by: default avatarMiriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240228094902.92936a3ce216.I4b736ce4fdc199fa1d6b00d00032f448c873a8b4@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 508c423d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1736,6 +1736,7 @@ struct ieee802_11_elems {
	const struct ieee80211_eht_cap_elem *eht_cap;
	const struct ieee80211_eht_operation *eht_operation;
	const struct ieee80211_multi_link_elem *ml_basic;
	const struct ieee80211_multi_link_elem *ml_reconf;
	const struct ieee80211_bandwidth_indication *bandwidth_indication;
	const struct ieee80211_ttlm_elem *ttlm[IEEE80211_TTLM_MAX_CNT];

@@ -1763,6 +1764,7 @@ struct ieee802_11_elems {

	/* mult-link element can be de-fragmented and thus u8 is not sufficient */
	size_t ml_basic_len;
	size_t ml_reconf_len;

	/* The basic Multi-Link element in the original elements */
	const struct element *ml_basic_elem;
+3 −16
Original line number Diff line number Diff line
@@ -5752,33 +5752,20 @@ static void ieee80211_ml_reconf_work(struct wiphy *wiphy,
static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata,
					 struct ieee802_11_elems *elems)
{
	const struct ieee80211_multi_link_elem *ml;
	const struct element *sub;
	ssize_t ml_len;
	unsigned long removed_links = 0;
	u16 link_removal_timeout[IEEE80211_MLD_MAX_NUM_LINKS] = {};
	u8 link_id;
	u32 delay;

	if (!ieee80211_vif_is_mld(&sdata->vif) || !elems->ml_reconf_elem)
	if (!ieee80211_vif_is_mld(&sdata->vif) || !elems->ml_reconf)
		return;

	ml_len = cfg80211_defragment_element(elems->ml_reconf_elem,
					     elems->ie_start,
					     elems->total_len,
					     elems->scratch_pos,
					     elems->scratch + elems->scratch_len -
					     elems->scratch_pos,
					     WLAN_EID_FRAGMENT);
	if (ml_len < 0)
		return;

	ml = (const void *)elems->scratch_pos;

	/* Directly parse the sub elements as the common information doesn't
	 * hold any useful information.
	 */
	for_each_mle_subelement(sub, (u8 *)ml, ml_len) {
	for_each_mle_subelement(sub, (const u8 *)elems->ml_reconf,
				elems->ml_reconf_len) {
		struct ieee80211_mle_per_sta_profile *prof = (void *)sub->data;
		u8 *pos = prof->variable;
		u16 control;
+22 −0
Original line number Diff line number Diff line
@@ -819,6 +819,26 @@ static void ieee80211_mle_parse_link(struct ieee802_11_elems *elems,
	_ieee802_11_parse_elems_full(&sub, elems, non_inherit);
}

static void
ieee80211_mle_defrag_reconf(struct ieee802_11_elems *elems)
{
	ssize_t ml_len;

	ml_len = cfg80211_defragment_element(elems->ml_reconf_elem,
					     elems->ie_start,
					     elems->total_len,
					     elems->scratch_pos,
					     elems->scratch +
					     elems->scratch_len -
					     elems->scratch_pos,
					     WLAN_EID_FRAGMENT);
	if (ml_len < 0)
		return;
	elems->ml_reconf = (void *)elems->scratch_pos;
	elems->ml_reconf_len = ml_len;
	elems->scratch_pos += ml_len;
}

struct ieee802_11_elems *
ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
{
@@ -864,6 +884,8 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)

	ieee80211_mle_parse_link(elems, params);

	ieee80211_mle_defrag_reconf(elems);

	if (elems->tim && !elems->parse_error) {
		const struct ieee80211_tim_ie *tim_ie = elems->tim;