mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mac80211: refactor extended element parsing
This code was really ugly, refactor it a bit to make it more readable. While at it, use sizeof() and fix the UORA element length check bug. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/20200131111300.891737-4-luca@coelho.fi Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									75e296e9b2
								
							
						
					
					
						commit
						e4d005b80d
					
				
					 1 changed files with 48 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -890,6 +890,51 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(ieee80211_queue_delayed_work);
 | 
			
		||||
 | 
			
		||||
static void ieee80211_parse_extension_element(u32 *crc,
 | 
			
		||||
					      const struct element *elem,
 | 
			
		||||
					      struct ieee802_11_elems *elems)
 | 
			
		||||
{
 | 
			
		||||
	const void *data = elem->data + 1;
 | 
			
		||||
	u8 len = elem->datalen - 1;
 | 
			
		||||
 | 
			
		||||
	switch (elem->data[0]) {
 | 
			
		||||
	case WLAN_EID_EXT_HE_MU_EDCA:
 | 
			
		||||
		if (len == sizeof(*elems->mu_edca_param_set)) {
 | 
			
		||||
			elems->mu_edca_param_set = data;
 | 
			
		||||
			if (crc)
 | 
			
		||||
				*crc = crc32_be(*crc, (void *)elem,
 | 
			
		||||
						elem->datalen + 2);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_HE_CAPABILITY:
 | 
			
		||||
		elems->he_cap = data;
 | 
			
		||||
		elems->he_cap_len = len;
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_HE_OPERATION:
 | 
			
		||||
		if (len >= sizeof(*elems->he_operation) &&
 | 
			
		||||
		    len == ieee80211_he_oper_size(data) - 1)
 | 
			
		||||
			elems->he_operation = data;
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_UORA:
 | 
			
		||||
		if (len == 1)
 | 
			
		||||
			elems->uora_element = data;
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME:
 | 
			
		||||
		if (len == 3)
 | 
			
		||||
			elems->max_channel_switch_time = data;
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION:
 | 
			
		||||
		if (len == sizeof(*elems->mbssid_config_ie))
 | 
			
		||||
			elems->mbssid_config_ie = data;
 | 
			
		||||
		break;
 | 
			
		||||
	case WLAN_EID_EXT_HE_SPR:
 | 
			
		||||
		if (len >= sizeof(*elems->he_spr) &&
 | 
			
		||||
		    len >= ieee80211_he_spr_size(data))
 | 
			
		||||
			elems->he_spr = data;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32
 | 
			
		||||
_ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 | 
			
		||||
			    struct ieee802_11_elems *elems,
 | 
			
		||||
| 
						 | 
				
			
			@ -1220,33 +1265,9 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 | 
			
		|||
				elems->max_idle_period_ie = (void *)pos;
 | 
			
		||||
			break;
 | 
			
		||||
		case WLAN_EID_EXTENSION:
 | 
			
		||||
			if (pos[0] == WLAN_EID_EXT_HE_MU_EDCA &&
 | 
			
		||||
			    elen >= (sizeof(*elems->mu_edca_param_set) + 1)) {
 | 
			
		||||
				elems->mu_edca_param_set = (void *)&pos[1];
 | 
			
		||||
				if (calc_crc)
 | 
			
		||||
					crc = crc32_be(crc, pos - 2, elen + 2);
 | 
			
		||||
			} else if (pos[0] == WLAN_EID_EXT_HE_CAPABILITY) {
 | 
			
		||||
				elems->he_cap = (void *)&pos[1];
 | 
			
		||||
				elems->he_cap_len = elen - 1;
 | 
			
		||||
			} else if (pos[0] == WLAN_EID_EXT_HE_OPERATION &&
 | 
			
		||||
				   elen >= sizeof(*elems->he_operation) &&
 | 
			
		||||
				   elen >= ieee80211_he_oper_size(&pos[1])) {
 | 
			
		||||
				elems->he_operation = (void *)&pos[1];
 | 
			
		||||
			} else if (pos[0] == WLAN_EID_EXT_UORA && elen >= 1) {
 | 
			
		||||
				elems->uora_element = (void *)&pos[1];
 | 
			
		||||
			} else if (pos[0] ==
 | 
			
		||||
				   WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME &&
 | 
			
		||||
				   elen == 4) {
 | 
			
		||||
				elems->max_channel_switch_time = pos + 1;
 | 
			
		||||
			} else if (pos[0] ==
 | 
			
		||||
				   WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION &&
 | 
			
		||||
				   elen == 3) {
 | 
			
		||||
				elems->mbssid_config_ie = (void *)&pos[1];
 | 
			
		||||
			} else if (pos[0] == WLAN_EID_EXT_HE_SPR &&
 | 
			
		||||
				   elen >= sizeof(*elems->he_spr) &&
 | 
			
		||||
				   elen >= ieee80211_he_spr_size(&pos[1])) {
 | 
			
		||||
				elems->he_spr = (void *)&pos[1];
 | 
			
		||||
			}
 | 
			
		||||
			ieee80211_parse_extension_element(calc_crc ?
 | 
			
		||||
								&crc : NULL,
 | 
			
		||||
							  elem, elems);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue