Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 265684
b: refs/heads/master
c: 2a33bee
h: refs/heads/master
v: v3
  • Loading branch information
Guy Eilam authored and John W. Linville committed Aug 26, 2011
1 parent e8f963c commit cd50a02
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 61 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8c71df7a2f6a5345d6cad34e810c50edeca81521
refs/heads/master: 2a33bee2753bf28411de8822e3e3c7501966eb1b
59 changes: 53 additions & 6 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1482,10 +1482,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,

ifmgd->aid = aid;

sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
if (!sta) {
printk(KERN_DEBUG "%s: failed to alloc STA entry for"
" the AP\n", sdata->name);
mutex_lock(&sdata->local->sta_mtx);
/*
* station info was already allocated and inserted before
* the association and should be available to us
*/
sta = sta_info_get_rx(sdata, cbss->bssid);
if (WARN_ON(!sta)) {
mutex_unlock(&sdata->local->sta_mtx);
return false;
}

Expand Down Expand Up @@ -1556,7 +1560,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
if (elems.wmm_param)
set_sta_flags(sta, WLAN_STA_WME);

err = sta_info_insert(sta);
/* sta_info_reinsert will also unlock the mutex lock */
err = sta_info_reinsert(sta);
sta = NULL;
if (err) {
printk(KERN_DEBUG "%s: failed to insert STA entry for"
Expand Down Expand Up @@ -2429,16 +2434,44 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
return 0;
}

/* create and insert a dummy station entry */
static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
u8 *bssid) {
struct sta_info *sta;
int err;

sta = sta_info_alloc(sdata, bssid, GFP_KERNEL);
if (!sta) {
printk(KERN_DEBUG "%s: failed to alloc STA entry for"
" the AP\n", sdata->name);
return -ENOMEM;
}

sta->dummy = true;

err = sta_info_insert(sta);
sta = NULL;
if (err) {
printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
" the AP (error %d)\n", sdata->name, err);
return err;
}

return 0;
}

static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
struct sk_buff *skb)
{
struct ieee80211_local *local = wk->sdata->local;
struct ieee80211_mgmt *mgmt;
struct ieee80211_rx_status *rx_status;
struct ieee802_11_elems elems;
struct cfg80211_bss *cbss = wk->assoc.bss;
u16 status;

if (!skb) {
sta_info_destroy_addr(wk->sdata, cbss->bssid);
cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
goto destroy;
}
Expand Down Expand Up @@ -2468,12 +2501,16 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
mutex_unlock(&wk->sdata->u.mgd.mtx);
/* oops -- internal error -- send timeout for now */
sta_info_destroy_addr(wk->sdata, cbss->bssid);
cfg80211_send_assoc_timeout(wk->sdata->dev,
wk->filter_ta);
return WORK_DONE_DESTROY;
}

mutex_unlock(&wk->sdata->u.mgd.mtx);
} else {
/* assoc failed - destroy the dummy station entry */
sta_info_destroy_addr(wk->sdata, cbss->bssid);
}

cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
Expand All @@ -2492,7 +2529,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss = (void *)req->bss->priv;
struct ieee80211_work *wk;
const u8 *ssid;
int i;
int i, err;

mutex_lock(&ifmgd->mtx);
if (ifmgd->associated) {
Expand All @@ -2517,6 +2554,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
if (!wk)
return -ENOMEM;

/*
* create a dummy station info entry in order
* to start accepting incoming EAPOL packets from the station
*/
err = ieee80211_pre_assoc(sdata, req->bss->bssid);
if (err) {
kfree(wk);
return err;
}

ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;

Expand Down
21 changes: 17 additions & 4 deletions trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,21 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
ieee80211_is_pspoll(hdr->frame_control)) &&
rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
(!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC))))
(!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
if (rx->sta && rx->sta->dummy &&
ieee80211_is_data_present(hdr->frame_control)) {
u16 ethertype;
u8 *payload;

payload = rx->skb->data +
ieee80211_hdrlen(hdr->frame_control);
ethertype = (payload[6] << 8) | payload[7];
if (cpu_to_be16(ethertype) ==
rx->sdata->control_port_protocol)
return RX_CONTINUE;
}
return RX_DROP_MONITOR;
}

return RX_CONTINUE;
}
Expand Down Expand Up @@ -2808,7 +2821,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (ieee80211_is_data(fc)) {
prev_sta = NULL;

for_each_sta_info(local, hdr->addr2, sta, tmp) {
for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
if (!prev_sta) {
prev_sta = sta;
continue;
Expand Down Expand Up @@ -2852,15 +2865,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
continue;
}

rx.sta = sta_info_get_bss(prev, hdr->addr2);
rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
rx.sdata = prev;
ieee80211_prepare_and_rx_handle(&rx, skb, false);

prev = sdata;
}

if (prev) {
rx.sta = sta_info_get_bss(prev, hdr->addr2);
rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
rx.sdata = prev;

if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
Expand Down
Loading

0 comments on commit cd50a02

Please sign in to comment.