* [PATCH] cfg80211: do not replace BSS structs
@ 2009-04-16 13:00 Johannes Berg
0 siblings, 0 replies; only message in thread
From: Johannes Berg @ 2009-04-16 13:00 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Instead, allocate extra IE memory if necessary. Normally,
this isn't even necessary since there's enough space.
This is a better way of correcting the "held BSS can
disappear" issue, but also a lot more code. It is also
necessary for proper auth/assoc BSS handling in the
future.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
John, you could roll this into one commit with the bandaid I posted
before, and if you think it's appropriate both can go into .30. But the
bandaid is sufficient for .30.
net/wireless/core.h | 2 +-
net/wireless/scan.c | 42 +++++++++++++++++++++++++++++++++---------
2 files changed, 34 insertions(+), 10 deletions(-)
--- wireless-testing.orig/net/wireless/core.h 2009-04-16 14:58:35.000000000 +0200
+++ wireless-testing/net/wireless/core.h 2009-04-16 14:58:37.000000000 +0200
@@ -86,7 +86,7 @@ struct cfg80211_internal_bss {
struct rb_node rbn;
unsigned long ts;
struct kref ref;
- bool hold;
+ bool hold, ies_allocated;
/* must be last because of priv member */
struct cfg80211_bss pub;
--- wireless-testing.orig/net/wireless/scan.c 2009-04-16 14:58:35.000000000 +0200
+++ wireless-testing/net/wireless/scan.c 2009-04-16 14:58:37.000000000 +0200
@@ -58,6 +58,10 @@ static void bss_release(struct kref *ref
bss = container_of(ref, struct cfg80211_internal_bss, ref);
if (bss->pub.free_priv)
bss->pub.free_priv(&bss->pub);
+
+ if (bss->ies_allocated)
+ kfree(bss->pub.information_elements);
+
kfree(bss);
}
@@ -360,21 +364,41 @@ cfg80211_bss_update(struct cfg80211_regi
found = rb_find_bss(dev, res);
- if (found && overwrite) {
- list_replace(&found->list, &res->list);
- rb_replace_node(&found->rbn, &res->rbn,
- &dev->bss_tree);
- /* XXX: workaround */
- res->hold = found->hold;
- kref_put(&found->ref, bss_release);
- found = res;
- } else if (found) {
+ if (found) {
kref_get(&found->ref);
found->pub.beacon_interval = res->pub.beacon_interval;
found->pub.tsf = res->pub.tsf;
found->pub.signal = res->pub.signal;
found->pub.capability = res->pub.capability;
found->ts = res->ts;
+
+ /* overwrite IEs */
+ if (overwrite) {
+ size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
+ size_t ielen = res->pub.len_information_elements;
+
+ if (ksize(found) >= used + ielen) {
+ memcpy(found->pub.information_elements,
+ res->pub.information_elements, ielen);
+ found->pub.len_information_elements = ielen;
+ } else {
+ u8 *ies = found->pub.information_elements;
+
+ if (found->ies_allocated) {
+ if (ksize(ies) < ielen)
+ ies = krealloc(ies, ielen,
+ GFP_ATOMIC);
+ } else
+ ies = kmalloc(ielen, GFP_ATOMIC);
+
+ if (ies) {
+ memcpy(ies, res->pub.information_elements, ielen);
+ found->ies_allocated = true;
+ found->pub.information_elements = ies;
+ }
+ }
+ }
+
kref_put(&res->ref, bss_release);
} else {
/* this "consumes" the reference */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-04-16 13:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-16 13:00 [PATCH] cfg80211: do not replace BSS structs Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox