From de1ede7ac3bd300f9aa565d0f93f6cf9ba74bb1a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 9 Sep 2008 14:42:50 +0200 Subject: mac80211: make BA session handling independent of STA mode The aggregation handling isn't dependent on anything related to our STA-mode implementation, and doesn't need to depend on it for frame processing. This patch moves the relevant code to ht.c and adds a hook in rx.c. For now, the relevant action frames are only processed in STA/IBSS modes, but that's now something we can easily change. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'net/mac80211/rx.c') diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7e09b30dd39..71cce0bcc5b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1510,6 +1510,65 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) return RX_CONTINUE; } +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_action(struct ieee80211_rx_data *rx) +{ + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + int len = rx->skb->len; + + if (!ieee80211_is_action(mgmt->frame_control)) + return RX_CONTINUE; + + if (!rx->sta) + return RX_DROP_MONITOR; + + if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + return RX_DROP_MONITOR; + + /* all categories we currently handle have action_code */ + if (len < IEEE80211_MIN_ACTION_SIZE + 1) + return RX_DROP_MONITOR; + + /* + * FIXME: revisit this, I'm sure we should handle most + * of these frames in other modes as well! + */ + if (sdata->vif.type != IEEE80211_IF_TYPE_STA && + sdata->vif.type != IEEE80211_IF_TYPE_IBSS) + return RX_DROP_MONITOR; + + switch (mgmt->u.action.category) { + case WLAN_CATEGORY_BACK: + switch (mgmt->u.action.u.addba_req.action_code) { + case WLAN_ACTION_ADDBA_REQ: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.addba_req))) + return RX_DROP_MONITOR; + ieee80211_process_addba_request(local, rx->sta, mgmt, len); + break; + case WLAN_ACTION_ADDBA_RESP: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.addba_resp))) + return RX_DROP_MONITOR; + ieee80211_process_addba_resp(local, rx->sta, mgmt, len); + break; + case WLAN_ACTION_DELBA: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.delba))) + return RX_DROP_MONITOR; + ieee80211_process_delba(sdata, rx->sta, mgmt, len); + break; + } + rx->sta->rx_packets++; + dev_kfree_skb(rx->skb); + return RX_QUEUED; + } + + return RX_CONTINUE; +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) { @@ -1689,6 +1748,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, CALL_RXH(ieee80211_rx_h_mesh_fwding); CALL_RXH(ieee80211_rx_h_data) CALL_RXH(ieee80211_rx_h_ctrl) + CALL_RXH(ieee80211_rx_h_action) CALL_RXH(ieee80211_rx_h_mgmt) #undef CALL_RXH -- cgit v1.2.3