aboutsummaryrefslogtreecommitdiff
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-24 07:46:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-24 07:46:51 -0700
commit3e241ff0c57cb610301009fe8c3b9da4c6877800 (patch)
tree9663c4ebd8e431a052675b19585e1cc9471b2ef3 /net/wireless/scan.c
parentdc0046c7586da5db7561dd8b8e09b40d29ade5fa (diff)
parent29fe1b481283a1bada994a69f65736db4ae6f35f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (94 commits) netfilter: ctnetlink: fix gcc warning during compilation net/netrom: Fix socket locking netlabel: Always remove the correct address selector ucc_geth.c: Fix upsmr setting in RMII mode 8139too: fix HW initial flow af_iucv: Fix race when queuing incoming iucv messages af_iucv: Test additional sk states in iucv_sock_shutdown af_iucv: Reject incoming msgs if RECV_SHUTDOWN is set af_iucv: fix oops in iucv_sock_recvmsg() for MSG_PEEK flag af_iucv: consider state IUCV_CLOSING when closing a socket iwlwifi: DMA fixes iwlwifi: add debugging for TX path mwl8: fix build warning. mac80211: fix alignment calculation bug mac80211: do not print WARN if config interface iwl3945: use cancel_delayed_work_sync to cancel rfkill_poll iwlwifi: fix EEPROM validation mask to include OTP only devices atmel: fix netdev ops conversion pcnet_cs: add cis(firmware) of the Allied Telesis LA-PCM mlx4_en: Fix cleanup if workqueue create in mlx4_en_add() fails ...
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2a00e362f5f..2ae65b39b52 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -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,19 +364,41 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
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);
- 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 */