public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [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