aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-10 04:21:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:39:26 -0400
commit77a121c3a88eb00a4b5e753d083dbb7d49fefb0a (patch)
treed1c802c9133a149094b484cd4796faeb9d7201fb /net/mac80211/rx.c
parent36b3a628a4e85d002ee8813ebd2a5caef6d3c1a7 (diff)
mac80211: pull mgmt frame rx into rx handler
Some code is duplicated between ibss, mesh and managed mode regarding the queueing of management frames. Since all modes now use a common skb queue and a common work function, we can pull the queueing code into the rx handler directly and remove the duplicated length checks etc. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3adcda502b7d..40fe2798cbf5 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1950,8 +1950,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1950 if (len < IEEE80211_MIN_ACTION_SIZE + 1) 1950 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
1951 break; 1951 break;
1952 1952
1953 if (sdata->vif.type == NL80211_IFTYPE_STATION) 1953 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
1954 return ieee80211_sta_rx_mgmt(sdata, rx->skb); 1954 skb_queue_tail(&sdata->skb_queue, rx->skb);
1955 ieee80211_queue_work(&local->hw, &sdata->work);
1956 return RX_QUEUED;
1957 }
1955 1958
1956 switch (mgmt->u.action.u.addba_req.action_code) { 1959 switch (mgmt->u.action.u.addba_req.action_code) {
1957 case WLAN_ACTION_ADDBA_REQ: 1960 case WLAN_ACTION_ADDBA_REQ:
@@ -2003,7 +2006,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2003 if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) 2006 if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
2004 break; 2007 break;
2005 2008
2006 return ieee80211_sta_rx_mgmt(sdata, rx->skb); 2009 skb_queue_tail(&sdata->skb_queue, rx->skb);
2010 ieee80211_queue_work(&local->hw, &sdata->work);
2011 return RX_QUEUED;
2007 } 2012 }
2008 break; 2013 break;
2009 case WLAN_CATEGORY_SA_QUERY: 2014 case WLAN_CATEGORY_SA_QUERY:
@@ -2021,9 +2026,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2021 break; 2026 break;
2022 case WLAN_CATEGORY_MESH_PLINK: 2027 case WLAN_CATEGORY_MESH_PLINK:
2023 case WLAN_CATEGORY_MESH_PATH_SEL: 2028 case WLAN_CATEGORY_MESH_PATH_SEL:
2024 if (ieee80211_vif_is_mesh(&sdata->vif)) 2029 if (!ieee80211_vif_is_mesh(&sdata->vif))
2025 return ieee80211_mesh_rx_mgmt(sdata, rx->skb); 2030 break;
2026 break; 2031 skb_queue_tail(&sdata->skb_queue, rx->skb);
2032 ieee80211_queue_work(&local->hw, &sdata->work);
2033 return RX_QUEUED;
2027 } 2034 }
2028 2035
2029 /* 2036 /*
@@ -2080,10 +2087,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
2080{ 2087{
2081 struct ieee80211_sub_if_data *sdata = rx->sdata; 2088 struct ieee80211_sub_if_data *sdata = rx->sdata;
2082 ieee80211_rx_result rxs; 2089 ieee80211_rx_result rxs;
2090 struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
2091 __le16 stype;
2083 2092
2084 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 2093 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
2085 return RX_DROP_MONITOR; 2094 return RX_DROP_MONITOR;
2086 2095
2096 if (rx->skb->len < 24)
2097 return RX_DROP_MONITOR;
2098
2087 if (ieee80211_drop_unencrypted_mgmt(rx)) 2099 if (ieee80211_drop_unencrypted_mgmt(rx))
2088 return RX_DROP_UNUSABLE; 2100 return RX_DROP_UNUSABLE;
2089 2101
@@ -2091,16 +2103,39 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
2091 if (rxs != RX_CONTINUE) 2103 if (rxs != RX_CONTINUE)
2092 return rxs; 2104 return rxs;
2093 2105
2094 if (ieee80211_vif_is_mesh(&sdata->vif)) 2106 stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
2095 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
2096 2107
2097 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 2108 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
2098 return ieee80211_ibss_rx_mgmt(sdata, rx->skb); 2109 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
2110 sdata->vif.type != NL80211_IFTYPE_STATION)
2111 return RX_DROP_MONITOR;
2099 2112
2100 if (sdata->vif.type == NL80211_IFTYPE_STATION) 2113 switch (stype) {
2101 return ieee80211_sta_rx_mgmt(sdata, rx->skb); 2114 case cpu_to_le16(IEEE80211_STYPE_BEACON):
2115 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
2116 /* process for all: mesh, mlme, ibss */
2117 break;
2118 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
2119 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
2120 /* process only for station */
2121 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2122 return RX_DROP_MONITOR;
2123 break;
2124 case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
2125 case cpu_to_le16(IEEE80211_STYPE_AUTH):
2126 /* process only for ibss */
2127 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
2128 return RX_DROP_MONITOR;
2129 break;
2130 default:
2131 return RX_DROP_MONITOR;
2132 }
2102 2133
2103 return RX_DROP_MONITOR; 2134 /* queue up frame and kick off work to process it */
2135 skb_queue_tail(&sdata->skb_queue, rx->skb);
2136 ieee80211_queue_work(&rx->local->hw, &sdata->work);
2137
2138 return RX_QUEUED;
2104} 2139}
2105 2140
2106static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, 2141static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,