wifi: cfg80211: add element defragmentation helper
This is already needed within mac80211 and support is also needed by cfg80211 to parse ML elements. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230616094949.29c3ebeed10d.I009c049289dd0162c2e858ed8b68d2875a672ed6@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
39432f8a37
commit
f837a653a0
|
@ -6676,6 +6676,28 @@ cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
|
||||||
return (const void *)cfg80211_find_vendor_elem(oui, oui_type, ies, len);
|
return (const void *)cfg80211_find_vendor_elem(oui, oui_type, ies, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cfg80211_defragment_element - Defrag the given element data into a buffer
|
||||||
|
*
|
||||||
|
* @elem: the element to defragment
|
||||||
|
* @ies: elements where @elem is contained
|
||||||
|
* @ieslen: length of @ies
|
||||||
|
* @data: buffer to store element data
|
||||||
|
* @data_len: length of @data
|
||||||
|
* @frag_id: the element ID of fragments
|
||||||
|
*
|
||||||
|
* Return: length of @data, or -EINVAL on error
|
||||||
|
*
|
||||||
|
* Copy out all data from an element that may be fragmented into @data, while
|
||||||
|
* skipping all headers.
|
||||||
|
*
|
||||||
|
* The function uses memmove() internally. It is acceptable to defragment an
|
||||||
|
* element in-place.
|
||||||
|
*/
|
||||||
|
ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
|
||||||
|
size_t ieslen, u8 *data, size_t data_len,
|
||||||
|
u8 frag_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cfg80211_send_layer2_update - send layer 2 update frame
|
* cfg80211_send_layer2_update - send layer 2 update frame
|
||||||
*
|
*
|
||||||
|
|
|
@ -2288,6 +2288,66 @@ out:
|
||||||
kfree(profile);
|
kfree(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
|
||||||
|
size_t ieslen, u8 *data, size_t data_len,
|
||||||
|
u8 frag_id)
|
||||||
|
{
|
||||||
|
const struct element *next;
|
||||||
|
ssize_t copied;
|
||||||
|
u8 elem_datalen;
|
||||||
|
|
||||||
|
if (!elem)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* elem might be invalid after the memmove */
|
||||||
|
next = (void *)(elem->data + elem->datalen);
|
||||||
|
|
||||||
|
elem_datalen = elem->datalen;
|
||||||
|
if (elem->id == WLAN_EID_EXTENSION) {
|
||||||
|
copied = elem->datalen - 1;
|
||||||
|
if (copied > data_len)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
memmove(data, elem->data + 1, copied);
|
||||||
|
} else {
|
||||||
|
copied = elem->datalen;
|
||||||
|
if (copied > data_len)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
memmove(data, elem->data, copied);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fragmented elements must have 255 bytes */
|
||||||
|
if (elem_datalen < 255)
|
||||||
|
return copied;
|
||||||
|
|
||||||
|
for (elem = next;
|
||||||
|
elem->data < ies + ieslen &&
|
||||||
|
elem->data + elem->datalen < ies + ieslen;
|
||||||
|
elem = next) {
|
||||||
|
/* elem might be invalid after the memmove */
|
||||||
|
next = (void *)(elem->data + elem->datalen);
|
||||||
|
|
||||||
|
if (elem->id != frag_id)
|
||||||
|
break;
|
||||||
|
|
||||||
|
elem_datalen = elem->datalen;
|
||||||
|
|
||||||
|
if (copied + elem_datalen > data_len)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
memmove(data + copied, elem->data, elem_datalen);
|
||||||
|
copied += elem_datalen;
|
||||||
|
|
||||||
|
/* Only the last fragment may be short */
|
||||||
|
if (elem_datalen != 255)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copied;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cfg80211_defragment_element);
|
||||||
|
|
||||||
struct cfg80211_bss *
|
struct cfg80211_bss *
|
||||||
cfg80211_inform_bss_data(struct wiphy *wiphy,
|
cfg80211_inform_bss_data(struct wiphy *wiphy,
|
||||||
struct cfg80211_inform_bss *data,
|
struct cfg80211_inform_bss *data,
|
||||||
|
|
Loading…
Reference in New Issue