]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
wifi: mac80211: add a helper to fragment an element
authorJohannes Berg <johannes.berg@intel.com>
Thu, 7 Jul 2022 13:28:14 +0000 (15:28 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 15 Jul 2022 09:43:19 +0000 (11:43 +0200)
The way this works is that you add all the element data,
keeping a pointer to the length field of the element.
Then call this helper function, which will fragment the
element if there was more than 255 bytes in the element,
memmove()ing the data back if needed.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ieee80211_i.h
net/mac80211/util.c

index 74d5fc5889bb1869584123b04760f5f362985a06..d17d73e8d19f1888b4ff443af2739535910a2601 100644 (file)
@@ -2193,6 +2193,7 @@ ieee802_11_parse_elems(const u8 *start, size_t len, bool action,
        return ieee802_11_parse_elems_crc(start, len, action, 0, 0, bss);
 }
 
+void ieee80211_fragment_element(struct sk_buff *skb, u8 *len_pos);
 
 extern const int ieee802_1d_to_ac[8];
 
index 6d6ba23aa0741cbaa1474752b764a8a18b2ee41d..2ff8d1ec564c699d4879f3a9cdee22f70bee6bc6 100644 (file)
@@ -4780,3 +4780,31 @@ u8 *ieee80211_ie_build_eht_cap(u8 *pos,
 
        return pos;
 }
+
+void ieee80211_fragment_element(struct sk_buff *skb, u8 *len_pos)
+{
+       unsigned int elem_len;
+
+       if (!len_pos)
+               return;
+
+       elem_len = skb->data + skb->len - len_pos - 1;
+
+       while (elem_len > 255) {
+               /* this one is 255 */
+               *len_pos = 255;
+               /* remaining data gets smaller */
+               elem_len -= 255;
+               /* make space for the fragment ID/len in SKB */
+               skb_put(skb, 2);
+               /* shift back the remaining data to place fragment ID/len */
+               memmove(len_pos + 255 + 3, len_pos + 255 + 1, elem_len);
+               /* place the fragment ID */
+               len_pos += 255 + 1;
+               *len_pos = WLAN_EID_FRAGMENT;
+               /* and point to fragment length to update later */
+               len_pos++;
+       }
+
+       *len_pos = elem_len;
+}