wifi: mac80211: defragment reconfiguration MLE when parsing
authorJohannes Berg <johannes.berg@intel.com>
Wed, 28 Feb 2024 08:48:14 +0000 (09:48 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 4 Mar 2024 13:32:59 +0000 (14:32 +0100)
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: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240228094902.92936a3ce216.I4b736ce4fdc199fa1d6b00d00032f448c873a8b4@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/parse.c

index 26cf24a3158309ebd221e4761537e80fe8afb61f..caee68cc8f14f03ec834e0b25b420c57a2ec24e8 100644 (file)
@@ -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;
index 3be4f4cf12c3414ee5c9ac557cb2fcf966328148..90e505778db6151a21b68f5dd149a475ddacd218 100644 (file)
@@ -5752,33 +5752,20 @@ out:
 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;
index 8bdf6e7efa58b4ad05a18876bf9607e082b38f51..804323858977e715c6092df54d7ac69acf837e34 100644 (file)
@@ -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;