diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-09-08 11:44:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-11 15:53:37 -0400 |
commit | 98c8fccfaea838e62ffde2f2e44568844e0e5472 (patch) | |
tree | c69552d4be03dd8321b6f90b3fbb17c607fa9940 /net/mac80211/scan.c | |
parent | 0a51b27e956bd9580296c48191b78175ed8b5971 (diff) |
mac80211: refactor and move scan RX code
This patch refactors some code and moves the scan RX function
to scan.c. More importantly, however, it changes it so that the
MLME's beacon/probe_resp functions aren't invoked when scanning
so that we can remove a "if (scanning)" conditions from two
places.
There's a very slight behavioural change in this patch: now,
when scanning, IBSS and mesh aren't updated even on the same
channel.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 68fa782acd75..2848ba3a08e3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -23,6 +23,74 @@ | |||
23 | #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) | 23 | #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) |
24 | 24 | ||
25 | 25 | ||
26 | ieee80211_rx_result | ||
27 | ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | ||
28 | struct ieee80211_rx_status *rx_status) | ||
29 | { | ||
30 | struct ieee80211_mgmt *mgmt; | ||
31 | struct ieee80211_sta_bss *bss; | ||
32 | u8 *elements; | ||
33 | struct ieee80211_channel *channel; | ||
34 | size_t baselen; | ||
35 | int freq; | ||
36 | __le16 fc; | ||
37 | bool presp, beacon = false; | ||
38 | struct ieee802_11_elems elems; | ||
39 | |||
40 | if (skb->len < 2) | ||
41 | return RX_DROP_UNUSABLE; | ||
42 | |||
43 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
44 | fc = mgmt->frame_control; | ||
45 | |||
46 | if (ieee80211_is_ctl(fc)) | ||
47 | return RX_CONTINUE; | ||
48 | |||
49 | if (skb->len < 24) | ||
50 | return RX_DROP_MONITOR; | ||
51 | |||
52 | presp = ieee80211_is_probe_resp(fc); | ||
53 | if (presp) { | ||
54 | /* ignore ProbeResp to foreign address */ | ||
55 | if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) | ||
56 | return RX_DROP_MONITOR; | ||
57 | |||
58 | presp = true; | ||
59 | elements = mgmt->u.probe_resp.variable; | ||
60 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | ||
61 | } else { | ||
62 | beacon = ieee80211_is_beacon(fc); | ||
63 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
64 | elements = mgmt->u.beacon.variable; | ||
65 | } | ||
66 | |||
67 | if (!presp && !beacon) | ||
68 | return RX_CONTINUE; | ||
69 | |||
70 | if (baselen > skb->len) | ||
71 | return RX_DROP_MONITOR; | ||
72 | |||
73 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); | ||
74 | |||
75 | if (elems.ds_params && elems.ds_params_len == 1) | ||
76 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | ||
77 | else | ||
78 | freq = rx_status->freq; | ||
79 | |||
80 | channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq); | ||
81 | |||
82 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | ||
83 | return RX_DROP_MONITOR; | ||
84 | |||
85 | bss = ieee80211_bss_info_update(sdata->local, rx_status, | ||
86 | mgmt, skb->len, &elems, | ||
87 | freq, beacon); | ||
88 | ieee80211_rx_bss_put(sdata->local, bss); | ||
89 | |||
90 | dev_kfree_skb(skb); | ||
91 | return RX_QUEUED; | ||
92 | } | ||
93 | |||
26 | static void ieee80211_send_nullfunc(struct ieee80211_local *local, | 94 | static void ieee80211_send_nullfunc(struct ieee80211_local *local, |
27 | struct ieee80211_sub_if_data *sdata, | 95 | struct ieee80211_sub_if_data *sdata, |
28 | int powersave) | 96 | int powersave) |