cfg80211: simplify mesh BSS comparison
authorJohannes Berg <johannes.berg@intel.com>
Tue, 29 Jan 2013 23:40:20 +0000 (00:40 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 4 Feb 2013 17:57:41 +0000 (18:57 +0100)
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>
net/wireless/scan.c

index d4fe065eeb1129cd227e25929e58520fd0e83b86..1435b97b1ca289b9043b0c0e76c0f7b9e9a535a2 100644 (file)
@@ -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);