forked from mirrors/linux
		
	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
					
				
					 2 changed files with 82 additions and 0 deletions
				
			
		| 
						 | 
					@ -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 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
 | 
				
			||||||
	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 a new issue