Search Linux Wireless

[PATCH 1/2] cfg80211: refactor hidden SSID finding

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Berg <johannes.berg@xxxxxxxxx>

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 <johannes.berg@xxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux