|
@@ -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);
|
|
|
|