Commit 98c8fccf authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0a51b27e
...@@ -937,6 +937,15 @@ void ieee802_11_parse_elems(u8 *start, size_t len, ...@@ -937,6 +937,15 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata, int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
u8 *ssid, size_t ssid_len); u8 *ssid, size_t ssid_len);
struct ieee80211_sta_bss *
ieee80211_bss_info_update(struct ieee80211_local *local,
struct ieee80211_rx_status *rx_status,
struct ieee80211_mgmt *mgmt,
size_t len,
struct ieee802_11_elems *elems,
int freq, bool beacon);
void ieee80211_rx_bss_put(struct ieee80211_local *local,
struct ieee80211_sta_bss *bss);
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
......
This diff is collapsed.
...@@ -23,6 +23,74 @@ ...@@ -23,6 +23,74 @@
#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
ieee80211_rx_result
ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_mgmt *mgmt;
struct ieee80211_sta_bss *bss;
u8 *elements;
struct ieee80211_channel *channel;
size_t baselen;
int freq;
__le16 fc;
bool presp, beacon = false;
struct ieee802_11_elems elems;
if (skb->len < 2)
return RX_DROP_UNUSABLE;
mgmt = (struct ieee80211_mgmt *) skb->data;
fc = mgmt->frame_control;
if (ieee80211_is_ctl(fc))
return RX_CONTINUE;
if (skb->len < 24)
return RX_DROP_MONITOR;
presp = ieee80211_is_probe_resp(fc);
if (presp) {
/* ignore ProbeResp to foreign address */
if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
return RX_DROP_MONITOR;
presp = true;
elements = mgmt->u.probe_resp.variable;
baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
} else {
beacon = ieee80211_is_beacon(fc);
baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
elements = mgmt->u.beacon.variable;
}
if (!presp && !beacon)
return RX_CONTINUE;
if (baselen > skb->len)
return RX_DROP_MONITOR;
ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
if (elems.ds_params && elems.ds_params_len == 1)
freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
else
freq = rx_status->freq;
channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
return RX_DROP_MONITOR;
bss = ieee80211_bss_info_update(sdata->local, rx_status,
mgmt, skb->len, &elems,
freq, beacon);
ieee80211_rx_bss_put(sdata->local, bss);
dev_kfree_skb(skb);
return RX_QUEUED;
}
static void ieee80211_send_nullfunc(struct ieee80211_local *local, static void ieee80211_send_nullfunc(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *sdata,
int powersave) int powersave)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment