cfg80211: simplify mesh BSS comparison
Instead of first checking if a BSS is an MBSS and then doing the comparisons, inline it all into the BSS comparison function. This avoids doing the IE searches twice and is also a lot less code. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									4593c4cbe1
								
							
						
					
					
						commit
						3af6341c53
					
				| @ -288,26 +288,6 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | ||||
| } | ||||
| EXPORT_SYMBOL(cfg80211_find_vendor_ie); | ||||
| 
 | ||||
| static int cmp_ies(u8 num, const u8 *ies1, int len1, const u8 *ies2, int len2) | ||||
| { | ||||
| 	const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); | ||||
| 	const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); | ||||
| 
 | ||||
| 	/* equal if both missing */ | ||||
| 	if (!ie1 && !ie2) | ||||
| 		return 0; | ||||
| 	/* sort missing IE before (left of) present IE */ | ||||
| 	if (!ie1) | ||||
| 		return -1; | ||||
| 	if (!ie2) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	/* sort by length first, then by contents */ | ||||
| 	if (ie1[1] != ie2[1]) | ||||
| 		return ie2[1] - ie1[1]; | ||||
| 	return memcmp(ie1 + 2, ie2 + 2, ie1[1]); | ||||
| } | ||||
| 
 | ||||
| static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, | ||||
| 		   const u8 *ssid, size_t ssid_len) | ||||
| { | ||||
| @ -331,29 +311,6 @@ static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, | ||||
| 	return memcmp(ssidie + 2, ssid, ssid_len) == 0; | ||||
| } | ||||
| 
 | ||||
| static bool is_mesh_bss(struct cfg80211_bss *a) | ||||
| { | ||||
| 	const struct cfg80211_bss_ies *ies; | ||||
| 	const u8 *ie; | ||||
| 
 | ||||
| 	if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	ies = rcu_access_pointer(a->ies); | ||||
| 	if (!ies) | ||||
| 		return false; | ||||
| 
 | ||||
| 	ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len); | ||||
| 	if (!ie) | ||||
| 		return false; | ||||
| 
 | ||||
| 	ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len); | ||||
| 	if (!ie) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static bool is_mesh(struct cfg80211_bss *a, | ||||
| 		    const u8 *meshid, size_t meshidlen, | ||||
| 		    const u8 *meshcfg) | ||||
| @ -391,39 +348,6 @@ static bool is_mesh(struct cfg80211_bss *a, | ||||
| 		      sizeof(struct ieee80211_meshconf_ie) - 2) == 0; | ||||
| } | ||||
| 
 | ||||
| static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b) | ||||
| { | ||||
| 	const struct cfg80211_bss_ies *a_ies, *b_ies; | ||||
| 	int r; | ||||
| 
 | ||||
| 	if (a->channel != b->channel) | ||||
| 		return b->channel->center_freq - a->channel->center_freq; | ||||
| 
 | ||||
| 	if (is_mesh_bss(a) && is_mesh_bss(b)) { | ||||
| 		a_ies = rcu_access_pointer(a->ies); | ||||
| 		if (!a_ies) | ||||
| 			return -1; | ||||
| 		b_ies = rcu_access_pointer(b->ies); | ||||
| 		if (!b_ies) | ||||
| 			return 1; | ||||
| 
 | ||||
| 		r = cmp_ies(WLAN_EID_MESH_ID, | ||||
| 			    a_ies->data, a_ies->len, | ||||
| 			    b_ies->data, b_ies->len); | ||||
| 		if (r) | ||||
| 			return r; | ||||
| 		return cmp_ies(WLAN_EID_MESH_CONFIG, | ||||
| 			       a_ies->data, a_ies->len, | ||||
| 			       b_ies->data, b_ies->len); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * we can't use compare_ether_addr here since we need a < > operator. | ||||
| 	 * The binary return value of compare_ether_addr isn't enough | ||||
| 	 */ | ||||
| 	return memcmp(a->bssid, b->bssid, sizeof(a->bssid)); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * enum bss_compare_mode - BSS compare mode | ||||
|  * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find) | ||||
| @ -441,13 +365,12 @@ static int cmp_bss(struct cfg80211_bss *a, | ||||
| 		   enum bss_compare_mode mode) | ||||
| { | ||||
| 	const struct cfg80211_bss_ies *a_ies, *b_ies; | ||||
| 	const u8 *ie1; | ||||
| 	const u8 *ie2; | ||||
| 	const u8 *ie1 = NULL; | ||||
| 	const u8 *ie2 = NULL; | ||||
| 	int i, r; | ||||
| 
 | ||||
| 	r = cmp_bss_core(a, b); | ||||
| 	if (r) | ||||
| 		return r; | ||||
| 	if (a->channel != b->channel) | ||||
| 		return b->channel->center_freq - a->channel->center_freq; | ||||
| 
 | ||||
| 	a_ies = rcu_access_pointer(a->ies); | ||||
| 	if (!a_ies) | ||||
| @ -456,6 +379,41 @@ static int cmp_bss(struct cfg80211_bss *a, | ||||
| 	if (!b_ies) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if (WLAN_CAPABILITY_IS_STA_BSS(a->capability)) | ||||
| 		ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||||
| 				       a_ies->data, a_ies->len); | ||||
| 	if (WLAN_CAPABILITY_IS_STA_BSS(b->capability)) | ||||
| 		ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||||
| 				       b_ies->data, b_ies->len); | ||||
| 	if (ie1 && ie2) { | ||||
| 		int mesh_id_cmp; | ||||
| 
 | ||||
| 		if (ie1[1] == ie2[1]) | ||||
| 			mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]); | ||||
| 		else | ||||
| 			mesh_id_cmp = ie2[1] - ie1[1]; | ||||
| 
 | ||||
| 		ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||||
| 				       a_ies->data, a_ies->len); | ||||
| 		ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||||
| 				       b_ies->data, b_ies->len); | ||||
| 		if (ie1 && ie2) { | ||||
| 			if (mesh_id_cmp) | ||||
| 				return mesh_id_cmp; | ||||
| 			if (ie1[1] != ie2[1]) | ||||
| 				return ie2[1] - ie1[1]; | ||||
| 			return memcmp(ie1 + 2, ie2 + 2, ie1[1]); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * we can't use compare_ether_addr here since we need a < > operator. | ||||
| 	 * The binary return value of compare_ether_addr isn't enough | ||||
| 	 */ | ||||
| 	r = memcmp(a->bssid, b->bssid, sizeof(a->bssid)); | ||||
| 	if (r) | ||||
| 		return r; | ||||
| 
 | ||||
| 	ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len); | ||||
| 	ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user