Return-path: Received: from he.sipsolutions.net ([78.46.109.217]:48139 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751452Ab3A2Xo6 (ORCPT ); Tue, 29 Jan 2013 18:44:58 -0500 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 1/2] cfg80211: refactor hidden SSID finding Date: Wed, 30 Jan 2013 00:45:19 +0100 Message-Id: <1359503120-25685-1-git-send-email-johannes@sipsolutions.net> (sfid-20130130_004508_523732_488C5419) Sender: linux-wireless-owner@vger.kernel.org List-ID: From: Johannes Berg Instead of duplicating the rbtree functions, pass an argument to the compare function. This removes the code duplication for the two searches. Signed-off-by: Johannes Berg --- net/wireless/scan.c | 79 ++++++++++++----------------------------------------- 1 file changed, 17 insertions(+), 62 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ca367c5..72ef3b2 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -425,34 +425,13 @@ static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b) } static int cmp_bss(struct cfg80211_bss *a, - struct cfg80211_bss *b) -{ - const struct cfg80211_bss_ies *a_ies, *b_ies; - int r; - - r = cmp_bss_core(a, b); - if (r) - return r; - - a_ies = rcu_access_pointer(a->ies); - if (!a_ies) - return -1; - b_ies = rcu_access_pointer(b->ies); - if (!b_ies) - return 1; - - return cmp_ies(WLAN_EID_SSID, - a_ies->data, a_ies->len, - b_ies->data, b_ies->len); -} - -static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b) + struct cfg80211_bss *b, + bool hide_ssid) { const struct cfg80211_bss_ies *a_ies, *b_ies; const u8 *ie1; const u8 *ie2; - int i; - int r; + int i, r; r = cmp_bss_core(a, b); if (r) @@ -469,14 +448,9 @@ static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b) ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len); /* - * Key comparator must use same algorithm in any rb-tree - * search function (order is important), otherwise ordering - * of items in the tree is broken and search gives incorrect - * results. This code uses same order as cmp_ies() does. - * - * Note that due to the differring behaviour with hidden SSIDs - * this function only works when "b" is the tree element and - * "a" is the key we're looking for. + * Note that with "hide_ssid", the function returns a match if + * the already-present BSS ("b") is a hidden SSID beacon for + * the new BSS ("a"). */ /* sort missing IE before (left of) present IE */ @@ -485,14 +459,17 @@ static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b) if (!ie2) return 1; - /* zero-size SSID is used as an indication of the hidden bss */ - if (!ie2[1]) + /* zero-length SSID is used as an indication of the hidden bss */ + if (hide_ssid && !ie2[1]) return 0; /* sort by length first, then by contents */ if (ie1[1] != ie2[1]) return ie2[1] - ie1[1]; + if (!hide_ssid) + return memcmp(ie1 + 2, ie2 + 2, ie1[1]); + /* * zeroed SSID ie is another indication of a hidden bss; * if it isn't zeroed just return the regular sort value @@ -584,7 +561,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *dev, parent = *p; tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn); - cmp = cmp_bss(&bss->pub, &tbss->pub); + cmp = cmp_bss(&bss->pub, &tbss->pub, false); if (WARN_ON(!cmp)) { /* will sort of leak this BSS */ @@ -603,30 +580,8 @@ static void rb_insert_bss(struct cfg80211_registered_device *dev, static struct cfg80211_internal_bss * rb_find_bss(struct cfg80211_registered_device *dev, - struct cfg80211_internal_bss *res) -{ - struct rb_node *n = dev->bss_tree.rb_node; - struct cfg80211_internal_bss *bss; - int r; - - while (n) { - bss = rb_entry(n, struct cfg80211_internal_bss, rbn); - r = cmp_bss(&res->pub, &bss->pub); - - if (r == 0) - return bss; - else if (r < 0) - n = n->rb_left; - else - n = n->rb_right; - } - - return NULL; -} - -static struct cfg80211_internal_bss * -rb_find_hidden_bss(struct cfg80211_registered_device *dev, - struct cfg80211_internal_bss *res) + struct cfg80211_internal_bss *res, + bool hidden) { struct rb_node *n = dev->bss_tree.rb_node; struct cfg80211_internal_bss *bss; @@ -634,7 +589,7 @@ rb_find_hidden_bss(struct cfg80211_registered_device *dev, while (n) { bss = rb_entry(n, struct cfg80211_internal_bss, rbn); - r = cmp_hidden_bss(&res->pub, &bss->pub); + r = cmp_bss(&res->pub, &bss->pub, hidden); if (r == 0) return bss; @@ -684,7 +639,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, return NULL; } - found = rb_find_bss(dev, tmp); + found = rb_find_bss(dev, tmp, false); if (found) { found->pub.beacon_interval = tmp->pub.beacon_interval; @@ -739,7 +694,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, /* TODO: The code is not trying to update existing probe * response bss entries when beacon ies are * getting changed. */ - hidden = rb_find_hidden_bss(dev, tmp); + hidden = rb_find_bss(dev, tmp, true); if (hidden) copy_hidden_ies(tmp, hidden); -- 1.8.0