Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352545
b: refs/heads/master
c: 4593c4c
h: refs/heads/master
i:
  352543: 67c57d8
v: v3
  • Loading branch information
Johannes Berg committed Feb 4, 2013
1 parent 51d343c commit ca42975
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5622f5bb8dd3cafe0e56014ed03e31957d1b4a03
refs/heads/master: 4593c4cbe1c96b3995727dc42f6aa103f4ff5afc
80 changes: 53 additions & 27 deletions trunk/net/wireless/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,21 @@ static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b)
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)
* @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
* @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
*/
enum bss_compare_mode {
BSS_CMP_REGULAR,
BSS_CMP_HIDE_ZLEN,
BSS_CMP_HIDE_NUL,
};

static int cmp_bss(struct cfg80211_bss *a,
struct cfg80211_bss *b,
bool hide_ssid)
enum bss_compare_mode mode)
{
const struct cfg80211_bss_ies *a_ies, *b_ies;
const u8 *ie1;
Expand Down Expand Up @@ -462,27 +474,36 @@ static int cmp_bss(struct cfg80211_bss *a,
if (!ie2)
return 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)
switch (mode) {
case BSS_CMP_HIDE_ZLEN:
/*
* In ZLEN mode we assume the BSS entry we're
* looking for has a zero-length SSID. So if
* the one we're looking at right now has that,
* return 0. Otherwise, return the difference
* in length, but since we're looking for the
* 0-length it's really equivalent to returning
* the length of the one we're looking at.
*
* No content comparison is needed as we assume
* the content length is zero.
*/
return ie2[1];
case BSS_CMP_REGULAR:
default:
/* 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]);

/*
* zeroed SSID ie is another indication of a hidden bss;
* if it isn't zeroed just return the regular sort value
* to find the next candidate
*/
for (i = 0; i < ie2[1]; i++)
if (ie2[i + 2])
return memcmp(ie1 + 2, ie2 + 2, ie1[1]);

return 0;
case BSS_CMP_HIDE_NUL:
if (ie1[1] != ie2[1])
return ie2[1] - ie1[1];
/* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
for (i = 0; i < ie2[1]; i++)
if (ie2[i + 2])
return -1;
return 0;
}
}

struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
Expand Down Expand Up @@ -564,7 +585,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, false);
cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);

if (WARN_ON(!cmp)) {
/* will sort of leak this BSS */
Expand All @@ -584,15 +605,15 @@ 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,
bool hidden)
enum bss_compare_mode mode)
{
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, hidden);
r = cmp_bss(&res->pub, &bss->pub, mode);

if (r == 0)
return bss;
Expand Down Expand Up @@ -642,7 +663,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
return NULL;
}

found = rb_find_bss(dev, tmp, false);
found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR);

if (found) {
found->pub.beacon_interval = tmp->pub.beacon_interval;
Expand Down Expand Up @@ -697,9 +718,14 @@ 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_bss(dev, tmp, true);
if (hidden)
hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN);
if (hidden) {
copy_hidden_ies(tmp, hidden);
} else {
hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_NUL);
if (hidden)
copy_hidden_ies(tmp, hidden);
}

/*
* create a copy -- the "res" variable that is passed in
Expand Down

0 comments on commit ca42975

Please sign in to comment.