From: James Ketrenos Date: Wed, 8 Mar 2006 19:14:45 +0000 (-0600) Subject: [PATCH] ieee80211: Don't update network statistics from off-channel packets. X-Git-Tag: v2.6.17-rc1~1186^2^2~7 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f44349f2217d05e4575f24edc3c0e0022f5d448f;p=linux-2.6 [PATCH] ieee80211: Don't update network statistics from off-channel packets. This patch fixes a problem in the ieee80211 probe response and beacon reception code that would use the packet statistics for a network even if they were received on a channel other than that which the network exists on. This causes a problem in overlapping channels where, for example, a strong AP on channel 2 could have its beacons received on channels 1 and 3, but at much lower signal levels. If scanning was done sequentially, this means the beacon received on channel 3 would update the AP's signal level as being much lower than it really is, which subsequently could cause that AP to be passed over and an alternate AP selected. Signed-off-by: James Ketrenos Signed-off-by: John W. Linville --- diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 785d5a170a..a7f2a642a5 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1345,7 +1345,19 @@ static void update_network(struct ieee80211_network *dst, ieee80211_network_reset(dst); dst->ibss_dfs = src->ibss_dfs; - memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); + /* We only update the statistics if they were created by receiving + * the network information on the actual channel the network is on. + * + * This keeps beacons received on neighbor channels from bringing + * down the signal level of an AP. */ + if (dst->channel == src->stats.received_channel) + memcpy(&dst->stats, &src->stats, + sizeof(struct ieee80211_rx_stats)); + else + IEEE80211_DEBUG_SCAN("Network " MAC_FMT " info received " + "off channel (%d vs. %d)\n", MAC_ARG(src->bssid), + dst->channel, src->stats.received_channel); + dst->capability = src->capability; memcpy(dst->rates, src->rates, src->rates_len); dst->rates_len = src->rates_len;